cojson 0.18.28 → 0.18.30
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 +16 -0
- package/dist/PeerState.d.ts +23 -14
- package/dist/PeerState.d.ts.map +1 -1
- package/dist/PeerState.js +74 -23
- package/dist/PeerState.js.map +1 -1
- package/dist/SyncStateManager.d.ts +3 -3
- package/dist/SyncStateManager.d.ts.map +1 -1
- package/dist/SyncStateManager.js +18 -44
- package/dist/SyncStateManager.js.map +1 -1
- package/dist/coValueContentMessage.d.ts.map +1 -1
- package/dist/coValueContentMessage.js +2 -1
- package/dist/coValueContentMessage.js.map +1 -1
- package/dist/coValueCore/PeerKnownState.d.ts +21 -0
- package/dist/coValueCore/PeerKnownState.d.ts.map +1 -0
- package/dist/coValueCore/PeerKnownState.js +52 -0
- package/dist/coValueCore/PeerKnownState.js.map +1 -0
- package/dist/coValueCore/coValueCore.d.ts +39 -8
- package/dist/coValueCore/coValueCore.d.ts.map +1 -1
- package/dist/coValueCore/coValueCore.js +139 -40
- package/dist/coValueCore/coValueCore.js.map +1 -1
- package/dist/coValueCore/decryptTransactionChangesAndMeta.d.ts.map +1 -1
- package/dist/coValueCore/decryptTransactionChangesAndMeta.js +0 -5
- package/dist/coValueCore/decryptTransactionChangesAndMeta.js.map +1 -1
- package/dist/coValueCore/verifiedState.d.ts +0 -14
- package/dist/coValueCore/verifiedState.d.ts.map +1 -1
- package/dist/coValueCore/verifiedState.js +2 -32
- package/dist/coValueCore/verifiedState.js.map +1 -1
- package/dist/coValues/coList.d.ts +3 -4
- package/dist/coValues/coList.d.ts.map +1 -1
- package/dist/coValues/coList.js +4 -4
- package/dist/coValues/coList.js.map +1 -1
- package/dist/coValues/coMap.d.ts +3 -4
- package/dist/coValues/coMap.d.ts.map +1 -1
- package/dist/coValues/coMap.js +5 -4
- package/dist/coValues/coMap.js.map +1 -1
- package/dist/coValues/coStream.d.ts +3 -3
- package/dist/coValues/coStream.d.ts.map +1 -1
- package/dist/coValues/coStream.js +3 -4
- package/dist/coValues/coStream.js.map +1 -1
- package/dist/coValues/group.d.ts +3 -3
- package/dist/coValues/group.d.ts.map +1 -1
- package/dist/coValues/group.js +74 -52
- package/dist/coValues/group.js.map +1 -1
- package/dist/exports.d.ts +2 -2
- package/dist/exports.d.ts.map +1 -1
- package/dist/exports.js +2 -2
- package/dist/exports.js.map +1 -1
- package/dist/localNode.d.ts.map +1 -1
- package/dist/localNode.js +7 -5
- package/dist/localNode.js.map +1 -1
- package/dist/permissions.d.ts +5 -1
- package/dist/permissions.d.ts.map +1 -1
- package/dist/permissions.js +173 -109
- package/dist/permissions.js.map +1 -1
- package/dist/sync.d.ts.map +1 -1
- package/dist/sync.js +33 -44
- package/dist/sync.js.map +1 -1
- package/dist/tests/PeerKnownState.test.d.ts +2 -0
- package/dist/tests/PeerKnownState.test.d.ts.map +1 -0
- package/dist/tests/PeerKnownState.test.js +342 -0
- package/dist/tests/PeerKnownState.test.js.map +1 -0
- package/dist/tests/PeerState.test.js +17 -16
- package/dist/tests/PeerState.test.js.map +1 -1
- package/dist/tests/StorageApiAsync.test.js +12 -12
- package/dist/tests/StorageApiAsync.test.js.map +1 -1
- package/dist/tests/StorageApiSync.test.js +11 -11
- package/dist/tests/StorageApiSync.test.js.map +1 -1
- package/dist/tests/SyncStateManager.test.js +16 -21
- package/dist/tests/SyncStateManager.test.js.map +1 -1
- package/dist/tests/coValueCore.dependencies.test.js +59 -0
- package/dist/tests/coValueCore.dependencies.test.js.map +1 -1
- package/dist/tests/coValueCore.test.js +41 -21
- package/dist/tests/coValueCore.test.js.map +1 -1
- package/dist/tests/group.addMember.test.js +266 -219
- package/dist/tests/group.addMember.test.js.map +1 -1
- package/dist/tests/group.inheritance.test.js +12 -0
- package/dist/tests/group.inheritance.test.js.map +1 -1
- package/dist/tests/group.invite.test.js +77 -0
- package/dist/tests/group.invite.test.js.map +1 -1
- package/dist/tests/group.removeMember.test.js +64 -7
- package/dist/tests/group.removeMember.test.js.map +1 -1
- package/dist/tests/group.roleOf.test.js +14 -4
- package/dist/tests/group.roleOf.test.js.map +1 -1
- package/dist/tests/permissions.test.js +51 -202
- package/dist/tests/permissions.test.js.map +1 -1
- package/dist/tests/sync.content.test.js +2 -2
- package/dist/tests/sync.content.test.js.map +1 -1
- package/dist/tests/sync.invite.test.js +6 -6
- package/dist/tests/sync.load.test.js +22 -22
- package/dist/tests/sync.mesh.test.js +9 -9
- package/dist/tests/sync.storage.test.js +13 -7
- package/dist/tests/sync.storage.test.js.map +1 -1
- package/dist/tests/sync.storageAsync.test.js +3 -3
- package/dist/tests/sync.test.js +13 -33
- package/dist/tests/sync.test.js.map +1 -1
- package/dist/tests/sync.upload.test.js +2 -2
- package/package.json +3 -3
- package/src/PeerState.ts +86 -34
- package/src/SyncStateManager.ts +25 -60
- package/src/coValueContentMessage.ts +3 -1
- package/src/coValueCore/PeerKnownState.ts +74 -0
- package/src/coValueCore/coValueCore.ts +180 -49
- package/src/coValueCore/decryptTransactionChangesAndMeta.ts +0 -6
- package/src/coValueCore/verifiedState.ts +2 -37
- package/src/coValues/coList.ts +7 -7
- package/src/coValues/coMap.ts +9 -7
- package/src/coValues/coStream.ts +6 -5
- package/src/coValues/group.ts +99 -60
- package/src/exports.ts +2 -1
- package/src/localNode.ts +7 -5
- package/src/permissions.ts +204 -123
- package/src/sync.ts +37 -53
- package/src/tests/PeerKnownState.test.ts +426 -0
- package/src/tests/PeerState.test.ts +24 -24
- package/src/tests/StorageApiAsync.test.ts +12 -12
- package/src/tests/StorageApiSync.test.ts +11 -11
- package/src/tests/SyncStateManager.test.ts +23 -53
- package/src/tests/coValueCore.dependencies.test.ts +87 -0
- package/src/tests/coValueCore.test.ts +64 -22
- package/src/tests/group.addMember.test.ts +384 -345
- package/src/tests/group.inheritance.test.ts +33 -0
- package/src/tests/group.invite.test.ts +117 -0
- package/src/tests/group.removeMember.test.ts +95 -9
- package/src/tests/group.roleOf.test.ts +16 -4
- package/src/tests/permissions.test.ts +56 -295
- package/src/tests/sync.content.test.ts +2 -2
- package/src/tests/sync.invite.test.ts +6 -6
- package/src/tests/sync.load.test.ts +22 -22
- package/src/tests/sync.mesh.test.ts +9 -9
- package/src/tests/sync.storage.test.ts +13 -8
- package/src/tests/sync.storageAsync.test.ts +3 -3
- package/src/tests/sync.test.ts +21 -50
- package/src/tests/sync.upload.test.ts +2 -2
- package/dist/PeerKnownStates.d.ts +0 -19
- package/dist/PeerKnownStates.d.ts.map +0 -1
- package/dist/PeerKnownStates.js +0 -64
- package/dist/PeerKnownStates.js.map +0 -1
- package/dist/tests/PeerKnownStates.test.d.ts +0 -2
- package/dist/tests/PeerKnownStates.test.d.ts.map +0 -1
- package/dist/tests/PeerKnownStates.test.js +0 -77
- package/dist/tests/PeerKnownStates.test.js.map +0 -1
- package/src/PeerKnownStates.ts +0 -93
- package/src/tests/PeerKnownStates.test.ts +0 -99
|
@@ -154,14 +154,14 @@ describe("multiple clients syncing with the a cloud-like server mesh", () => {
|
|
|
154
154
|
[
|
|
155
155
|
"edge-france -> storage | CONTENT Group header: true new: After: 0 New: 3",
|
|
156
156
|
"edge-france -> core | CONTENT Group header: true new: After: 0 New: 3",
|
|
157
|
-
"edge-france -> storage | CONTENT ParentGroup header: true new: After: 0 New:
|
|
158
|
-
"edge-france -> core | CONTENT ParentGroup header: true new: After: 0 New:
|
|
157
|
+
"edge-france -> storage | CONTENT ParentGroup header: true new: After: 0 New: 5",
|
|
158
|
+
"edge-france -> core | CONTENT ParentGroup header: true new: After: 0 New: 5",
|
|
159
159
|
"edge-france -> storage | CONTENT Group header: false new: After: 3 New: 2",
|
|
160
160
|
"edge-france -> core | CONTENT Group header: false new: After: 3 New: 2",
|
|
161
161
|
"core -> edge-france | KNOWN Group sessions: header/3",
|
|
162
162
|
"core -> storage | CONTENT Group header: true new: After: 0 New: 3",
|
|
163
|
-
"core -> edge-france | KNOWN ParentGroup sessions: header/
|
|
164
|
-
"core -> storage | CONTENT ParentGroup header: true new: After: 0 New:
|
|
163
|
+
"core -> edge-france | KNOWN ParentGroup sessions: header/5",
|
|
164
|
+
"core -> storage | CONTENT ParentGroup header: true new: After: 0 New: 5",
|
|
165
165
|
"core -> edge-france | KNOWN Group sessions: header/5",
|
|
166
166
|
"core -> storage | CONTENT Group header: false new: After: 3 New: 2",
|
|
167
167
|
"edge-france -> storage | CONTENT Map header: true new: After: 0 New: 1",
|
|
@@ -172,19 +172,19 @@ describe("multiple clients syncing with the a cloud-like server mesh", () => {
|
|
|
172
172
|
"edge-italy -> storage | LOAD Map sessions: empty",
|
|
173
173
|
"storage -> edge-italy | KNOWN Map sessions: empty",
|
|
174
174
|
"edge-italy -> core | LOAD Map sessions: empty",
|
|
175
|
-
"core -> edge-italy | CONTENT ParentGroup header: true new: After: 0 New:
|
|
175
|
+
"core -> edge-italy | CONTENT ParentGroup header: true new: After: 0 New: 5",
|
|
176
176
|
"core -> edge-italy | CONTENT Group header: true new: After: 0 New: 5",
|
|
177
177
|
"core -> edge-italy | CONTENT Map header: true new: After: 0 New: 1",
|
|
178
|
-
"edge-italy -> core | KNOWN ParentGroup sessions: header/
|
|
179
|
-
"edge-italy -> storage | CONTENT ParentGroup header: true new: After: 0 New:
|
|
178
|
+
"edge-italy -> core | KNOWN ParentGroup sessions: header/5",
|
|
179
|
+
"edge-italy -> storage | CONTENT ParentGroup header: true new: After: 0 New: 5",
|
|
180
180
|
"edge-italy -> core | KNOWN Group sessions: header/5",
|
|
181
181
|
"edge-italy -> storage | CONTENT Group header: true new: After: 0 New: 5",
|
|
182
182
|
"edge-italy -> core | KNOWN Map sessions: header/1",
|
|
183
183
|
"edge-italy -> storage | CONTENT Map header: true new: After: 0 New: 1",
|
|
184
|
-
"edge-italy -> client | CONTENT ParentGroup header: true new: After: 0 New:
|
|
184
|
+
"edge-italy -> client | CONTENT ParentGroup header: true new: After: 0 New: 5",
|
|
185
185
|
"edge-italy -> client | CONTENT Group header: true new: After: 0 New: 5",
|
|
186
186
|
"edge-italy -> client | CONTENT Map header: true new: After: 0 New: 1",
|
|
187
|
-
"client -> edge-italy | KNOWN ParentGroup sessions: header/
|
|
187
|
+
"client -> edge-italy | KNOWN ParentGroup sessions: header/5",
|
|
188
188
|
"client -> edge-italy | KNOWN Group sessions: header/5",
|
|
189
189
|
"client -> edge-italy | KNOWN Map sessions: header/1",
|
|
190
190
|
]
|
|
@@ -138,11 +138,11 @@ describe("client with storage syncs with server", () => {
|
|
|
138
138
|
"client -> storage | LOAD Map sessions: empty",
|
|
139
139
|
"storage -> client | KNOWN Map sessions: empty",
|
|
140
140
|
"client -> server | LOAD Map sessions: empty",
|
|
141
|
-
"server -> client | CONTENT ParentGroup header: true new: After: 0 New:
|
|
141
|
+
"server -> client | CONTENT ParentGroup header: true new: After: 0 New: 5",
|
|
142
142
|
"server -> client | CONTENT Group header: true new: After: 0 New: 5",
|
|
143
143
|
"server -> client | CONTENT Map header: true new: After: 0 New: 1",
|
|
144
|
-
"client -> server | KNOWN ParentGroup sessions: header/
|
|
145
|
-
"client -> storage | CONTENT ParentGroup header: true new: After: 0 New:
|
|
144
|
+
"client -> server | KNOWN ParentGroup sessions: header/5",
|
|
145
|
+
"client -> storage | CONTENT ParentGroup header: true new: After: 0 New: 5",
|
|
146
146
|
"client -> server | KNOWN Group sessions: header/5",
|
|
147
147
|
"client -> storage | CONTENT Group header: true new: After: 0 New: 5",
|
|
148
148
|
"client -> server | KNOWN Map sessions: header/1",
|
|
@@ -436,7 +436,7 @@ describe("client syncs with a server with storage", () => {
|
|
|
436
436
|
expect(streamingCounterDuringLoad).toBe(1);
|
|
437
437
|
|
|
438
438
|
const mapOnClient2 = await promise;
|
|
439
|
-
await mapOnClient2.core.
|
|
439
|
+
await mapOnClient2.core.waitForFullStreaming();
|
|
440
440
|
|
|
441
441
|
// Test streaming counter after loading is complete (should be 0)
|
|
442
442
|
await waitFor(async () => {
|
|
@@ -649,8 +649,9 @@ describe("client syncs with a server with storage", () => {
|
|
|
649
649
|
});
|
|
650
650
|
|
|
651
651
|
test("should store values with no transactions", async () => {
|
|
652
|
-
const alice = setupTestNode(
|
|
653
|
-
|
|
652
|
+
const alice = setupTestNode();
|
|
653
|
+
alice.connectToSyncServer({
|
|
654
|
+
ourName: "alice",
|
|
654
655
|
});
|
|
655
656
|
const group = alice.node.createGroup();
|
|
656
657
|
group.addMember("everyone", "writer");
|
|
@@ -666,8 +667,6 @@ describe("client syncs with a server with storage", () => {
|
|
|
666
667
|
ourName: "bob",
|
|
667
668
|
});
|
|
668
669
|
|
|
669
|
-
SyncMessagesLog.clear(); // We want to focus on the sync messages happening from now
|
|
670
|
-
|
|
671
670
|
await loadCoValueOrFail(bob.node, map.id);
|
|
672
671
|
|
|
673
672
|
// The map should be stored in bob's storage
|
|
@@ -684,9 +683,15 @@ describe("client syncs with a server with storage", () => {
|
|
|
684
683
|
}),
|
|
685
684
|
).toMatchInlineSnapshot(`
|
|
686
685
|
[
|
|
686
|
+
"alice -> server | CONTENT Group header: true new: After: 0 New: 5",
|
|
687
|
+
"alice -> server | CONTENT Map header: true new: ",
|
|
687
688
|
"bob -> storage | LOAD Map sessions: empty",
|
|
688
689
|
"storage -> bob | KNOWN Map sessions: empty",
|
|
689
690
|
"bob -> server | LOAD Map sessions: empty",
|
|
691
|
+
"server -> alice | KNOWN Group sessions: header/5",
|
|
692
|
+
"server -> storage | CONTENT Group header: true new: After: 0 New: 5",
|
|
693
|
+
"server -> alice | KNOWN Map sessions: header/0",
|
|
694
|
+
"server -> storage | CONTENT Map header: true new: ",
|
|
690
695
|
"server -> bob | CONTENT Group header: true new: After: 0 New: 5",
|
|
691
696
|
"server -> bob | CONTENT Map header: true new: ",
|
|
692
697
|
"bob -> server | KNOWN Group sessions: header/5",
|
|
@@ -133,11 +133,11 @@ describe("client with storage syncs with server", () => {
|
|
|
133
133
|
"client -> storage | LOAD Map sessions: empty",
|
|
134
134
|
"storage -> client | KNOWN Map sessions: empty",
|
|
135
135
|
"client -> server | LOAD Map sessions: empty",
|
|
136
|
-
"server -> client | CONTENT ParentGroup header: true new: After: 0 New:
|
|
136
|
+
"server -> client | CONTENT ParentGroup header: true new: After: 0 New: 5",
|
|
137
137
|
"server -> client | CONTENT Group header: true new: After: 0 New: 5",
|
|
138
138
|
"server -> client | CONTENT Map header: true new: After: 0 New: 1",
|
|
139
|
-
"client -> server | KNOWN ParentGroup sessions: header/
|
|
140
|
-
"client -> storage | CONTENT ParentGroup header: true new: After: 0 New:
|
|
139
|
+
"client -> server | KNOWN ParentGroup sessions: header/5",
|
|
140
|
+
"client -> storage | CONTENT ParentGroup header: true new: After: 0 New: 5",
|
|
141
141
|
"client -> server | KNOWN Group sessions: header/5",
|
|
142
142
|
"client -> storage | CONTENT Group header: true new: After: 0 New: 5",
|
|
143
143
|
"client -> server | KNOWN Map sessions: header/1",
|
package/src/tests/sync.test.ts
CHANGED
|
@@ -608,13 +608,13 @@ describe("SyncManager - knownStates vs optimisticKnownStates", () => {
|
|
|
608
608
|
|
|
609
609
|
// The optimisticKnownStates should be the same as the knownStates after the full sync is complete
|
|
610
610
|
expect(
|
|
611
|
-
peerStateClient.
|
|
612
|
-
).toEqual(peerStateClient.
|
|
611
|
+
peerStateClient.getOptimisticKnownState(mapOnClient.core.id),
|
|
612
|
+
).toEqual(peerStateClient.getKnownState(mapOnClient.core.id));
|
|
613
613
|
|
|
614
614
|
// On the other node the knownStates should be updated correctly based on the messages we received
|
|
615
615
|
expect(
|
|
616
|
-
peerStateJazzCloud.
|
|
617
|
-
).toEqual(peerStateJazzCloud.
|
|
616
|
+
peerStateJazzCloud.getOptimisticKnownState(mapOnClient.core.id),
|
|
617
|
+
).toEqual(peerStateJazzCloud.getKnownState(mapOnClient.core.id));
|
|
618
618
|
});
|
|
619
619
|
|
|
620
620
|
test("optimisticKnownStates is updated as new transactions are sent, while knownStates only when the updates are acknowledged", async () => {
|
|
@@ -642,8 +642,8 @@ describe("SyncManager - knownStates vs optimisticKnownStates", () => {
|
|
|
642
642
|
|
|
643
643
|
await new Promise<void>(queueMicrotask);
|
|
644
644
|
|
|
645
|
-
expect(peerState.
|
|
646
|
-
peerState.
|
|
645
|
+
expect(peerState.getOptimisticKnownState(map.core.id)).not.toEqual(
|
|
646
|
+
peerState.getKnownState(map.core.id),
|
|
647
647
|
);
|
|
648
648
|
|
|
649
649
|
// Restore the implementation of push and send the blocked messages
|
|
@@ -654,45 +654,13 @@ describe("SyncManager - knownStates vs optimisticKnownStates", () => {
|
|
|
654
654
|
|
|
655
655
|
await map.core.waitForSync();
|
|
656
656
|
|
|
657
|
-
expect(peerState.
|
|
658
|
-
peerState.
|
|
657
|
+
expect(peerState.getOptimisticKnownState(map.core.id)).toEqual(
|
|
658
|
+
peerState.getKnownState(map.core.id),
|
|
659
659
|
);
|
|
660
660
|
});
|
|
661
661
|
});
|
|
662
662
|
|
|
663
663
|
describe("SyncManager.addPeer", () => {
|
|
664
|
-
test("new peer gets a copy of previous peer's knownStates when replacing it", async () => {
|
|
665
|
-
const client = await setupTestAccount();
|
|
666
|
-
|
|
667
|
-
const { peerState: firstPeerState, getCurrentPeerState } =
|
|
668
|
-
client.connectToSyncServer();
|
|
669
|
-
|
|
670
|
-
// Create test data
|
|
671
|
-
const group = client.node.createGroup();
|
|
672
|
-
const map = group.createMap();
|
|
673
|
-
map.set("key1", "value1", "trusting");
|
|
674
|
-
|
|
675
|
-
// Wait for initial sync
|
|
676
|
-
await map.core.waitForSync();
|
|
677
|
-
|
|
678
|
-
// Store the initial known states
|
|
679
|
-
const initialKnownStates = firstPeerState.knownStates;
|
|
680
|
-
|
|
681
|
-
// Create new connection with same ID
|
|
682
|
-
client.connectToSyncServer();
|
|
683
|
-
|
|
684
|
-
// Wait for the new peer to be added
|
|
685
|
-
await waitFor(() => expect(getCurrentPeerState()).not.toBe(firstPeerState));
|
|
686
|
-
|
|
687
|
-
// Verify that the new peer has a copy of the previous known states
|
|
688
|
-
const newPeerKnownStates = getCurrentPeerState().knownStates;
|
|
689
|
-
|
|
690
|
-
expect(newPeerKnownStates).not.toBe(initialKnownStates); // Should be a different instance
|
|
691
|
-
expect(newPeerKnownStates.get(map.core.id)).toEqual(
|
|
692
|
-
initialKnownStates.get(map.core.id),
|
|
693
|
-
);
|
|
694
|
-
});
|
|
695
|
-
|
|
696
664
|
test("new peer with new ID starts with empty knownStates", async () => {
|
|
697
665
|
const client = await setupTestAccount({
|
|
698
666
|
connected: true,
|
|
@@ -716,9 +684,8 @@ describe("SyncManager.addPeer", () => {
|
|
|
716
684
|
client.node.syncManager.addPeer(brandNewPeer);
|
|
717
685
|
|
|
718
686
|
// Verify that the new peer starts with empty known states
|
|
719
|
-
const
|
|
720
|
-
|
|
721
|
-
expect(newPeerKnownStates.get(map.core.id)).toBe(undefined);
|
|
687
|
+
const newPeerState = client.node.syncManager.peers["brandNewPeer"];
|
|
688
|
+
expect(newPeerState?.getKnownState(map.core.id)).toBe(undefined);
|
|
722
689
|
});
|
|
723
690
|
|
|
724
691
|
test("when adding a peer with the same ID as a previous peer, the previous peer is closed", async () => {
|
|
@@ -1071,8 +1038,10 @@ describe("SyncManager.handleSyncMessage", () => {
|
|
|
1071
1038
|
await client.node.syncManager.handleSyncMessage(invalidMessage, peerState);
|
|
1072
1039
|
|
|
1073
1040
|
// Verify that no state changes occurred
|
|
1074
|
-
expect(peerState.
|
|
1075
|
-
expect(peerState.
|
|
1041
|
+
expect(peerState.getKnownState(invalidMessage.id)).toBe(undefined);
|
|
1042
|
+
expect(peerState.getOptimisticKnownState(invalidMessage.id)).toBe(
|
|
1043
|
+
undefined,
|
|
1044
|
+
);
|
|
1076
1045
|
});
|
|
1077
1046
|
|
|
1078
1047
|
test("should ignore messages with invalid ID format", async () => {
|
|
@@ -1091,8 +1060,10 @@ describe("SyncManager.handleSyncMessage", () => {
|
|
|
1091
1060
|
client.node.syncManager.handleSyncMessage(invalidMessage, peerState);
|
|
1092
1061
|
|
|
1093
1062
|
// Verify that no state changes occurred
|
|
1094
|
-
expect(peerState.
|
|
1095
|
-
expect(peerState.
|
|
1063
|
+
expect(peerState.getKnownState(invalidMessage.id)).toBe(undefined);
|
|
1064
|
+
expect(peerState.getOptimisticKnownState(invalidMessage.id)).toBe(
|
|
1065
|
+
undefined,
|
|
1066
|
+
);
|
|
1096
1067
|
});
|
|
1097
1068
|
|
|
1098
1069
|
test("should ignore messages for errored coValues", async () => {
|
|
@@ -1116,8 +1087,8 @@ describe("SyncManager.handleSyncMessage", () => {
|
|
|
1116
1087
|
await client.node.syncManager.handleSyncMessage(message, peerState);
|
|
1117
1088
|
|
|
1118
1089
|
// Verify that no state changes occurred
|
|
1119
|
-
expect(peerState.
|
|
1120
|
-
expect(peerState.
|
|
1090
|
+
expect(peerState.getKnownState(message.id)).toBe(undefined);
|
|
1091
|
+
expect(peerState.getOptimisticKnownState(message.id)).toBe(undefined);
|
|
1121
1092
|
});
|
|
1122
1093
|
|
|
1123
1094
|
test("should process valid messages", async () => {
|
|
@@ -1137,7 +1108,7 @@ describe("SyncManager.handleSyncMessage", () => {
|
|
|
1137
1108
|
await client.node.syncManager.handleSyncMessage(validMessage, peerState);
|
|
1138
1109
|
|
|
1139
1110
|
// Verify that the message was processed
|
|
1140
|
-
expect(peerState.
|
|
1111
|
+
expect(peerState.getKnownState(group.id)).toBeDefined();
|
|
1141
1112
|
});
|
|
1142
1113
|
});
|
|
1143
1114
|
|
|
@@ -164,11 +164,11 @@ describe("client to server upload", () => {
|
|
|
164
164
|
).toMatchInlineSnapshot(`
|
|
165
165
|
[
|
|
166
166
|
"client -> server | CONTENT Group header: true new: After: 0 New: 3",
|
|
167
|
-
"client -> server | CONTENT ParentGroup header: true new: After: 0 New:
|
|
167
|
+
"client -> server | CONTENT ParentGroup header: true new: After: 0 New: 5",
|
|
168
168
|
"client -> server | CONTENT Group header: false new: After: 3 New: 2",
|
|
169
169
|
"client -> server | CONTENT Map header: true new: After: 0 New: 1",
|
|
170
170
|
"server -> client | KNOWN Group sessions: header/3",
|
|
171
|
-
"server -> client | KNOWN ParentGroup sessions: header/
|
|
171
|
+
"server -> client | KNOWN ParentGroup sessions: header/5",
|
|
172
172
|
"server -> client | KNOWN Group sessions: header/5",
|
|
173
173
|
"server -> client | KNOWN Map sessions: header/1",
|
|
174
174
|
]
|
|
@@ -1,19 +0,0 @@
|
|
|
1
|
-
import { RawCoID, SessionID } from "./ids.js";
|
|
2
|
-
import { CoValueKnownState } from "./knownState.js";
|
|
3
|
-
export declare class PeerKnownStates {
|
|
4
|
-
private coValues;
|
|
5
|
-
getKnownState(id: RawCoID): CoValueKnownState;
|
|
6
|
-
updateHeader(id: RawCoID, header: boolean): void;
|
|
7
|
-
combineWith(id: RawCoID, value: CoValueKnownState): void;
|
|
8
|
-
updateSessionCounter(id: RawCoID, sessionId: SessionID, value: number): void;
|
|
9
|
-
set(id: RawCoID, payload: CoValueKnownState | "empty"): void;
|
|
10
|
-
get(id: RawCoID): CoValueKnownState | undefined;
|
|
11
|
-
has(id: RawCoID): boolean;
|
|
12
|
-
clone(): PeerKnownStates;
|
|
13
|
-
listeners: Set<(id: RawCoID, knownState: CoValueKnownState) => void>;
|
|
14
|
-
private triggerUpdate;
|
|
15
|
-
private trigger;
|
|
16
|
-
subscribe(listener: (id: RawCoID, knownState: CoValueKnownState) => void): () => void;
|
|
17
|
-
}
|
|
18
|
-
export type ReadonlyPeerKnownStates = Pick<PeerKnownStates, "get" | "has" | "clone" | "subscribe">;
|
|
19
|
-
//# sourceMappingURL=PeerKnownStates.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"PeerKnownStates.d.ts","sourceRoot":"","sources":["../src/PeerKnownStates.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,SAAS,EAAE,MAAM,UAAU,CAAC;AAC9C,OAAO,EAGL,iBAAiB,EAGlB,MAAM,iBAAiB,CAAC;AAEzB,qBAAa,eAAe;IAC1B,OAAO,CAAC,QAAQ,CAAyC;IAEzD,aAAa,CAAC,EAAE,EAAE,OAAO;IAYzB,YAAY,CAAC,EAAE,EAAE,OAAO,EAAE,MAAM,EAAE,OAAO;IAMzC,WAAW,CAAC,EAAE,EAAE,OAAO,EAAE,KAAK,EAAE,iBAAiB;IAMjD,oBAAoB,CAAC,EAAE,EAAE,OAAO,EAAE,SAAS,EAAE,SAAS,EAAE,KAAK,EAAE,MAAM;IAOrE,GAAG,CAAC,EAAE,EAAE,OAAO,EAAE,OAAO,EAAE,iBAAiB,GAAG,OAAO;IAOrD,GAAG,CAAC,EAAE,EAAE,OAAO;IAIf,GAAG,CAAC,EAAE,EAAE,OAAO;IAIf,KAAK;IAUL,SAAS,WAAgB,OAAO,cAAc,iBAAiB,KAAK,IAAI,EAAI;IAE5E,OAAO,CAAC,aAAa;IAIrB,OAAO,CAAC,OAAO;IAMf,SAAS,CAAC,QAAQ,EAAE,CAAC,EAAE,EAAE,OAAO,EAAE,UAAU,EAAE,iBAAiB,KAAK,IAAI;CAOzE;AAED,MAAM,MAAM,uBAAuB,GAAG,IAAI,CACxC,eAAe,EACf,KAAK,GAAG,KAAK,GAAG,OAAO,GAAG,WAAW,CACtC,CAAC"}
|
package/dist/PeerKnownStates.js
DELETED
|
@@ -1,64 +0,0 @@
|
|
|
1
|
-
import { cloneKnownState, combineKnownStates, emptyKnownState, updateSessionCounter, } from "./knownState.js";
|
|
2
|
-
export class PeerKnownStates {
|
|
3
|
-
constructor() {
|
|
4
|
-
this.coValues = new Map();
|
|
5
|
-
this.listeners = new Set();
|
|
6
|
-
}
|
|
7
|
-
getKnownState(id) {
|
|
8
|
-
const knownState = this.coValues.get(id);
|
|
9
|
-
if (!knownState) {
|
|
10
|
-
const knownState = emptyKnownState(id);
|
|
11
|
-
this.coValues.set(id, knownState);
|
|
12
|
-
return knownState;
|
|
13
|
-
}
|
|
14
|
-
return knownState;
|
|
15
|
-
}
|
|
16
|
-
updateHeader(id, header) {
|
|
17
|
-
const knownState = this.getKnownState(id);
|
|
18
|
-
knownState.header = header;
|
|
19
|
-
this.triggerUpdate(id, knownState);
|
|
20
|
-
}
|
|
21
|
-
combineWith(id, value) {
|
|
22
|
-
const knownState = this.getKnownState(id);
|
|
23
|
-
combineKnownStates(knownState, value);
|
|
24
|
-
this.triggerUpdate(id, knownState);
|
|
25
|
-
}
|
|
26
|
-
updateSessionCounter(id, sessionId, value) {
|
|
27
|
-
const knownState = this.getKnownState(id);
|
|
28
|
-
updateSessionCounter(knownState.sessions, sessionId, value);
|
|
29
|
-
this.triggerUpdate(id, knownState);
|
|
30
|
-
}
|
|
31
|
-
set(id, payload) {
|
|
32
|
-
const knownState = payload === "empty" ? emptyKnownState(id) : cloneKnownState(payload);
|
|
33
|
-
this.coValues.set(id, knownState);
|
|
34
|
-
this.triggerUpdate(id, knownState);
|
|
35
|
-
}
|
|
36
|
-
get(id) {
|
|
37
|
-
return this.coValues.get(id);
|
|
38
|
-
}
|
|
39
|
-
has(id) {
|
|
40
|
-
return this.coValues.has(id);
|
|
41
|
-
}
|
|
42
|
-
clone() {
|
|
43
|
-
const clone = new PeerKnownStates();
|
|
44
|
-
for (const [id, knownState] of this.coValues) {
|
|
45
|
-
clone.coValues.set(id, cloneKnownState(knownState));
|
|
46
|
-
}
|
|
47
|
-
return clone;
|
|
48
|
-
}
|
|
49
|
-
triggerUpdate(id, knownState) {
|
|
50
|
-
this.trigger(id, knownState);
|
|
51
|
-
}
|
|
52
|
-
trigger(id, knownState) {
|
|
53
|
-
for (const listener of this.listeners) {
|
|
54
|
-
listener(id, knownState);
|
|
55
|
-
}
|
|
56
|
-
}
|
|
57
|
-
subscribe(listener) {
|
|
58
|
-
this.listeners.add(listener);
|
|
59
|
-
return () => {
|
|
60
|
-
this.listeners.delete(listener);
|
|
61
|
-
};
|
|
62
|
-
}
|
|
63
|
-
}
|
|
64
|
-
//# sourceMappingURL=PeerKnownStates.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"PeerKnownStates.js","sourceRoot":"","sources":["../src/PeerKnownStates.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"PeerKnownStates.test.d.ts","sourceRoot":"","sources":["../../src/tests/PeerKnownStates.test.ts"],"names":[],"mappings":""}
|
|
@@ -1,77 +0,0 @@
|
|
|
1
|
-
import { describe, expect, test, vi } from "vitest";
|
|
2
|
-
import { PeerKnownStates } from "../PeerKnownStates.js";
|
|
3
|
-
import { emptyKnownState } from "../knownState.js";
|
|
4
|
-
describe("PeerKnownStates", () => {
|
|
5
|
-
test("should set and get a known state", () => {
|
|
6
|
-
const peerKnownStates = new PeerKnownStates();
|
|
7
|
-
const id = "test-id";
|
|
8
|
-
const knownState = emptyKnownState(id);
|
|
9
|
-
peerKnownStates.set(id, knownState);
|
|
10
|
-
expect(peerKnownStates.get(id)).toEqual(knownState);
|
|
11
|
-
expect(peerKnownStates.has(id)).toBe(true);
|
|
12
|
-
});
|
|
13
|
-
test("should update header", () => {
|
|
14
|
-
const peerKnownStates = new PeerKnownStates();
|
|
15
|
-
const id = "test-id";
|
|
16
|
-
peerKnownStates.updateHeader(id, true);
|
|
17
|
-
const result = peerKnownStates.get(id);
|
|
18
|
-
expect(result?.header).toBe(true);
|
|
19
|
-
});
|
|
20
|
-
test("should update session counter", () => {
|
|
21
|
-
const peerKnownStates = new PeerKnownStates();
|
|
22
|
-
const id = "test-id";
|
|
23
|
-
const sessionId = "session-1";
|
|
24
|
-
peerKnownStates.updateSessionCounter(id, sessionId, 5);
|
|
25
|
-
const result = peerKnownStates.get(id);
|
|
26
|
-
expect(result?.sessions[sessionId]).toBe(5);
|
|
27
|
-
});
|
|
28
|
-
test("should combine with existing state", () => {
|
|
29
|
-
const peerKnownStates = new PeerKnownStates();
|
|
30
|
-
const id = "test-id";
|
|
31
|
-
const session1 = "session-1";
|
|
32
|
-
const session2 = "session-2";
|
|
33
|
-
const initialState = {
|
|
34
|
-
...emptyKnownState(id),
|
|
35
|
-
sessions: { [session1]: 5 },
|
|
36
|
-
};
|
|
37
|
-
const combineState = {
|
|
38
|
-
...emptyKnownState(id),
|
|
39
|
-
sessions: { [session2]: 10 },
|
|
40
|
-
};
|
|
41
|
-
peerKnownStates.set(id, initialState);
|
|
42
|
-
peerKnownStates.combineWith(id, combineState);
|
|
43
|
-
const result = peerKnownStates.get(id);
|
|
44
|
-
expect(result?.sessions).toEqual({ [session1]: 5, [session2]: 10 });
|
|
45
|
-
});
|
|
46
|
-
test("should set as empty", () => {
|
|
47
|
-
const peerKnownStates = new PeerKnownStates();
|
|
48
|
-
const id = "test-id";
|
|
49
|
-
const sessionId = "session-1";
|
|
50
|
-
const initialState = {
|
|
51
|
-
...emptyKnownState(id),
|
|
52
|
-
sessions: { [sessionId]: 5 },
|
|
53
|
-
};
|
|
54
|
-
peerKnownStates.set(id, initialState);
|
|
55
|
-
peerKnownStates.set(id, "empty");
|
|
56
|
-
const result = peerKnownStates.get(id);
|
|
57
|
-
expect(result).toEqual(emptyKnownState(id));
|
|
58
|
-
});
|
|
59
|
-
test("should trigger listeners on dispatch", () => {
|
|
60
|
-
const peerKnownStates = new PeerKnownStates();
|
|
61
|
-
const id = "test-id";
|
|
62
|
-
const listener = vi.fn();
|
|
63
|
-
peerKnownStates.subscribe(listener);
|
|
64
|
-
peerKnownStates.set(id, "empty");
|
|
65
|
-
expect(listener).toHaveBeenCalledWith(id, emptyKnownState(id));
|
|
66
|
-
});
|
|
67
|
-
test("should unsubscribe listener", () => {
|
|
68
|
-
const peerKnownStates = new PeerKnownStates();
|
|
69
|
-
const id = "test-id";
|
|
70
|
-
const listener = vi.fn();
|
|
71
|
-
const unsubscribe = peerKnownStates.subscribe(listener);
|
|
72
|
-
unsubscribe();
|
|
73
|
-
peerKnownStates.set(id, "empty");
|
|
74
|
-
expect(listener).not.toHaveBeenCalled();
|
|
75
|
-
});
|
|
76
|
-
});
|
|
77
|
-
//# sourceMappingURL=PeerKnownStates.test.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"PeerKnownStates.test.js","sourceRoot":"","sources":["../../src/tests/PeerKnownStates.test.ts"],"names":[],"mappings":"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"}
|
package/src/PeerKnownStates.ts
DELETED
|
@@ -1,93 +0,0 @@
|
|
|
1
|
-
import { RawCoID, SessionID } from "./ids.js";
|
|
2
|
-
import {
|
|
3
|
-
cloneKnownState,
|
|
4
|
-
combineKnownStates,
|
|
5
|
-
CoValueKnownState,
|
|
6
|
-
emptyKnownState,
|
|
7
|
-
updateSessionCounter,
|
|
8
|
-
} from "./knownState.js";
|
|
9
|
-
|
|
10
|
-
export class PeerKnownStates {
|
|
11
|
-
private coValues = new Map<RawCoID, CoValueKnownState>();
|
|
12
|
-
|
|
13
|
-
getKnownState(id: RawCoID) {
|
|
14
|
-
const knownState = this.coValues.get(id);
|
|
15
|
-
|
|
16
|
-
if (!knownState) {
|
|
17
|
-
const knownState = emptyKnownState(id);
|
|
18
|
-
this.coValues.set(id, knownState);
|
|
19
|
-
return knownState;
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
return knownState;
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
updateHeader(id: RawCoID, header: boolean) {
|
|
26
|
-
const knownState = this.getKnownState(id);
|
|
27
|
-
knownState.header = header;
|
|
28
|
-
this.triggerUpdate(id, knownState);
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
combineWith(id: RawCoID, value: CoValueKnownState) {
|
|
32
|
-
const knownState = this.getKnownState(id);
|
|
33
|
-
combineKnownStates(knownState, value);
|
|
34
|
-
this.triggerUpdate(id, knownState);
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
updateSessionCounter(id: RawCoID, sessionId: SessionID, value: number) {
|
|
38
|
-
const knownState = this.getKnownState(id);
|
|
39
|
-
updateSessionCounter(knownState.sessions, sessionId, value);
|
|
40
|
-
|
|
41
|
-
this.triggerUpdate(id, knownState);
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
set(id: RawCoID, payload: CoValueKnownState | "empty") {
|
|
45
|
-
const knownState =
|
|
46
|
-
payload === "empty" ? emptyKnownState(id) : cloneKnownState(payload);
|
|
47
|
-
this.coValues.set(id, knownState);
|
|
48
|
-
this.triggerUpdate(id, knownState);
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
get(id: RawCoID) {
|
|
52
|
-
return this.coValues.get(id);
|
|
53
|
-
}
|
|
54
|
-
|
|
55
|
-
has(id: RawCoID) {
|
|
56
|
-
return this.coValues.has(id);
|
|
57
|
-
}
|
|
58
|
-
|
|
59
|
-
clone() {
|
|
60
|
-
const clone = new PeerKnownStates();
|
|
61
|
-
|
|
62
|
-
for (const [id, knownState] of this.coValues) {
|
|
63
|
-
clone.coValues.set(id, cloneKnownState(knownState));
|
|
64
|
-
}
|
|
65
|
-
|
|
66
|
-
return clone;
|
|
67
|
-
}
|
|
68
|
-
|
|
69
|
-
listeners = new Set<(id: RawCoID, knownState: CoValueKnownState) => void>();
|
|
70
|
-
|
|
71
|
-
private triggerUpdate(id: RawCoID, knownState: CoValueKnownState) {
|
|
72
|
-
this.trigger(id, knownState);
|
|
73
|
-
}
|
|
74
|
-
|
|
75
|
-
private trigger(id: RawCoID, knownState: CoValueKnownState) {
|
|
76
|
-
for (const listener of this.listeners) {
|
|
77
|
-
listener(id, knownState);
|
|
78
|
-
}
|
|
79
|
-
}
|
|
80
|
-
|
|
81
|
-
subscribe(listener: (id: RawCoID, knownState: CoValueKnownState) => void) {
|
|
82
|
-
this.listeners.add(listener);
|
|
83
|
-
|
|
84
|
-
return () => {
|
|
85
|
-
this.listeners.delete(listener);
|
|
86
|
-
};
|
|
87
|
-
}
|
|
88
|
-
}
|
|
89
|
-
|
|
90
|
-
export type ReadonlyPeerKnownStates = Pick<
|
|
91
|
-
PeerKnownStates,
|
|
92
|
-
"get" | "has" | "clone" | "subscribe"
|
|
93
|
-
>;
|
|
@@ -1,99 +0,0 @@
|
|
|
1
|
-
import { describe, expect, test, vi } from "vitest";
|
|
2
|
-
import { PeerKnownStates } from "../PeerKnownStates.js";
|
|
3
|
-
import { RawCoID, SessionID } from "../ids.js";
|
|
4
|
-
import { CoValueKnownState, emptyKnownState } from "../knownState.js";
|
|
5
|
-
|
|
6
|
-
describe("PeerKnownStates", () => {
|
|
7
|
-
test("should set and get a known state", () => {
|
|
8
|
-
const peerKnownStates = new PeerKnownStates();
|
|
9
|
-
const id = "test-id" as RawCoID;
|
|
10
|
-
const knownState: CoValueKnownState = emptyKnownState(id);
|
|
11
|
-
|
|
12
|
-
peerKnownStates.set(id, knownState);
|
|
13
|
-
|
|
14
|
-
expect(peerKnownStates.get(id)).toEqual(knownState);
|
|
15
|
-
expect(peerKnownStates.has(id)).toBe(true);
|
|
16
|
-
});
|
|
17
|
-
|
|
18
|
-
test("should update header", () => {
|
|
19
|
-
const peerKnownStates = new PeerKnownStates();
|
|
20
|
-
const id = "test-id" as RawCoID;
|
|
21
|
-
|
|
22
|
-
peerKnownStates.updateHeader(id, true);
|
|
23
|
-
|
|
24
|
-
const result = peerKnownStates.get(id);
|
|
25
|
-
expect(result?.header).toBe(true);
|
|
26
|
-
});
|
|
27
|
-
|
|
28
|
-
test("should update session counter", () => {
|
|
29
|
-
const peerKnownStates = new PeerKnownStates();
|
|
30
|
-
const id = "test-id" as RawCoID;
|
|
31
|
-
const sessionId = "session-1" as SessionID;
|
|
32
|
-
|
|
33
|
-
peerKnownStates.updateSessionCounter(id, sessionId, 5);
|
|
34
|
-
|
|
35
|
-
const result = peerKnownStates.get(id);
|
|
36
|
-
expect(result?.sessions[sessionId]).toBe(5);
|
|
37
|
-
});
|
|
38
|
-
|
|
39
|
-
test("should combine with existing state", () => {
|
|
40
|
-
const peerKnownStates = new PeerKnownStates();
|
|
41
|
-
const id = "test-id" as RawCoID;
|
|
42
|
-
const session1 = "session-1" as SessionID;
|
|
43
|
-
const session2 = "session-2" as SessionID;
|
|
44
|
-
const initialState: CoValueKnownState = {
|
|
45
|
-
...emptyKnownState(id),
|
|
46
|
-
sessions: { [session1]: 5 },
|
|
47
|
-
};
|
|
48
|
-
const combineState: CoValueKnownState = {
|
|
49
|
-
...emptyKnownState(id),
|
|
50
|
-
sessions: { [session2]: 10 },
|
|
51
|
-
};
|
|
52
|
-
|
|
53
|
-
peerKnownStates.set(id, initialState);
|
|
54
|
-
peerKnownStates.combineWith(id, combineState);
|
|
55
|
-
|
|
56
|
-
const result = peerKnownStates.get(id);
|
|
57
|
-
expect(result?.sessions).toEqual({ [session1]: 5, [session2]: 10 });
|
|
58
|
-
});
|
|
59
|
-
|
|
60
|
-
test("should set as empty", () => {
|
|
61
|
-
const peerKnownStates = new PeerKnownStates();
|
|
62
|
-
const id = "test-id" as RawCoID;
|
|
63
|
-
const sessionId = "session-1" as SessionID;
|
|
64
|
-
const initialState: CoValueKnownState = {
|
|
65
|
-
...emptyKnownState(id),
|
|
66
|
-
sessions: { [sessionId]: 5 },
|
|
67
|
-
};
|
|
68
|
-
|
|
69
|
-
peerKnownStates.set(id, initialState);
|
|
70
|
-
peerKnownStates.set(id, "empty");
|
|
71
|
-
|
|
72
|
-
const result = peerKnownStates.get(id);
|
|
73
|
-
expect(result).toEqual(emptyKnownState(id));
|
|
74
|
-
});
|
|
75
|
-
|
|
76
|
-
test("should trigger listeners on dispatch", () => {
|
|
77
|
-
const peerKnownStates = new PeerKnownStates();
|
|
78
|
-
const id = "test-id" as RawCoID;
|
|
79
|
-
const listener = vi.fn();
|
|
80
|
-
|
|
81
|
-
peerKnownStates.subscribe(listener);
|
|
82
|
-
peerKnownStates.set(id, "empty");
|
|
83
|
-
|
|
84
|
-
expect(listener).toHaveBeenCalledWith(id, emptyKnownState(id));
|
|
85
|
-
});
|
|
86
|
-
|
|
87
|
-
test("should unsubscribe listener", () => {
|
|
88
|
-
const peerKnownStates = new PeerKnownStates();
|
|
89
|
-
const id = "test-id" as RawCoID;
|
|
90
|
-
const listener = vi.fn();
|
|
91
|
-
|
|
92
|
-
const unsubscribe = peerKnownStates.subscribe(listener);
|
|
93
|
-
unsubscribe();
|
|
94
|
-
|
|
95
|
-
peerKnownStates.set(id, "empty");
|
|
96
|
-
|
|
97
|
-
expect(listener).not.toHaveBeenCalled();
|
|
98
|
-
});
|
|
99
|
-
});
|