cojson 0.7.0-alpha.36 → 0.7.0-alpha.38
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 +3 -2
- package/.prettierrc.js +9 -0
- package/.turbo/turbo-build.log +3 -36
- package/.turbo/turbo-lint.log +4 -0
- package/.turbo/turbo-test.log +1106 -0
- package/CHANGELOG.md +12 -0
- package/README.md +3 -1
- package/dist/base64url.test.js +25 -0
- package/dist/base64url.test.js.map +1 -0
- package/dist/coValueCore.js +16 -15
- package/dist/coValueCore.js.map +1 -1
- package/dist/coValues/account.js +16 -15
- package/dist/coValues/account.js.map +1 -1
- package/dist/coValues/group.js +13 -14
- package/dist/coValues/group.js.map +1 -1
- package/dist/coreToCoValue.js.map +1 -1
- package/dist/crypto/PureJSCrypto.js +89 -0
- package/dist/crypto/PureJSCrypto.js.map +1 -0
- package/dist/crypto/WasmCrypto.js +127 -0
- package/dist/crypto/WasmCrypto.js.map +1 -0
- package/dist/crypto/crypto.js +151 -0
- package/dist/crypto/crypto.js.map +1 -0
- package/dist/ids.js +4 -2
- package/dist/ids.js.map +1 -1
- package/dist/index.js +5 -9
- package/dist/index.js.map +1 -1
- package/dist/jsonStringify.js.map +1 -1
- package/dist/localNode.js +24 -24
- package/dist/localNode.js.map +1 -1
- package/dist/permissions.js.map +1 -1
- package/dist/storage/FileSystem.js +2 -2
- package/dist/storage/FileSystem.js.map +1 -1
- package/dist/storage/chunksAndKnownStates.js +2 -2
- package/dist/storage/chunksAndKnownStates.js.map +1 -1
- package/dist/storage/index.js.map +1 -1
- package/dist/sync.js +6 -2
- package/dist/sync.js.map +1 -1
- package/dist/tests/account.test.js +58 -0
- package/dist/tests/account.test.js.map +1 -0
- package/dist/tests/coList.test.js +76 -0
- package/dist/tests/coList.test.js.map +1 -0
- package/dist/tests/coMap.test.js +136 -0
- package/dist/tests/coMap.test.js.map +1 -0
- package/dist/tests/coStream.test.js +172 -0
- package/dist/tests/coStream.test.js.map +1 -0
- package/dist/tests/coValueCore.test.js +114 -0
- package/dist/tests/coValueCore.test.js.map +1 -0
- package/dist/tests/crypto.test.js +118 -0
- package/dist/tests/crypto.test.js.map +1 -0
- package/dist/tests/cryptoImpl.test.js +113 -0
- package/dist/tests/cryptoImpl.test.js.map +1 -0
- package/dist/tests/group.test.js +34 -0
- package/dist/tests/group.test.js.map +1 -0
- package/dist/tests/permissions.test.js +1060 -0
- package/dist/tests/permissions.test.js.map +1 -0
- package/dist/tests/sync.test.js +816 -0
- package/dist/tests/sync.test.js.map +1 -0
- package/dist/tests/testUtils.js +10 -9
- 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/dist/typeUtils/isCoValue.js.map +1 -1
- package/package.json +14 -28
- package/src/base64url.test.ts +6 -6
- package/src/coValue.ts +1 -1
- package/src/coValueCore.ts +87 -85
- package/src/coValues/account.ts +26 -28
- package/src/coValues/coList.ts +10 -10
- package/src/coValues/coMap.ts +10 -10
- package/src/coValues/coStream.ts +17 -17
- package/src/coValues/group.ts +93 -109
- package/src/coreToCoValue.ts +5 -2
- package/src/crypto/PureJSCrypto.ts +200 -0
- package/src/crypto/WasmCrypto.ts +259 -0
- package/src/crypto/crypto.ts +336 -0
- package/src/ids.ts +8 -7
- package/src/index.ts +14 -26
- package/src/jsonStringify.ts +6 -4
- package/src/jsonValue.ts +2 -2
- package/src/localNode.ts +86 -80
- package/src/media.ts +3 -3
- package/src/permissions.ts +14 -16
- package/src/storage/FileSystem.ts +31 -30
- package/src/storage/chunksAndKnownStates.ts +24 -17
- package/src/storage/index.ts +42 -38
- package/src/streamUtils.ts +12 -12
- package/src/sync.ts +56 -40
- package/src/tests/account.test.ts +8 -12
- package/src/tests/coList.test.ts +19 -25
- package/src/tests/coMap.test.ts +25 -30
- package/src/tests/coStream.test.ts +28 -38
- package/src/tests/coValueCore.test.ts +35 -36
- package/src/tests/crypto.test.ts +66 -72
- package/src/tests/cryptoImpl.test.ts +183 -0
- package/src/tests/group.test.ts +16 -17
- package/src/tests/permissions.test.ts +237 -254
- package/src/tests/sync.test.ts +119 -120
- package/src/tests/testUtils.ts +22 -19
- package/src/typeUtils/accountOrAgentIDfromSessionID.ts +1 -2
- package/src/typeUtils/expectGroup.ts +1 -1
- package/src/typeUtils/isAccountID.ts +0 -1
- package/src/typeUtils/isCoValue.ts +1 -2
- package/tsconfig.json +0 -1
- package/dist/crypto.js +0 -255
- package/dist/crypto.js.map +0 -1
- package/src/crypto.ts +0 -485
package/src/tests/sync.test.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { expect, test
|
|
1
|
+
import { expect, test } from "vitest";
|
|
2
2
|
import { newRandomSessionID } from "../coValueCore.js";
|
|
3
3
|
import { LocalNode } from "../localNode.js";
|
|
4
4
|
import { SyncMessage } from "../sync.js";
|
|
@@ -11,22 +11,14 @@ import {
|
|
|
11
11
|
} from "./testUtils.js";
|
|
12
12
|
import { connectedPeers, newStreamPair } from "../streamUtils.js";
|
|
13
13
|
import { AccountID } from "../coValues/account.js";
|
|
14
|
-
import { cojsonReady } from "../index.js";
|
|
15
14
|
import { stableStringify } from "../jsonStringify.js";
|
|
15
|
+
import { WasmCrypto } from "../crypto/WasmCrypto.js";
|
|
16
16
|
|
|
17
|
-
|
|
18
|
-
if (!("crypto" in globalThis)) {
|
|
19
|
-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
20
|
-
(globalThis as any).crypto = webcrypto;
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
beforeEach(async () => {
|
|
24
|
-
await cojsonReady;
|
|
25
|
-
});
|
|
17
|
+
const Crypto = await WasmCrypto.create();
|
|
26
18
|
|
|
27
19
|
test("Node replies with initial tx and header to empty subscribe", async () => {
|
|
28
20
|
const [admin, session] = randomAnonymousAccountAndSessionID();
|
|
29
|
-
const node = new LocalNode(admin, session);
|
|
21
|
+
const node = new LocalNode(admin, session, Crypto);
|
|
30
22
|
|
|
31
23
|
const group = node.createGroup();
|
|
32
24
|
|
|
@@ -105,7 +97,7 @@ test("Node replies with initial tx and header to empty subscribe", async () => {
|
|
|
105
97
|
|
|
106
98
|
test("Node replies with only new tx to subscribe with some known state", async () => {
|
|
107
99
|
const [admin, session] = randomAnonymousAccountAndSessionID();
|
|
108
|
-
const node = new LocalNode(admin, session);
|
|
100
|
+
const node = new LocalNode(admin, session, Crypto);
|
|
109
101
|
|
|
110
102
|
const group = node.createGroup();
|
|
111
103
|
|
|
@@ -180,12 +172,12 @@ test("Node replies with only new tx to subscribe with some known state", async (
|
|
|
180
172
|
});
|
|
181
173
|
|
|
182
174
|
test.todo(
|
|
183
|
-
"TODO: node only replies with new tx to subscribe with some known state, even in the depended on coValues"
|
|
175
|
+
"TODO: node only replies with new tx to subscribe with some known state, even in the depended on coValues",
|
|
184
176
|
);
|
|
185
177
|
|
|
186
178
|
test("After subscribing, node sends own known state and new txs to peer", async () => {
|
|
187
179
|
const [admin, session] = randomAnonymousAccountAndSessionID();
|
|
188
|
-
const node = new LocalNode(admin, session);
|
|
180
|
+
const node = new LocalNode(admin, session, Crypto);
|
|
189
181
|
|
|
190
182
|
const group = node.createGroup();
|
|
191
183
|
|
|
@@ -298,7 +290,7 @@ test("After subscribing, node sends own known state and new txs to peer", async
|
|
|
298
290
|
|
|
299
291
|
test("Client replies with known new content to tellKnownState from server", async () => {
|
|
300
292
|
const [admin, session] = randomAnonymousAccountAndSessionID();
|
|
301
|
-
const node = new LocalNode(admin, session);
|
|
293
|
+
const node = new LocalNode(admin, session, Crypto);
|
|
302
294
|
|
|
303
295
|
const group = node.createGroup();
|
|
304
296
|
|
|
@@ -375,7 +367,7 @@ test("Client replies with known new content to tellKnownState from server", asyn
|
|
|
375
367
|
|
|
376
368
|
test("No matter the optimistic known state, node respects invalid known state messages and resyncs", async () => {
|
|
377
369
|
const [admin, session] = randomAnonymousAccountAndSessionID();
|
|
378
|
-
const node = new LocalNode(admin, session);
|
|
370
|
+
const node = new LocalNode(admin, session, Crypto);
|
|
379
371
|
|
|
380
372
|
const group = node.createGroup();
|
|
381
373
|
|
|
@@ -475,7 +467,7 @@ test("No matter the optimistic known state, node respects invalid known state me
|
|
|
475
467
|
|
|
476
468
|
test("If we add a peer, but it never subscribes to a coValue, it won't get any messages", async () => {
|
|
477
469
|
const [admin, session] = randomAnonymousAccountAndSessionID();
|
|
478
|
-
const node = new LocalNode(admin, session);
|
|
470
|
+
const node = new LocalNode(admin, session, Crypto);
|
|
479
471
|
|
|
480
472
|
const group = node.createGroup();
|
|
481
473
|
|
|
@@ -496,85 +488,92 @@ test("If we add a peer, but it never subscribes to a coValue, it won't get any m
|
|
|
496
488
|
const reader = outRx.getReader();
|
|
497
489
|
|
|
498
490
|
await expect(
|
|
499
|
-
shouldNotResolve(reader.read(), { timeout: 100 })
|
|
491
|
+
shouldNotResolve(reader.read(), { timeout: 100 }),
|
|
500
492
|
).resolves.toBeUndefined();
|
|
501
493
|
});
|
|
502
494
|
|
|
503
|
-
test(
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
|
|
562
|
-
|
|
563
|
-
|
|
564
|
-
|
|
565
|
-
|
|
566
|
-
|
|
567
|
-
|
|
568
|
-
|
|
569
|
-
|
|
495
|
+
test.todo(
|
|
496
|
+
"If we add a server peer, all updates to all coValues are sent to it, even if it doesn't subscribe",
|
|
497
|
+
async () => {
|
|
498
|
+
const [admin, session] = randomAnonymousAccountAndSessionID();
|
|
499
|
+
const node = new LocalNode(admin, session, Crypto);
|
|
500
|
+
|
|
501
|
+
const group = node.createGroup();
|
|
502
|
+
|
|
503
|
+
const map = group.createMap();
|
|
504
|
+
|
|
505
|
+
const [inRx, _inTx] = newStreamPair<SyncMessage>();
|
|
506
|
+
const [outRx, outTx] = newStreamPair<SyncMessage>();
|
|
507
|
+
|
|
508
|
+
node.syncManager.addPeer({
|
|
509
|
+
id: "test",
|
|
510
|
+
incoming: inRx,
|
|
511
|
+
outgoing: outTx,
|
|
512
|
+
role: "server",
|
|
513
|
+
});
|
|
514
|
+
|
|
515
|
+
const reader = outRx.getReader();
|
|
516
|
+
// expect((await reader.read()).value).toMatchObject({
|
|
517
|
+
// action: "load",
|
|
518
|
+
// id: adminID,
|
|
519
|
+
// });
|
|
520
|
+
expect((await reader.read()).value).toMatchObject({
|
|
521
|
+
action: "load",
|
|
522
|
+
id: group.core.id,
|
|
523
|
+
});
|
|
524
|
+
|
|
525
|
+
const mapSubscribeMsg = await reader.read();
|
|
526
|
+
|
|
527
|
+
expect(mapSubscribeMsg.value).toEqual({
|
|
528
|
+
action: "load",
|
|
529
|
+
id: map.core.id,
|
|
530
|
+
header: true,
|
|
531
|
+
sessions: {},
|
|
532
|
+
} satisfies SyncMessage);
|
|
533
|
+
|
|
534
|
+
map.set("hello", "world", "trusting");
|
|
535
|
+
|
|
536
|
+
// expect((await reader.read()).value).toMatchObject(admContEx(admin.id));
|
|
537
|
+
expect((await reader.read()).value).toMatchObject(
|
|
538
|
+
groupContentEx(group),
|
|
539
|
+
);
|
|
540
|
+
|
|
541
|
+
const mapNewContentMsg = await reader.read();
|
|
542
|
+
|
|
543
|
+
expect(mapNewContentMsg.value).toEqual({
|
|
544
|
+
action: "content",
|
|
545
|
+
id: map.core.id,
|
|
546
|
+
header: map.core.header,
|
|
547
|
+
new: {
|
|
548
|
+
[node.currentSessionID]: {
|
|
549
|
+
after: 0,
|
|
550
|
+
newTransactions: [
|
|
551
|
+
{
|
|
552
|
+
privacy: "trusting" as const,
|
|
553
|
+
madeAt: map.core.sessionLogs.get(
|
|
554
|
+
node.currentSessionID,
|
|
555
|
+
)!.transactions[0]!.madeAt,
|
|
556
|
+
changes: stableStringify([
|
|
557
|
+
{
|
|
558
|
+
op: "set",
|
|
559
|
+
key: "hello",
|
|
560
|
+
value: "world",
|
|
561
|
+
} satisfies MapOpPayload<string, string>,
|
|
562
|
+
]),
|
|
563
|
+
},
|
|
564
|
+
],
|
|
565
|
+
lastSignature: map.core.sessionLogs.get(
|
|
566
|
+
node.currentSessionID,
|
|
567
|
+
)!.lastSignature!,
|
|
568
|
+
},
|
|
570
569
|
},
|
|
571
|
-
}
|
|
572
|
-
}
|
|
573
|
-
|
|
570
|
+
} satisfies SyncMessage);
|
|
571
|
+
},
|
|
572
|
+
);
|
|
574
573
|
|
|
575
574
|
test.skip("If we add a server peer, newly created coValues are auto-subscribed to", async () => {
|
|
576
575
|
const [admin, session] = randomAnonymousAccountAndSessionID();
|
|
577
|
-
const node = new LocalNode(admin, session);
|
|
576
|
+
const node = new LocalNode(admin, session, Crypto);
|
|
578
577
|
|
|
579
578
|
const group = node.createGroup();
|
|
580
579
|
|
|
@@ -621,12 +620,12 @@ test.skip("If we add a server peer, newly created coValues are auto-subscribed t
|
|
|
621
620
|
});
|
|
622
621
|
|
|
623
622
|
test.todo(
|
|
624
|
-
"TODO: when receiving a subscribe response that is behind our optimistic state (due to already sent content), we ignore it"
|
|
623
|
+
"TODO: when receiving a subscribe response that is behind our optimistic state (due to already sent content), we ignore it",
|
|
625
624
|
);
|
|
626
625
|
|
|
627
626
|
test("When we connect a new server peer, we try to sync all existing coValues to it", async () => {
|
|
628
627
|
const [admin, session] = randomAnonymousAccountAndSessionID();
|
|
629
|
-
const node = new LocalNode(admin, session);
|
|
628
|
+
const node = new LocalNode(admin, session, Crypto);
|
|
630
629
|
|
|
631
630
|
const group = node.createGroup();
|
|
632
631
|
|
|
@@ -662,7 +661,7 @@ test("When we connect a new server peer, we try to sync all existing coValues to
|
|
|
662
661
|
|
|
663
662
|
test("When receiving a subscribe with a known state that is ahead of our own, peers should respond with a corresponding subscribe response message", async () => {
|
|
664
663
|
const [admin, session] = randomAnonymousAccountAndSessionID();
|
|
665
|
-
const node = new LocalNode(admin, session);
|
|
664
|
+
const node = new LocalNode(admin, session, Crypto);
|
|
666
665
|
|
|
667
666
|
const group = node.createGroup();
|
|
668
667
|
|
|
@@ -705,7 +704,7 @@ test.skip("When replaying creation and transactions of a coValue as new content,
|
|
|
705
704
|
// TODO: this test is mostly correct but also slightly unrealistic, make sure we pass all messages back and forth as expected and then it should work
|
|
706
705
|
const [admin, session] = randomAnonymousAccountAndSessionID();
|
|
707
706
|
|
|
708
|
-
const node1 = new LocalNode(admin, session);
|
|
707
|
+
const node1 = new LocalNode(admin, session, Crypto);
|
|
709
708
|
|
|
710
709
|
const group = node1.createGroup();
|
|
711
710
|
|
|
@@ -722,7 +721,7 @@ test.skip("When replaying creation and transactions of a coValue as new content,
|
|
|
722
721
|
const to1 = inTx1.getWriter();
|
|
723
722
|
const from1 = outRx1.getReader();
|
|
724
723
|
|
|
725
|
-
const node2 = new LocalNode(admin, newRandomSessionID(admin.id));
|
|
724
|
+
const node2 = new LocalNode(admin, newRandomSessionID(admin.id), Crypto);
|
|
726
725
|
|
|
727
726
|
const [inRx2, inTx2] = newStreamPair<SyncMessage>();
|
|
728
727
|
const [outRx2, outTx2] = newStreamPair<SyncMessage>();
|
|
@@ -758,7 +757,7 @@ test.skip("When replaying creation and transactions of a coValue as new content,
|
|
|
758
757
|
expect(groupTellKnownStateMsg.value).toMatchObject(groupStateEx(group));
|
|
759
758
|
|
|
760
759
|
expect(
|
|
761
|
-
node2.syncManager.peers["test1"]!.optimisticKnownStates[group.core.id]
|
|
760
|
+
node2.syncManager.peers["test1"]!.optimisticKnownStates[group.core.id],
|
|
762
761
|
).toBeDefined();
|
|
763
762
|
|
|
764
763
|
// await to1.write(adminTellKnownStateMsg.value!);
|
|
@@ -813,8 +812,8 @@ test.skip("When replaying creation and transactions of a coValue as new content,
|
|
|
813
812
|
|
|
814
813
|
expect(
|
|
815
814
|
expectMap(
|
|
816
|
-
node2.expectCoValueLoaded(map.core.id).getCurrentContent()
|
|
817
|
-
).get("hello")
|
|
815
|
+
node2.expectCoValueLoaded(map.core.id).getCurrentContent(),
|
|
816
|
+
).get("hello"),
|
|
818
817
|
).toEqual("world");
|
|
819
818
|
});
|
|
820
819
|
|
|
@@ -822,14 +821,14 @@ test.skip("When loading a coValue on one node, the server node it is requested f
|
|
|
822
821
|
// TODO: this test is mostly correct but also slightly unrealistic, make sure we pass all messages back and forth as expected and then it should work
|
|
823
822
|
const [admin, session] = randomAnonymousAccountAndSessionID();
|
|
824
823
|
|
|
825
|
-
const node1 = new LocalNode(admin, session);
|
|
824
|
+
const node1 = new LocalNode(admin, session, Crypto);
|
|
826
825
|
|
|
827
826
|
const group = node1.createGroup();
|
|
828
827
|
|
|
829
828
|
const map = group.createMap();
|
|
830
829
|
map.set("hello", "world", "trusting");
|
|
831
830
|
|
|
832
|
-
const node2 = new LocalNode(admin, newRandomSessionID(admin.id));
|
|
831
|
+
const node2 = new LocalNode(admin, newRandomSessionID(admin.id), Crypto);
|
|
833
832
|
|
|
834
833
|
const [node1asPeer, node2asPeer] = connectedPeers("peer1", "peer2");
|
|
835
834
|
|
|
@@ -840,15 +839,15 @@ test.skip("When loading a coValue on one node, the server node it is requested f
|
|
|
840
839
|
|
|
841
840
|
expect(
|
|
842
841
|
expectMap(
|
|
843
|
-
node2.expectCoValueLoaded(map.core.id).getCurrentContent()
|
|
844
|
-
).get("hello")
|
|
842
|
+
node2.expectCoValueLoaded(map.core.id).getCurrentContent(),
|
|
843
|
+
).get("hello"),
|
|
845
844
|
).toEqual("world");
|
|
846
845
|
});
|
|
847
846
|
|
|
848
847
|
test("Can sync a coValue through a server to another client", async () => {
|
|
849
848
|
const [admin, session] = randomAnonymousAccountAndSessionID();
|
|
850
849
|
|
|
851
|
-
const client1 = new LocalNode(admin, session);
|
|
850
|
+
const client1 = new LocalNode(admin, session, Crypto);
|
|
852
851
|
|
|
853
852
|
const group = client1.createGroup();
|
|
854
853
|
|
|
@@ -857,7 +856,7 @@ test("Can sync a coValue through a server to another client", async () => {
|
|
|
857
856
|
|
|
858
857
|
const [serverUser, serverSession] = randomAnonymousAccountAndSessionID();
|
|
859
858
|
|
|
860
|
-
const server = new LocalNode(serverUser, serverSession);
|
|
859
|
+
const server = new LocalNode(serverUser, serverSession, Crypto);
|
|
861
860
|
|
|
862
861
|
const [serverAsPeer, client1AsPeer] = connectedPeers("server", "client1", {
|
|
863
862
|
peer1role: "server",
|
|
@@ -868,12 +867,12 @@ test("Can sync a coValue through a server to another client", async () => {
|
|
|
868
867
|
client1.syncManager.addPeer(serverAsPeer);
|
|
869
868
|
server.syncManager.addPeer(client1AsPeer);
|
|
870
869
|
|
|
871
|
-
const client2 = new LocalNode(admin, newRandomSessionID(admin.id));
|
|
870
|
+
const client2 = new LocalNode(admin, newRandomSessionID(admin.id), Crypto);
|
|
872
871
|
|
|
873
872
|
const [serverAsOtherPeer, client2AsPeer] = connectedPeers(
|
|
874
873
|
"server",
|
|
875
874
|
"client2",
|
|
876
|
-
{ peer1role: "server", peer2role: "client", trace: true }
|
|
875
|
+
{ peer1role: "server", peer2role: "client", trace: true },
|
|
877
876
|
);
|
|
878
877
|
|
|
879
878
|
client2.syncManager.addPeer(serverAsOtherPeer);
|
|
@@ -885,14 +884,14 @@ test("Can sync a coValue through a server to another client", async () => {
|
|
|
885
884
|
}
|
|
886
885
|
|
|
887
886
|
expect(expectMap(mapOnClient2.getCurrentContent()).get("hello")).toEqual(
|
|
888
|
-
"world"
|
|
887
|
+
"world",
|
|
889
888
|
);
|
|
890
889
|
});
|
|
891
890
|
|
|
892
891
|
test("Can sync a coValue with private transactions through a server to another client", async () => {
|
|
893
892
|
const [admin, session] = randomAnonymousAccountAndSessionID();
|
|
894
893
|
|
|
895
|
-
const client1 = new LocalNode(admin, session);
|
|
894
|
+
const client1 = new LocalNode(admin, session, Crypto);
|
|
896
895
|
|
|
897
896
|
const group = client1.createGroup();
|
|
898
897
|
|
|
@@ -901,7 +900,7 @@ test("Can sync a coValue with private transactions through a server to another c
|
|
|
901
900
|
|
|
902
901
|
const [serverUser, serverSession] = randomAnonymousAccountAndSessionID();
|
|
903
902
|
|
|
904
|
-
const server = new LocalNode(serverUser, serverSession);
|
|
903
|
+
const server = new LocalNode(serverUser, serverSession, Crypto);
|
|
905
904
|
|
|
906
905
|
const [serverAsPeer, client1AsPeer] = connectedPeers("server", "client1", {
|
|
907
906
|
trace: true,
|
|
@@ -912,12 +911,12 @@ test("Can sync a coValue with private transactions through a server to another c
|
|
|
912
911
|
client1.syncManager.addPeer(serverAsPeer);
|
|
913
912
|
server.syncManager.addPeer(client1AsPeer);
|
|
914
913
|
|
|
915
|
-
const client2 = new LocalNode(admin, newRandomSessionID(admin.id));
|
|
914
|
+
const client2 = new LocalNode(admin, newRandomSessionID(admin.id), Crypto);
|
|
916
915
|
|
|
917
916
|
const [serverAsOtherPeer, client2AsPeer] = connectedPeers(
|
|
918
917
|
"server",
|
|
919
918
|
"client2",
|
|
920
|
-
{ trace: true, peer1role: "server", peer2role: "client" }
|
|
919
|
+
{ trace: true, peer1role: "server", peer2role: "client" },
|
|
921
920
|
);
|
|
922
921
|
|
|
923
922
|
client2.syncManager.addPeer(serverAsOtherPeer);
|
|
@@ -929,13 +928,13 @@ test("Can sync a coValue with private transactions through a server to another c
|
|
|
929
928
|
}
|
|
930
929
|
|
|
931
930
|
expect(expectMap(mapOnClient2.getCurrentContent()).get("hello")).toEqual(
|
|
932
|
-
"world"
|
|
931
|
+
"world",
|
|
933
932
|
);
|
|
934
933
|
});
|
|
935
934
|
|
|
936
935
|
test.skip("When a peer's incoming/readable stream closes, we remove the peer", async () => {
|
|
937
936
|
const [admin, session] = randomAnonymousAccountAndSessionID();
|
|
938
|
-
const node = new LocalNode(admin, session);
|
|
937
|
+
const node = new LocalNode(admin, session, Crypto);
|
|
939
938
|
|
|
940
939
|
const group = node.createGroup();
|
|
941
940
|
|
|
@@ -989,11 +988,11 @@ test.skip("When a peer's incoming/readable stream closes, we remove the peer", a
|
|
|
989
988
|
|
|
990
989
|
test.skip("When a peer's outgoing/writable stream closes, we remove the peer", async () => {
|
|
991
990
|
const [admin, session] = randomAnonymousAccountAndSessionID();
|
|
992
|
-
const node = new LocalNode(admin, session);
|
|
991
|
+
const node = new LocalNode(admin, session, Crypto);
|
|
993
992
|
|
|
994
993
|
const group = node.createGroup();
|
|
995
994
|
|
|
996
|
-
const [inRx
|
|
995
|
+
const [inRx] = newStreamPair<SyncMessage>();
|
|
997
996
|
const [outRx, outTx] = newStreamPair<SyncMessage>();
|
|
998
997
|
|
|
999
998
|
node.syncManager.addPeer({
|
|
@@ -1047,14 +1046,14 @@ test.skip("When a peer's outgoing/writable stream closes, we remove the peer", a
|
|
|
1047
1046
|
test("If we start loading a coValue before connecting to a peer that has it, it will load it once we connect", async () => {
|
|
1048
1047
|
const [admin, session] = randomAnonymousAccountAndSessionID();
|
|
1049
1048
|
|
|
1050
|
-
const node1 = new LocalNode(admin, session);
|
|
1049
|
+
const node1 = new LocalNode(admin, session, Crypto);
|
|
1051
1050
|
|
|
1052
1051
|
const group = node1.createGroup();
|
|
1053
1052
|
|
|
1054
1053
|
const map = group.createMap();
|
|
1055
1054
|
map.set("hello", "world", "trusting");
|
|
1056
1055
|
|
|
1057
|
-
const node2 = new LocalNode(admin, newRandomSessionID(admin.id));
|
|
1056
|
+
const node2 = new LocalNode(admin, newRandomSessionID(admin.id), Crypto);
|
|
1058
1057
|
|
|
1059
1058
|
const [node1asPeer, node2asPeer] = connectedPeers("peer1", "peer2", {
|
|
1060
1059
|
peer1role: "server",
|
|
@@ -1076,7 +1075,7 @@ test("If we start loading a coValue before connecting to a peer that has it, it
|
|
|
1076
1075
|
}
|
|
1077
1076
|
|
|
1078
1077
|
expect(expectMap(mapOnNode2.getCurrentContent()).get("hello")).toEqual(
|
|
1079
|
-
"world"
|
|
1078
|
+
"world",
|
|
1080
1079
|
);
|
|
1081
1080
|
});
|
|
1082
1081
|
|
|
@@ -1087,7 +1086,7 @@ function groupContentEx(group: RawGroup) {
|
|
|
1087
1086
|
};
|
|
1088
1087
|
}
|
|
1089
1088
|
|
|
1090
|
-
function
|
|
1089
|
+
function _admContEx(adminID: AccountID) {
|
|
1091
1090
|
return {
|
|
1092
1091
|
action: "content",
|
|
1093
1092
|
id: adminID,
|
|
@@ -1101,7 +1100,7 @@ function groupStateEx(group: RawGroup) {
|
|
|
1101
1100
|
};
|
|
1102
1101
|
}
|
|
1103
1102
|
|
|
1104
|
-
function
|
|
1103
|
+
function _admStateEx(adminID: AccountID) {
|
|
1105
1104
|
return {
|
|
1106
1105
|
action: "known",
|
|
1107
1106
|
id: adminID,
|
package/src/tests/testUtils.ts
CHANGED
|
@@ -1,35 +1,40 @@
|
|
|
1
1
|
import { expect } from "vitest";
|
|
2
|
-
import { AgentSecret, createdNowUnique, getAgentID, newRandomAgentSecret } from "../crypto.js";
|
|
3
2
|
import { newRandomSessionID } from "../coValueCore.js";
|
|
4
3
|
import { LocalNode } from "../localNode.js";
|
|
5
4
|
import { expectGroup } from "../typeUtils/expectGroup.js";
|
|
6
5
|
import { ControlledAgent } from "../coValues/account.js";
|
|
7
6
|
import { SessionID } from "../ids.js";
|
|
7
|
+
import { WasmCrypto } from "../crypto/WasmCrypto.js";
|
|
8
8
|
|
|
9
|
-
|
|
10
|
-
const agentSecret = newRandomAgentSecret();
|
|
9
|
+
const Crypto = await WasmCrypto.create();
|
|
11
10
|
|
|
12
|
-
|
|
11
|
+
export function randomAnonymousAccountAndSessionID(): [
|
|
12
|
+
ControlledAgent,
|
|
13
|
+
SessionID,
|
|
14
|
+
] {
|
|
15
|
+
const agentSecret = Crypto.newRandomAgentSecret();
|
|
13
16
|
|
|
14
|
-
|
|
17
|
+
const sessionID = newRandomSessionID(Crypto.getAgentID(agentSecret));
|
|
18
|
+
|
|
19
|
+
return [new ControlledAgent(agentSecret, Crypto), sessionID];
|
|
15
20
|
}
|
|
16
21
|
|
|
17
22
|
export function newGroup() {
|
|
18
23
|
const [admin, sessionID] = randomAnonymousAccountAndSessionID();
|
|
19
24
|
|
|
20
|
-
const node = new LocalNode(admin, sessionID);
|
|
25
|
+
const node = new LocalNode(admin, sessionID, Crypto);
|
|
21
26
|
|
|
22
27
|
const groupCore = node.createCoValue({
|
|
23
28
|
type: "comap",
|
|
24
29
|
ruleset: { type: "group", initialAdmin: admin.id },
|
|
25
30
|
meta: null,
|
|
26
|
-
...createdNowUnique(),
|
|
31
|
+
...Crypto.createdNowUnique(),
|
|
27
32
|
});
|
|
28
33
|
|
|
29
34
|
const group = expectGroup(groupCore.getCurrentContent());
|
|
30
35
|
|
|
31
36
|
group.set(admin.id, "admin", "trusting");
|
|
32
|
-
|
|
37
|
+
expect(group.get(admin.id)).toEqual("admin");
|
|
33
38
|
|
|
34
39
|
return { node, groupCore, admin };
|
|
35
40
|
}
|
|
@@ -39,10 +44,10 @@ export function groupWithTwoAdmins() {
|
|
|
39
44
|
|
|
40
45
|
const otherAdmin = node.createAccount();
|
|
41
46
|
|
|
42
|
-
|
|
47
|
+
const group = expectGroup(groupCore.getCurrentContent());
|
|
43
48
|
|
|
44
|
-
|
|
45
|
-
|
|
49
|
+
group.set(otherAdmin.id, "admin", "trusting");
|
|
50
|
+
expect(group.get(otherAdmin.id)).toEqual("admin");
|
|
46
51
|
|
|
47
52
|
if (group.type !== "comap") {
|
|
48
53
|
throw new Error("Expected map");
|
|
@@ -55,8 +60,7 @@ export function groupWithTwoAdmins() {
|
|
|
55
60
|
export function newGroupHighLevel() {
|
|
56
61
|
const [admin, sessionID] = randomAnonymousAccountAndSessionID();
|
|
57
62
|
|
|
58
|
-
|
|
59
|
-
const node = new LocalNode(admin, sessionID);
|
|
63
|
+
const node = new LocalNode(admin, sessionID, Crypto);
|
|
60
64
|
|
|
61
65
|
const group = node.createGroup();
|
|
62
66
|
|
|
@@ -64,7 +68,7 @@ export function newGroupHighLevel() {
|
|
|
64
68
|
}
|
|
65
69
|
|
|
66
70
|
export function groupWithTwoAdminsHighLevel() {
|
|
67
|
-
|
|
71
|
+
const { admin, node, group } = newGroupHighLevel();
|
|
68
72
|
|
|
69
73
|
const otherAdmin = node.createAccount();
|
|
70
74
|
|
|
@@ -75,7 +79,7 @@ export function groupWithTwoAdminsHighLevel() {
|
|
|
75
79
|
|
|
76
80
|
export function shouldNotResolve<T>(
|
|
77
81
|
promise: Promise<T>,
|
|
78
|
-
ops: { timeout: number }
|
|
82
|
+
ops: { timeout: number },
|
|
79
83
|
): Promise<void> {
|
|
80
84
|
return new Promise((resolve, reject) => {
|
|
81
85
|
promise
|
|
@@ -83,12 +87,11 @@ export function shouldNotResolve<T>(
|
|
|
83
87
|
reject(
|
|
84
88
|
new Error(
|
|
85
89
|
"Should not have resolved, but resolved to " +
|
|
86
|
-
JSON.stringify(v)
|
|
87
|
-
)
|
|
88
|
-
)
|
|
90
|
+
JSON.stringify(v),
|
|
91
|
+
),
|
|
92
|
+
),
|
|
89
93
|
)
|
|
90
94
|
.catch(reject);
|
|
91
95
|
setTimeout(resolve, ops.timeout);
|
|
92
96
|
});
|
|
93
97
|
}
|
|
94
|
-
|
|
@@ -1,9 +1,8 @@
|
|
|
1
1
|
import { AgentID, SessionID } from "../ids.js";
|
|
2
2
|
import { AccountID } from "../coValues/account.js";
|
|
3
3
|
|
|
4
|
-
|
|
5
4
|
export function accountOrAgentIDfromSessionID(
|
|
6
|
-
sessionID: SessionID
|
|
5
|
+
sessionID: SessionID,
|
|
7
6
|
): AccountID | AgentID {
|
|
8
7
|
const until = sessionID.indexOf("_session");
|
|
9
8
|
return sessionID.slice(0, until) as AccountID | AgentID;
|
|
@@ -5,9 +5,8 @@ import { RawCoList } from "../coValues/coList.js";
|
|
|
5
5
|
import { RawCoStream } from "../coValues/coStream.js";
|
|
6
6
|
import { RawBinaryCoStream } from "../coValues/coStream.js";
|
|
7
7
|
|
|
8
|
-
|
|
9
8
|
export function isCoValue(
|
|
10
|
-
value: JsonValue | RawCoValue | undefined
|
|
9
|
+
value: JsonValue | RawCoValue | undefined,
|
|
11
10
|
): value is RawCoValue {
|
|
12
11
|
return (
|
|
13
12
|
value instanceof RawCoMap ||
|