cojson 0.14.25 → 0.14.27
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 +1 -1
- package/CHANGELOG.md +8 -0
- package/dist/coValueCore/coValueCore.d.ts +3 -3
- package/dist/coValueCore/coValueCore.d.ts.map +1 -1
- package/dist/coValueCore/coValueCore.js +25 -30
- package/dist/coValueCore/coValueCore.js.map +1 -1
- package/dist/coValueCore/utils.d.ts +4 -0
- package/dist/coValueCore/utils.d.ts.map +1 -0
- package/dist/coValueCore/utils.js +48 -0
- package/dist/coValueCore/utils.js.map +1 -0
- package/dist/exports.d.ts +2 -0
- package/dist/exports.d.ts.map +1 -1
- package/dist/exports.js +2 -0
- package/dist/exports.js.map +1 -1
- package/dist/sync.d.ts.map +1 -1
- package/dist/sync.js +48 -39
- package/dist/sync.js.map +1 -1
- package/dist/tests/coValueCoreLoadingState.test.js +2 -2
- package/dist/tests/sync.load.test.js +256 -2
- package/dist/tests/sync.load.test.js.map +1 -1
- package/dist/tests/sync.mesh.test.js +2 -2
- package/dist/tests/sync.mesh.test.js.map +1 -1
- package/dist/tests/sync.peerReconciliation.test.js +6 -7
- package/dist/tests/sync.peerReconciliation.test.js.map +1 -1
- package/dist/tests/sync.test.js +1 -1
- package/dist/tests/sync.test.js.map +1 -1
- package/dist/tests/testUtils.d.ts +4 -1
- package/dist/tests/testUtils.d.ts.map +1 -1
- package/dist/tests/testUtils.js +6 -2
- package/dist/tests/testUtils.js.map +1 -1
- package/package.json +1 -1
- package/src/coValueCore/coValueCore.ts +33 -41
- package/src/coValueCore/utils.ts +64 -0
- package/src/exports.ts +2 -0
- package/src/sync.ts +63 -40
- package/src/tests/coValueCoreLoadingState.test.ts +2 -2
- package/src/tests/sync.load.test.ts +338 -2
- package/src/tests/sync.mesh.test.ts +2 -2
- package/src/tests/sync.peerReconciliation.test.ts +8 -8
- package/src/tests/sync.test.ts +1 -1
- package/src/tests/testUtils.ts +11 -1
|
@@ -195,7 +195,7 @@ describe("CoValueCore loading state", () => {
|
|
|
195
195
|
role: "storage",
|
|
196
196
|
},
|
|
197
197
|
async () => {
|
|
198
|
-
state.
|
|
198
|
+
state.provideHeader({} as CoValueHeader, "peer1");
|
|
199
199
|
},
|
|
200
200
|
);
|
|
201
201
|
const peer2 = createMockPeerState(
|
|
@@ -248,7 +248,7 @@ describe("CoValueCore loading state", () => {
|
|
|
248
248
|
role: "server",
|
|
249
249
|
},
|
|
250
250
|
async () => {
|
|
251
|
-
state.
|
|
251
|
+
state.provideHeader({} as CoValueHeader, "peer2");
|
|
252
252
|
},
|
|
253
253
|
);
|
|
254
254
|
|
|
@@ -1,16 +1,22 @@
|
|
|
1
|
-
import { beforeEach, describe, expect, test } from "vitest";
|
|
1
|
+
import { beforeEach, describe, expect, onTestFinished, test, vi } from "vitest";
|
|
2
2
|
|
|
3
3
|
import { expectMap } from "../coValue";
|
|
4
|
-
import {
|
|
4
|
+
import { CO_VALUE_LOADING_CONFIG } from "../coValueCore/coValueCore";
|
|
5
|
+
import { RawCoMap } from "../exports";
|
|
5
6
|
import {
|
|
6
7
|
SyncMessagesLog,
|
|
8
|
+
blockMessageTypeOnOutgoingPeer,
|
|
7
9
|
loadCoValueOrFail,
|
|
10
|
+
setupTestAccount,
|
|
8
11
|
setupTestNode,
|
|
9
12
|
waitFor,
|
|
10
13
|
} from "./testUtils";
|
|
11
14
|
|
|
12
15
|
let jazzCloud = setupTestNode({ isSyncServer: true });
|
|
13
16
|
|
|
17
|
+
// Set a short timeout to make the tests on unavailable complete faster
|
|
18
|
+
CO_VALUE_LOADING_CONFIG.RETRY_DELAY = 100;
|
|
19
|
+
|
|
14
20
|
beforeEach(async () => {
|
|
15
21
|
SyncMessagesLog.clear();
|
|
16
22
|
jazzCloud = setupTestNode({ isSyncServer: true });
|
|
@@ -406,4 +412,334 @@ describe("loading coValues from server", () => {
|
|
|
406
412
|
]
|
|
407
413
|
`);
|
|
408
414
|
});
|
|
415
|
+
|
|
416
|
+
test("coValue with a delayed group loading", async () => {
|
|
417
|
+
const client = setupTestNode();
|
|
418
|
+
|
|
419
|
+
const { peerOnServer } = client.connectToSyncServer();
|
|
420
|
+
|
|
421
|
+
const group = jazzCloud.node.createGroup();
|
|
422
|
+
const parentGroup = jazzCloud.node.createGroup();
|
|
423
|
+
parentGroup.addMember("everyone", "reader");
|
|
424
|
+
|
|
425
|
+
const blocker = blockMessageTypeOnOutgoingPeer(peerOnServer, "content", {
|
|
426
|
+
id: group.id,
|
|
427
|
+
once: true,
|
|
428
|
+
});
|
|
429
|
+
|
|
430
|
+
group.extend(parentGroup);
|
|
431
|
+
|
|
432
|
+
const map = group.createMap();
|
|
433
|
+
map.set("hello", "world");
|
|
434
|
+
|
|
435
|
+
const mapOnClient = await loadCoValueOrFail(client.node, map.id);
|
|
436
|
+
expect(mapOnClient.get("hello")).toEqual("world");
|
|
437
|
+
|
|
438
|
+
expect(
|
|
439
|
+
SyncMessagesLog.getMessages({
|
|
440
|
+
ParentGroup: parentGroup.core,
|
|
441
|
+
Group: group.core,
|
|
442
|
+
Map: map.core,
|
|
443
|
+
}),
|
|
444
|
+
).toMatchInlineSnapshot(`
|
|
445
|
+
[
|
|
446
|
+
"client -> server | LOAD Map sessions: empty",
|
|
447
|
+
"server -> client | CONTENT ParentGroup header: true new: After: 0 New: 6",
|
|
448
|
+
"client -> server | KNOWN ParentGroup sessions: header/6",
|
|
449
|
+
"server -> client | CONTENT Map header: true new: After: 0 New: 1",
|
|
450
|
+
"client -> server | LOAD Group sessions: empty",
|
|
451
|
+
"client -> server | KNOWN Map sessions: empty",
|
|
452
|
+
"server -> client | CONTENT Group header: true new: After: 0 New: 5",
|
|
453
|
+
"client -> server | KNOWN Group sessions: header/5",
|
|
454
|
+
]
|
|
455
|
+
`);
|
|
456
|
+
|
|
457
|
+
blocker.unblock();
|
|
458
|
+
});
|
|
459
|
+
|
|
460
|
+
test("coValue with a delayed parent group loading", async () => {
|
|
461
|
+
const client = setupTestNode();
|
|
462
|
+
|
|
463
|
+
const { peerOnServer } = client.connectToSyncServer();
|
|
464
|
+
|
|
465
|
+
const group = jazzCloud.node.createGroup();
|
|
466
|
+
const parentGroup = jazzCloud.node.createGroup();
|
|
467
|
+
parentGroup.addMember("everyone", "reader");
|
|
468
|
+
|
|
469
|
+
const blocker = blockMessageTypeOnOutgoingPeer(peerOnServer, "content", {
|
|
470
|
+
id: parentGroup.id,
|
|
471
|
+
once: true,
|
|
472
|
+
});
|
|
473
|
+
|
|
474
|
+
group.extend(parentGroup);
|
|
475
|
+
|
|
476
|
+
const map = group.createMap();
|
|
477
|
+
map.set("hello", "world");
|
|
478
|
+
|
|
479
|
+
const mapOnClient = await loadCoValueOrFail(client.node, map.id);
|
|
480
|
+
expect(mapOnClient.get("hello")).toEqual("world");
|
|
481
|
+
|
|
482
|
+
expect(
|
|
483
|
+
SyncMessagesLog.getMessages({
|
|
484
|
+
ParentGroup: parentGroup.core,
|
|
485
|
+
Group: group.core,
|
|
486
|
+
Map: map.core,
|
|
487
|
+
}),
|
|
488
|
+
).toMatchInlineSnapshot(`
|
|
489
|
+
[
|
|
490
|
+
"client -> server | LOAD Map sessions: empty",
|
|
491
|
+
"server -> client | CONTENT Group header: true new: After: 0 New: 5",
|
|
492
|
+
"client -> server | LOAD ParentGroup sessions: empty",
|
|
493
|
+
"client -> server | KNOWN Group sessions: empty",
|
|
494
|
+
"server -> client | CONTENT ParentGroup header: true new: After: 0 New: 6",
|
|
495
|
+
"client -> server | KNOWN ParentGroup sessions: header/6",
|
|
496
|
+
"server -> client | CONTENT Map header: true new: After: 0 New: 1",
|
|
497
|
+
"client -> server | KNOWN Map sessions: header/1",
|
|
498
|
+
]
|
|
499
|
+
`);
|
|
500
|
+
|
|
501
|
+
blocker.unblock();
|
|
502
|
+
});
|
|
503
|
+
|
|
504
|
+
test("coValue with a delayed account loading (block once)", async () => {
|
|
505
|
+
const client = setupTestNode();
|
|
506
|
+
const syncServer = await setupTestAccount({ isSyncServer: true });
|
|
507
|
+
|
|
508
|
+
const { peerOnServer } = client.connectToSyncServer({
|
|
509
|
+
syncServer: syncServer.node,
|
|
510
|
+
});
|
|
511
|
+
|
|
512
|
+
const group = syncServer.node.createGroup();
|
|
513
|
+
group.addMember("everyone", "writer");
|
|
514
|
+
const blocker = blockMessageTypeOnOutgoingPeer(peerOnServer, "content", {
|
|
515
|
+
id: syncServer.accountID,
|
|
516
|
+
once: true,
|
|
517
|
+
});
|
|
518
|
+
|
|
519
|
+
const account = syncServer.node.expectCurrentAccount(syncServer.accountID);
|
|
520
|
+
|
|
521
|
+
const map = group.createMap();
|
|
522
|
+
map.set("hello", "world");
|
|
523
|
+
|
|
524
|
+
const mapOnClient = await loadCoValueOrFail(client.node, map.id);
|
|
525
|
+
expect(mapOnClient.get("hello")).toEqual("world");
|
|
526
|
+
|
|
527
|
+
// ParentGroup sent twice, once because the server pushed it and another time because the client requested the missing dependency
|
|
528
|
+
expect(
|
|
529
|
+
SyncMessagesLog.getMessages({
|
|
530
|
+
Account: account.core,
|
|
531
|
+
Group: group.core,
|
|
532
|
+
Map: map.core,
|
|
533
|
+
}),
|
|
534
|
+
).toMatchInlineSnapshot(`
|
|
535
|
+
[
|
|
536
|
+
"client -> server | LOAD Map sessions: empty",
|
|
537
|
+
"server -> client | CONTENT Group header: true new: After: 0 New: 5",
|
|
538
|
+
"client -> server | LOAD Account sessions: empty",
|
|
539
|
+
"client -> server | KNOWN Group sessions: empty",
|
|
540
|
+
"server -> client | CONTENT Account header: true new: After: 0 New: 4",
|
|
541
|
+
"client -> server | KNOWN Account sessions: header/4",
|
|
542
|
+
"client -> server | KNOWN Group sessions: header/5",
|
|
543
|
+
"server -> client | CONTENT Map header: true new: After: 0 New: 1",
|
|
544
|
+
"client -> server | KNOWN Map sessions: header/1",
|
|
545
|
+
]
|
|
546
|
+
`);
|
|
547
|
+
|
|
548
|
+
blocker.unblock();
|
|
549
|
+
});
|
|
550
|
+
|
|
551
|
+
test("coValue with a delayed account loading related to an update (block once)", async () => {
|
|
552
|
+
const client = setupTestNode();
|
|
553
|
+
const user = await setupTestAccount({
|
|
554
|
+
connected: true,
|
|
555
|
+
});
|
|
556
|
+
|
|
557
|
+
const { peerOnServer } = client.connectToSyncServer();
|
|
558
|
+
|
|
559
|
+
const account = user.node.expectCurrentAccount(user.accountID);
|
|
560
|
+
await user.node.syncManager.waitForAllCoValuesSync();
|
|
561
|
+
|
|
562
|
+
SyncMessagesLog.clear();
|
|
563
|
+
|
|
564
|
+
const group = jazzCloud.node.createGroup();
|
|
565
|
+
group.addMember("everyone", "writer");
|
|
566
|
+
const blocker = blockMessageTypeOnOutgoingPeer(peerOnServer, "content", {
|
|
567
|
+
id: user.accountID,
|
|
568
|
+
once: true,
|
|
569
|
+
});
|
|
570
|
+
|
|
571
|
+
const map = group.createMap();
|
|
572
|
+
map.set("hello", "world");
|
|
573
|
+
|
|
574
|
+
const mapOnUser = await loadCoValueOrFail(user.node, map.id);
|
|
575
|
+
mapOnUser.set("user", true);
|
|
576
|
+
|
|
577
|
+
await mapOnUser.core.waitForSync();
|
|
578
|
+
|
|
579
|
+
const mapOnClient = await loadCoValueOrFail(client.node, map.id);
|
|
580
|
+
expect(mapOnClient.get("user")).toEqual(true);
|
|
581
|
+
|
|
582
|
+
// ParentGroup sent twice, once because the server pushed it and another time because the client requested the missing dependency
|
|
583
|
+
expect(
|
|
584
|
+
SyncMessagesLog.getMessages({
|
|
585
|
+
Account: account.core,
|
|
586
|
+
Group: group.core,
|
|
587
|
+
Map: map.core,
|
|
588
|
+
}),
|
|
589
|
+
).toMatchInlineSnapshot(`
|
|
590
|
+
[
|
|
591
|
+
"client -> server | LOAD Map sessions: empty",
|
|
592
|
+
"server -> client | CONTENT Group header: true new: After: 0 New: 5",
|
|
593
|
+
"client -> server | KNOWN Group sessions: header/5",
|
|
594
|
+
"server -> client | CONTENT Map header: true new: After: 0 New: 1",
|
|
595
|
+
"client -> server | KNOWN Map sessions: header/1",
|
|
596
|
+
"client -> server | CONTENT Map header: false new: After: 0 New: 1",
|
|
597
|
+
"server -> client | KNOWN Map sessions: header/2",
|
|
598
|
+
"client -> server | LOAD Map sessions: empty",
|
|
599
|
+
"server -> client | CONTENT Group header: true new: After: 0 New: 5",
|
|
600
|
+
"client -> server | KNOWN Group sessions: header/5",
|
|
601
|
+
"server -> client | CONTENT Map header: true new: After: 0 New: 1 | After: 0 New: 1",
|
|
602
|
+
"client -> server | LOAD Account sessions: empty",
|
|
603
|
+
"client -> server | KNOWN Map sessions: empty",
|
|
604
|
+
"server -> client | CONTENT Account header: true new: After: 0 New: 4",
|
|
605
|
+
"client -> server | KNOWN Account sessions: header/4",
|
|
606
|
+
"client -> server | KNOWN Map sessions: header/2",
|
|
607
|
+
]
|
|
608
|
+
`);
|
|
609
|
+
|
|
610
|
+
blocker.unblock();
|
|
611
|
+
});
|
|
612
|
+
|
|
613
|
+
test("coValue with a delayed account loading (block for 100ms)", async () => {
|
|
614
|
+
const client = setupTestNode();
|
|
615
|
+
const syncServer = await setupTestAccount({ isSyncServer: true });
|
|
616
|
+
|
|
617
|
+
const { peerOnServer } = client.connectToSyncServer({
|
|
618
|
+
syncServer: syncServer.node,
|
|
619
|
+
});
|
|
620
|
+
|
|
621
|
+
const group = syncServer.node.createGroup();
|
|
622
|
+
group.addMember("everyone", "writer");
|
|
623
|
+
|
|
624
|
+
const blocker = blockMessageTypeOnOutgoingPeer(peerOnServer, "content", {
|
|
625
|
+
id: syncServer.accountID,
|
|
626
|
+
});
|
|
627
|
+
|
|
628
|
+
const account = syncServer.node.expectCurrentAccount(syncServer.accountID);
|
|
629
|
+
|
|
630
|
+
const map = group.createMap();
|
|
631
|
+
map.set("hello", "world");
|
|
632
|
+
|
|
633
|
+
const core = client.node.getCoValue(map.id);
|
|
634
|
+
const promise = client.node.loadCoValueCore(map.id);
|
|
635
|
+
|
|
636
|
+
const spy = vi.fn();
|
|
637
|
+
|
|
638
|
+
core.subscribe(spy);
|
|
639
|
+
spy.mockClear(); // Reset the first call
|
|
640
|
+
|
|
641
|
+
await new Promise((resolve) => setTimeout(resolve, 100));
|
|
642
|
+
|
|
643
|
+
blocker.sendBlockedMessages();
|
|
644
|
+
blocker.unblock();
|
|
645
|
+
|
|
646
|
+
await promise;
|
|
647
|
+
|
|
648
|
+
expect(spy).toHaveBeenCalled();
|
|
649
|
+
expect(core.isAvailable()).toBe(true);
|
|
650
|
+
|
|
651
|
+
const mapOnClient = expectMap(core.getCurrentContent());
|
|
652
|
+
expect(mapOnClient.get("hello")).toEqual("world");
|
|
653
|
+
|
|
654
|
+
// Account sent twice, once because the server pushed it and another time because the client requested the missing dependency
|
|
655
|
+
expect(
|
|
656
|
+
SyncMessagesLog.getMessages({
|
|
657
|
+
Account: account.core,
|
|
658
|
+
Group: group.core,
|
|
659
|
+
Map: map.core,
|
|
660
|
+
}),
|
|
661
|
+
).toMatchInlineSnapshot(`
|
|
662
|
+
[
|
|
663
|
+
"client -> server | LOAD Map sessions: empty",
|
|
664
|
+
"server -> client | CONTENT Group header: true new: After: 0 New: 5",
|
|
665
|
+
"client -> server | LOAD Account sessions: empty",
|
|
666
|
+
"client -> server | KNOWN Group sessions: empty",
|
|
667
|
+
"server -> client | CONTENT Map header: true new: After: 0 New: 1",
|
|
668
|
+
"client -> server | KNOWN Map sessions: empty",
|
|
669
|
+
"server -> client | CONTENT Account header: true new: After: 0 New: 4",
|
|
670
|
+
"client -> server | KNOWN Account sessions: header/4",
|
|
671
|
+
"server -> client | CONTENT Account header: true new: After: 0 New: 4",
|
|
672
|
+
"client -> server | KNOWN Group sessions: header/5",
|
|
673
|
+
]
|
|
674
|
+
`);
|
|
675
|
+
});
|
|
676
|
+
|
|
677
|
+
test("coValue with a delayed account loading with no group (block for 100ms)", async () => {
|
|
678
|
+
const client = setupTestNode();
|
|
679
|
+
const syncServer = await setupTestAccount({ isSyncServer: true });
|
|
680
|
+
|
|
681
|
+
const { peerOnServer } = client.connectToSyncServer({
|
|
682
|
+
syncServer: syncServer.node,
|
|
683
|
+
});
|
|
684
|
+
|
|
685
|
+
const blocker = blockMessageTypeOnOutgoingPeer(peerOnServer, "content", {
|
|
686
|
+
id: syncServer.accountID,
|
|
687
|
+
});
|
|
688
|
+
|
|
689
|
+
const account = syncServer.node.expectCurrentAccount(syncServer.accountID);
|
|
690
|
+
|
|
691
|
+
const map = syncServer.node
|
|
692
|
+
.createCoValue({
|
|
693
|
+
type: "comap",
|
|
694
|
+
ruleset: {
|
|
695
|
+
type: "ownedByGroup",
|
|
696
|
+
group: syncServer.accountID,
|
|
697
|
+
},
|
|
698
|
+
meta: null,
|
|
699
|
+
...syncServer.node.crypto.createdNowUnique(),
|
|
700
|
+
})
|
|
701
|
+
.getCurrentContent() as RawCoMap;
|
|
702
|
+
|
|
703
|
+
map.set("hello", "world", "trusting");
|
|
704
|
+
|
|
705
|
+
const core = client.node.getCoValue(map.id);
|
|
706
|
+
const promise = client.node.loadCoValueCore(map.id);
|
|
707
|
+
|
|
708
|
+
const spy = vi.fn();
|
|
709
|
+
|
|
710
|
+
core.subscribe(spy);
|
|
711
|
+
spy.mockClear(); // Reset the first call
|
|
712
|
+
|
|
713
|
+
await new Promise((resolve) => setTimeout(resolve, 100));
|
|
714
|
+
|
|
715
|
+
blocker.sendBlockedMessages();
|
|
716
|
+
blocker.unblock();
|
|
717
|
+
|
|
718
|
+
await promise;
|
|
719
|
+
|
|
720
|
+
expect(spy).toHaveBeenCalled();
|
|
721
|
+
expect(core.isAvailable()).toBe(true);
|
|
722
|
+
|
|
723
|
+
const mapOnClient = expectMap(core.getCurrentContent());
|
|
724
|
+
expect(mapOnClient.get("hello")).toEqual("world");
|
|
725
|
+
|
|
726
|
+
// Account sent twice, once because the server pushed it and another time because the client requested the missing dependency
|
|
727
|
+
expect(
|
|
728
|
+
SyncMessagesLog.getMessages({
|
|
729
|
+
Account: account.core,
|
|
730
|
+
Map: map.core,
|
|
731
|
+
}),
|
|
732
|
+
).toMatchInlineSnapshot(`
|
|
733
|
+
[
|
|
734
|
+
"client -> server | LOAD Map sessions: empty",
|
|
735
|
+
"server -> client | CONTENT Map header: true new: After: 0 New: 1",
|
|
736
|
+
"client -> server | LOAD Account sessions: empty",
|
|
737
|
+
"client -> server | KNOWN Map sessions: empty",
|
|
738
|
+
"server -> client | CONTENT Account header: true new: After: 0 New: 4",
|
|
739
|
+
"client -> server | KNOWN Account sessions: header/4",
|
|
740
|
+
"server -> client | CONTENT Account header: true new: After: 0 New: 4",
|
|
741
|
+
"client -> server | KNOWN Map sessions: header/1",
|
|
742
|
+
]
|
|
743
|
+
`);
|
|
744
|
+
});
|
|
409
745
|
});
|
|
@@ -380,7 +380,7 @@ describe("multiple clients syncing with the a cloud-like server mesh", () => {
|
|
|
380
380
|
map.set("hello", "updated", "trusting");
|
|
381
381
|
|
|
382
382
|
// Block the content message from the core peer to simulate the delay on response
|
|
383
|
-
blockMessageTypeOnOutgoingPeer(peerOnServer, "content");
|
|
383
|
+
blockMessageTypeOnOutgoingPeer(peerOnServer, "content", {});
|
|
384
384
|
|
|
385
385
|
const mapOnClient = await loadCoValueOrFail(client.node, map.id);
|
|
386
386
|
|
|
@@ -431,7 +431,7 @@ describe("multiple clients syncing with the a cloud-like server mesh", () => {
|
|
|
431
431
|
},
|
|
432
432
|
});
|
|
433
433
|
|
|
434
|
-
blockMessageTypeOnOutgoingPeer(peerToCoreServer, "load");
|
|
434
|
+
blockMessageTypeOnOutgoingPeer(peerToCoreServer, "load", {});
|
|
435
435
|
|
|
436
436
|
client.node.syncManager.addPeer(peer1);
|
|
437
437
|
anotherServer.node.syncManager.addPeer(peer2);
|
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
import { assert, beforeEach, describe, expect, test } from "vitest";
|
|
2
2
|
import { expectMap } from "../coValue";
|
|
3
|
+
import { CO_VALUE_LOADING_CONFIG } from "../coValueCore/coValueCore";
|
|
3
4
|
import { WasmCrypto } from "../crypto/WasmCrypto";
|
|
5
|
+
import { RawCoMap } from "../exports";
|
|
4
6
|
import {
|
|
5
7
|
SyncMessagesLog,
|
|
6
|
-
loadCoValueOrFail,
|
|
7
8
|
setupTestAccount,
|
|
8
9
|
setupTestNode,
|
|
9
10
|
waitFor,
|
|
@@ -195,10 +196,8 @@ describe("peer reconciliation", () => {
|
|
|
195
196
|
"client -> server | CONTENT Map header: true new: After: 0 New: 2",
|
|
196
197
|
"server -> client | LOAD Group sessions: empty",
|
|
197
198
|
"client -> server | CONTENT Group header: true new: After: 0 New: 3",
|
|
198
|
-
"server -> client | KNOWN
|
|
199
|
-
"client -> server | CONTENT Map header: true new: After: 0 New: 2",
|
|
199
|
+
"server -> client | KNOWN Map sessions: empty",
|
|
200
200
|
"server -> client | KNOWN Group sessions: header/3",
|
|
201
|
-
"server -> client | KNOWN Map sessions: header/2",
|
|
202
201
|
"client -> server | LOAD Group sessions: header/3",
|
|
203
202
|
"server -> client | KNOWN Group sessions: header/3",
|
|
204
203
|
"client -> server | LOAD Map sessions: header/2",
|
|
@@ -232,7 +231,9 @@ describe("peer reconciliation", () => {
|
|
|
232
231
|
await waitFor(() => {
|
|
233
232
|
const mapOnSyncServer = jazzCloud.node.getCoValue(map.id);
|
|
234
233
|
|
|
235
|
-
expect(mapOnSyncServer.
|
|
234
|
+
expect(mapOnSyncServer.isAvailable()).toBe(true);
|
|
235
|
+
const content = mapOnSyncServer.getCurrentContent() as RawCoMap;
|
|
236
|
+
expect(content.get("hello")).toBe("updated");
|
|
236
237
|
});
|
|
237
238
|
|
|
238
239
|
expect(
|
|
@@ -263,11 +264,10 @@ describe("peer reconciliation", () => {
|
|
|
263
264
|
"client -> server | CONTENT Account header: true new: After: 0 New: 4",
|
|
264
265
|
"server -> client | LOAD Group sessions: empty",
|
|
265
266
|
"client -> server | CONTENT Group header: true new: After: 0 New: 3",
|
|
266
|
-
"server -> client | KNOWN
|
|
267
|
-
"client -> server | CONTENT Map header: true new: After: 0 New: 2",
|
|
267
|
+
"server -> client | KNOWN Map sessions: empty",
|
|
268
268
|
"server -> client | KNOWN Account sessions: header/4",
|
|
269
|
+
"server -> client | KNOWN Map sessions: empty",
|
|
269
270
|
"server -> client | KNOWN Group sessions: header/3",
|
|
270
|
-
"server -> client | KNOWN Map sessions: header/2",
|
|
271
271
|
"client -> server | LOAD Account sessions: header/4",
|
|
272
272
|
"server -> client | KNOWN Account sessions: header/4",
|
|
273
273
|
"client -> server | LOAD ProfileGroup sessions: header/5",
|
package/src/tests/sync.test.ts
CHANGED
|
@@ -601,7 +601,7 @@ describe("SyncManager - knownStates vs optimisticKnownStates", () => {
|
|
|
601
601
|
// optimisticKnownStates is updated when the content messages are sent,
|
|
602
602
|
// while knownStates is only updated when we receive the "known" messages
|
|
603
603
|
// that are acknowledging the receipt of the content messages
|
|
604
|
-
const outgoing = blockMessageTypeOnOutgoingPeer(peer, "content");
|
|
604
|
+
const outgoing = blockMessageTypeOnOutgoingPeer(peer, "content", {});
|
|
605
605
|
|
|
606
606
|
map.set("key2", "value2", "trusting");
|
|
607
607
|
|
package/src/tests/testUtils.ts
CHANGED
|
@@ -287,15 +287,25 @@ export async function loadCoValueOrFail<V extends RawCoValue>(
|
|
|
287
287
|
export function blockMessageTypeOnOutgoingPeer(
|
|
288
288
|
peer: Peer,
|
|
289
289
|
messageType: SyncMessage["action"],
|
|
290
|
+
opts: {
|
|
291
|
+
id?: string;
|
|
292
|
+
once?: boolean;
|
|
293
|
+
},
|
|
290
294
|
) {
|
|
291
295
|
const push = peer.outgoing.push;
|
|
292
296
|
const pushSpy = vi.spyOn(peer.outgoing, "push");
|
|
293
297
|
|
|
294
298
|
const blockedMessages: SyncMessage[] = [];
|
|
299
|
+
const blockedIds = new Set<string>();
|
|
295
300
|
|
|
296
301
|
pushSpy.mockImplementation(async (msg) => {
|
|
297
|
-
if (
|
|
302
|
+
if (
|
|
303
|
+
msg.action === messageType &&
|
|
304
|
+
(!opts.id || msg.id === opts.id) &&
|
|
305
|
+
(!opts.once || !blockedIds.has(msg.id))
|
|
306
|
+
) {
|
|
298
307
|
blockedMessages.push(msg);
|
|
308
|
+
blockedIds.add(msg.id);
|
|
299
309
|
return Promise.resolve();
|
|
300
310
|
}
|
|
301
311
|
|