cojson 0.19.21 → 0.19.22
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 +13 -0
- package/dist/CojsonMessageChannel/CojsonMessageChannel.d.ts +42 -0
- package/dist/CojsonMessageChannel/CojsonMessageChannel.d.ts.map +1 -0
- package/dist/CojsonMessageChannel/CojsonMessageChannel.js +261 -0
- package/dist/CojsonMessageChannel/CojsonMessageChannel.js.map +1 -0
- package/dist/CojsonMessageChannel/MessagePortOutgoingChannel.d.ts +18 -0
- package/dist/CojsonMessageChannel/MessagePortOutgoingChannel.d.ts.map +1 -0
- package/dist/CojsonMessageChannel/MessagePortOutgoingChannel.js +37 -0
- package/dist/CojsonMessageChannel/MessagePortOutgoingChannel.js.map +1 -0
- package/dist/CojsonMessageChannel/index.d.ts +3 -0
- package/dist/CojsonMessageChannel/index.d.ts.map +1 -0
- package/dist/CojsonMessageChannel/index.js +2 -0
- package/dist/CojsonMessageChannel/index.js.map +1 -0
- package/dist/CojsonMessageChannel/types.d.ts +149 -0
- package/dist/CojsonMessageChannel/types.d.ts.map +1 -0
- package/dist/CojsonMessageChannel/types.js +36 -0
- package/dist/CojsonMessageChannel/types.js.map +1 -0
- package/dist/GarbageCollector.d.ts +4 -2
- package/dist/GarbageCollector.d.ts.map +1 -1
- package/dist/GarbageCollector.js +5 -3
- package/dist/GarbageCollector.js.map +1 -1
- package/dist/SyncStateManager.d.ts +3 -3
- package/dist/SyncStateManager.d.ts.map +1 -1
- package/dist/SyncStateManager.js +4 -4
- package/dist/SyncStateManager.js.map +1 -1
- package/dist/coValueCore/coValueCore.d.ts +19 -1
- package/dist/coValueCore/coValueCore.d.ts.map +1 -1
- package/dist/coValueCore/coValueCore.js +29 -5
- package/dist/coValueCore/coValueCore.js.map +1 -1
- package/dist/exports.d.ts +1 -0
- package/dist/exports.d.ts.map +1 -1
- package/dist/exports.js +1 -0
- package/dist/exports.js.map +1 -1
- package/dist/localNode.d.ts +1 -3
- package/dist/localNode.d.ts.map +1 -1
- package/dist/localNode.js +3 -2
- package/dist/localNode.js.map +1 -1
- package/dist/storage/storageAsync.d.ts +8 -3
- package/dist/storage/storageAsync.d.ts.map +1 -1
- package/dist/storage/storageAsync.js +12 -3
- package/dist/storage/storageAsync.js.map +1 -1
- package/dist/storage/storageSync.d.ts +8 -3
- package/dist/storage/storageSync.d.ts.map +1 -1
- package/dist/storage/storageSync.js +12 -3
- package/dist/storage/storageSync.js.map +1 -1
- package/dist/storage/types.d.ts +5 -0
- package/dist/storage/types.d.ts.map +1 -1
- package/dist/sync.d.ts +6 -0
- package/dist/sync.d.ts.map +1 -1
- package/dist/sync.js +25 -4
- package/dist/sync.js.map +1 -1
- package/dist/tests/CojsonMessageChannel.test.d.ts +2 -0
- package/dist/tests/CojsonMessageChannel.test.d.ts.map +1 -0
- package/dist/tests/CojsonMessageChannel.test.js +236 -0
- package/dist/tests/CojsonMessageChannel.test.js.map +1 -0
- package/dist/tests/GarbageCollector.test.js +87 -13
- package/dist/tests/GarbageCollector.test.js.map +1 -1
- package/dist/tests/StorageApiAsync.test.js +33 -1
- package/dist/tests/StorageApiAsync.test.js.map +1 -1
- package/dist/tests/StorageApiSync.test.js +32 -0
- package/dist/tests/StorageApiSync.test.js.map +1 -1
- package/dist/tests/SyncManager.processQueues.test.js +1 -1
- package/dist/tests/SyncManager.processQueues.test.js.map +1 -1
- package/dist/tests/SyncStateManager.test.js +1 -1
- package/dist/tests/SyncStateManager.test.js.map +1 -1
- package/dist/tests/coPlainText.test.js +1 -1
- package/dist/tests/coPlainText.test.js.map +1 -1
- package/dist/tests/coValueCore.loadFromStorage.test.js +1 -0
- package/dist/tests/coValueCore.loadFromStorage.test.js.map +1 -1
- package/dist/tests/knownState.lazyLoading.test.js +1 -0
- package/dist/tests/knownState.lazyLoading.test.js.map +1 -1
- package/dist/tests/sync.garbageCollection.test.js +56 -32
- package/dist/tests/sync.garbageCollection.test.js.map +1 -1
- package/dist/tests/sync.load.test.js +3 -5
- package/dist/tests/sync.load.test.js.map +1 -1
- package/dist/tests/sync.mesh.test.js +1 -1
- package/dist/tests/sync.mesh.test.js.map +1 -1
- package/dist/tests/sync.peerReconciliation.test.js +3 -3
- package/dist/tests/sync.peerReconciliation.test.js.map +1 -1
- package/dist/tests/sync.storage.test.js +9 -9
- package/dist/tests/sync.storage.test.js.map +1 -1
- package/dist/tests/sync.storageAsync.test.js +7 -7
- package/dist/tests/sync.storageAsync.test.js.map +1 -1
- package/dist/tests/sync.tracking.test.js +35 -4
- package/dist/tests/sync.tracking.test.js.map +1 -1
- package/dist/tests/testStorage.js +2 -2
- package/dist/tests/testStorage.js.map +1 -1
- package/dist/tests/testUtils.d.ts +24 -2
- package/dist/tests/testUtils.d.ts.map +1 -1
- package/dist/tests/testUtils.js +68 -7
- package/dist/tests/testUtils.js.map +1 -1
- package/package.json +4 -4
- package/src/CojsonMessageChannel/CojsonMessageChannel.ts +332 -0
- package/src/CojsonMessageChannel/MessagePortOutgoingChannel.ts +52 -0
- package/src/CojsonMessageChannel/index.ts +9 -0
- package/src/CojsonMessageChannel/types.ts +200 -0
- package/src/GarbageCollector.ts +5 -5
- package/src/SyncStateManager.ts +6 -6
- package/src/coValueCore/coValueCore.ts +30 -7
- package/src/exports.ts +1 -0
- package/src/localNode.ts +3 -5
- package/src/storage/storageAsync.ts +15 -4
- package/src/storage/storageSync.ts +15 -4
- package/src/storage/types.ts +6 -0
- package/src/sync.ts +33 -4
- package/src/tests/CojsonMessageChannel.test.ts +306 -0
- package/src/tests/GarbageCollector.test.ts +114 -13
- package/src/tests/StorageApiAsync.test.ts +50 -1
- package/src/tests/StorageApiSync.test.ts +49 -0
- package/src/tests/SyncManager.processQueues.test.ts +1 -1
- package/src/tests/SyncStateManager.test.ts +1 -1
- package/src/tests/coPlainText.test.ts +1 -1
- package/src/tests/coValueCore.loadFromStorage.test.ts +2 -0
- package/src/tests/knownState.lazyLoading.test.ts +2 -0
- package/src/tests/sync.garbageCollection.test.ts +69 -36
- package/src/tests/sync.load.test.ts +3 -5
- package/src/tests/sync.mesh.test.ts +1 -1
- package/src/tests/sync.peerReconciliation.test.ts +3 -3
- package/src/tests/sync.storage.test.ts +9 -9
- package/src/tests/sync.storageAsync.test.ts +7 -7
- package/src/tests/sync.tracking.test.ts +54 -4
- package/src/tests/testStorage.ts +2 -2
- package/src/tests/testUtils.ts +85 -6
|
@@ -0,0 +1,236 @@
|
|
|
1
|
+
import { describe, test, expect, beforeEach } from "vitest";
|
|
2
|
+
import { CojsonMessageChannel } from "../CojsonMessageChannel";
|
|
3
|
+
import { setupTestNode, SyncMessagesLog, waitFor, createTrackedMessageChannel, createMockWorkerWithAccept, loadCoValueOrFail, } from "./testUtils";
|
|
4
|
+
describe("CojsonMessageChannel", () => {
|
|
5
|
+
beforeEach(() => {
|
|
6
|
+
SyncMessagesLog.clear();
|
|
7
|
+
});
|
|
8
|
+
test("should sync data between two contexts via MessageChannel", async () => {
|
|
9
|
+
// Create two nodes using setupTestNode (handles cleanup automatically)
|
|
10
|
+
const { node: node1 } = setupTestNode();
|
|
11
|
+
const { node: node2 } = setupTestNode();
|
|
12
|
+
const mockWorker = createMockWorkerWithAccept(async (port) => {
|
|
13
|
+
// This runs in the "worker" context
|
|
14
|
+
const peer = await CojsonMessageChannel.acceptFromPort(port, {
|
|
15
|
+
role: "server",
|
|
16
|
+
});
|
|
17
|
+
node2.syncManager.addPeer(peer);
|
|
18
|
+
});
|
|
19
|
+
// Host side: expose to the mock worker
|
|
20
|
+
const peer1 = await CojsonMessageChannel.expose(mockWorker, {
|
|
21
|
+
role: "client",
|
|
22
|
+
messageChannel: createTrackedMessageChannel({
|
|
23
|
+
port1Name: "client",
|
|
24
|
+
port2Name: "server",
|
|
25
|
+
}),
|
|
26
|
+
});
|
|
27
|
+
node1.syncManager.addPeer(peer1);
|
|
28
|
+
// Create data on node1
|
|
29
|
+
const group = node1.createGroup();
|
|
30
|
+
group.addMember("everyone", "writer");
|
|
31
|
+
const map = group.createMap();
|
|
32
|
+
map.set("key", "value", "trusting");
|
|
33
|
+
// Verify data synced
|
|
34
|
+
const mapOnNode2 = await loadCoValueOrFail(node2, map.id);
|
|
35
|
+
expect(mapOnNode2.get("key")).toBe("value");
|
|
36
|
+
expect(SyncMessagesLog.getMessages({
|
|
37
|
+
Map: map.core,
|
|
38
|
+
Group: group.core,
|
|
39
|
+
})).toMatchInlineSnapshot(`
|
|
40
|
+
[
|
|
41
|
+
"server -> client | LOAD Map sessions: empty",
|
|
42
|
+
"client -> server | CONTENT Group header: true new: After: 0 New: 5",
|
|
43
|
+
"client -> server | CONTENT Map header: true new: After: 0 New: 1",
|
|
44
|
+
"server -> client | KNOWN Group sessions: header/5",
|
|
45
|
+
"server -> client | KNOWN Map sessions: header/1",
|
|
46
|
+
]
|
|
47
|
+
`);
|
|
48
|
+
});
|
|
49
|
+
test("should handle disconnection correctly", async () => {
|
|
50
|
+
const { node: node1 } = setupTestNode();
|
|
51
|
+
const { node: node2 } = setupTestNode();
|
|
52
|
+
const peerId = "disconnect-test-peer";
|
|
53
|
+
let peer2 = null;
|
|
54
|
+
const mockWorker = createMockWorkerWithAccept(async (port) => {
|
|
55
|
+
peer2 = await CojsonMessageChannel.acceptFromPort(port, {
|
|
56
|
+
id: peerId,
|
|
57
|
+
role: "server",
|
|
58
|
+
});
|
|
59
|
+
node2.syncManager.addPeer(peer2);
|
|
60
|
+
});
|
|
61
|
+
const peer1 = await CojsonMessageChannel.expose(mockWorker, {
|
|
62
|
+
id: peerId,
|
|
63
|
+
role: "client",
|
|
64
|
+
});
|
|
65
|
+
node1.syncManager.addPeer(peer1);
|
|
66
|
+
// Verify peers are connected (same ID on both sides)
|
|
67
|
+
expect(node1.syncManager.peers["disconnect-test-peer"]).toBeDefined();
|
|
68
|
+
expect(node2.syncManager.peers["disconnect-test-peer"]).toBeDefined();
|
|
69
|
+
peer1.outgoing.close();
|
|
70
|
+
expect(node1.syncManager.peers["disconnect-test-peer"]).toBeUndefined();
|
|
71
|
+
await waitFor(() => {
|
|
72
|
+
expect(node2.syncManager.peers["disconnect-test-peer"]).toBeUndefined();
|
|
73
|
+
});
|
|
74
|
+
});
|
|
75
|
+
test("should ignore mismatched peer IDs in waitForConnection() when id filter is provided", async () => {
|
|
76
|
+
const { node } = setupTestNode();
|
|
77
|
+
const hostPeerId = "host-peer-id";
|
|
78
|
+
const wrongPeerId = "wrong-peer-id";
|
|
79
|
+
let acceptPromiseResolved = false;
|
|
80
|
+
// Mock worker that expects a different ID
|
|
81
|
+
const mockWorker = createMockWorkerWithAccept(async (port) => {
|
|
82
|
+
// This should not resolve because the ID doesn't match
|
|
83
|
+
const acceptPromise = CojsonMessageChannel.acceptFromPort(port, {
|
|
84
|
+
id: wrongPeerId, // Expecting a different ID
|
|
85
|
+
role: "server",
|
|
86
|
+
});
|
|
87
|
+
// Set a timeout to detect if it's waiting
|
|
88
|
+
const timeoutPromise = new Promise((resolve) => setTimeout(() => resolve(null), 100));
|
|
89
|
+
const result = await Promise.race([acceptPromise, timeoutPromise]);
|
|
90
|
+
if (result !== null) {
|
|
91
|
+
acceptPromiseResolved = true;
|
|
92
|
+
node.syncManager.addPeer(result);
|
|
93
|
+
}
|
|
94
|
+
});
|
|
95
|
+
// Expose with a different ID than what accept expects
|
|
96
|
+
CojsonMessageChannel.expose(mockWorker, {
|
|
97
|
+
id: hostPeerId,
|
|
98
|
+
role: "client",
|
|
99
|
+
});
|
|
100
|
+
// Wait a bit to ensure the accept didn't resolve
|
|
101
|
+
await new Promise((resolve) => setTimeout(resolve, 150));
|
|
102
|
+
// The accept should not have resolved because IDs don't match
|
|
103
|
+
expect(acceptPromiseResolved).toBe(false);
|
|
104
|
+
});
|
|
105
|
+
test("should sync data bidirectionally", async () => {
|
|
106
|
+
const { node: node1 } = setupTestNode();
|
|
107
|
+
const { node: node2 } = setupTestNode();
|
|
108
|
+
const mockWorker = createMockWorkerWithAccept(async (port) => {
|
|
109
|
+
const peer = await CojsonMessageChannel.acceptFromPort(port, {
|
|
110
|
+
role: "server",
|
|
111
|
+
});
|
|
112
|
+
node2.syncManager.addPeer(peer);
|
|
113
|
+
});
|
|
114
|
+
const peer1 = await CojsonMessageChannel.expose(mockWorker, {
|
|
115
|
+
role: "client",
|
|
116
|
+
});
|
|
117
|
+
node1.syncManager.addPeer(peer1);
|
|
118
|
+
// Create data on node1
|
|
119
|
+
const group1 = node1.createGroup();
|
|
120
|
+
group1.addMember("everyone", "writer");
|
|
121
|
+
const map1 = group1.createMap();
|
|
122
|
+
map1.set("from", "node1", "trusting");
|
|
123
|
+
// Create data on node2
|
|
124
|
+
const group2 = node2.createGroup();
|
|
125
|
+
group2.addMember("everyone", "writer");
|
|
126
|
+
const map2 = group2.createMap();
|
|
127
|
+
map2.set("from", "node2", "trusting");
|
|
128
|
+
// Verify data synced in both directions
|
|
129
|
+
const map1OnNode2 = await loadCoValueOrFail(node2, map1.id);
|
|
130
|
+
expect(map1OnNode2.get("from")).toBe("node1");
|
|
131
|
+
const map2OnNode1 = await loadCoValueOrFail(node1, map2.id);
|
|
132
|
+
expect(map2OnNode1.get("from")).toBe("node2");
|
|
133
|
+
});
|
|
134
|
+
test("should invoke onClose callback when connection closes", async () => {
|
|
135
|
+
const { node: node1 } = setupTestNode();
|
|
136
|
+
const { node: node2 } = setupTestNode();
|
|
137
|
+
let onCloseCalledOnHost = false;
|
|
138
|
+
let onCloseCalledOnWorker = false;
|
|
139
|
+
const mockWorker = createMockWorkerWithAccept(async (port) => {
|
|
140
|
+
const peer = await CojsonMessageChannel.acceptFromPort(port, {
|
|
141
|
+
role: "server",
|
|
142
|
+
onClose: () => {
|
|
143
|
+
onCloseCalledOnWorker = true;
|
|
144
|
+
},
|
|
145
|
+
});
|
|
146
|
+
node2.syncManager.addPeer(peer);
|
|
147
|
+
});
|
|
148
|
+
const peer1 = await CojsonMessageChannel.expose(mockWorker, {
|
|
149
|
+
role: "client",
|
|
150
|
+
onClose: () => {
|
|
151
|
+
onCloseCalledOnHost = true;
|
|
152
|
+
},
|
|
153
|
+
});
|
|
154
|
+
node1.syncManager.addPeer(peer1);
|
|
155
|
+
// Close the connection
|
|
156
|
+
peer1.outgoing.close();
|
|
157
|
+
// Wait for close to propagate
|
|
158
|
+
await waitFor(() => {
|
|
159
|
+
expect(onCloseCalledOnHost).toBe(true);
|
|
160
|
+
});
|
|
161
|
+
await waitFor(() => {
|
|
162
|
+
expect(onCloseCalledOnWorker).toBe(true);
|
|
163
|
+
});
|
|
164
|
+
});
|
|
165
|
+
test("should apply role configuration correctly", async () => {
|
|
166
|
+
const { node: node1 } = setupTestNode();
|
|
167
|
+
const { node: node2 } = setupTestNode();
|
|
168
|
+
let peer2 = null;
|
|
169
|
+
const mockWorker = createMockWorkerWithAccept(async (port) => {
|
|
170
|
+
peer2 = await CojsonMessageChannel.acceptFromPort(port, {
|
|
171
|
+
role: "server",
|
|
172
|
+
});
|
|
173
|
+
node2.syncManager.addPeer(peer2);
|
|
174
|
+
});
|
|
175
|
+
const peer1 = await CojsonMessageChannel.expose(mockWorker, {
|
|
176
|
+
role: "client",
|
|
177
|
+
});
|
|
178
|
+
node1.syncManager.addPeer(peer1);
|
|
179
|
+
// Verify roles are correctly set
|
|
180
|
+
expect(peer1.role).toBe("client");
|
|
181
|
+
expect(peer2).not.toBeNull();
|
|
182
|
+
expect(peer2.role).toBe("server");
|
|
183
|
+
});
|
|
184
|
+
test("should generate and use the same peer ID on both sides when not provided", async () => {
|
|
185
|
+
const { node: node1 } = setupTestNode();
|
|
186
|
+
const { node: node2 } = setupTestNode();
|
|
187
|
+
let peer2 = null;
|
|
188
|
+
const mockWorker = createMockWorkerWithAccept(async (port) => {
|
|
189
|
+
peer2 = await CojsonMessageChannel.acceptFromPort(port, {
|
|
190
|
+
role: "server",
|
|
191
|
+
});
|
|
192
|
+
node2.syncManager.addPeer(peer2);
|
|
193
|
+
});
|
|
194
|
+
// Don't provide an id - it should be auto-generated
|
|
195
|
+
const peer1 = await CojsonMessageChannel.expose(mockWorker, {
|
|
196
|
+
role: "client",
|
|
197
|
+
});
|
|
198
|
+
node1.syncManager.addPeer(peer1);
|
|
199
|
+
// Verify peer1 has an auto-generated ID
|
|
200
|
+
expect(peer1.id).toMatch(/^channel_/);
|
|
201
|
+
// Verify both peers have the same ID
|
|
202
|
+
expect(peer2).not.toBeNull();
|
|
203
|
+
expect(peer2.id).toBe(peer1.id);
|
|
204
|
+
// Verify the peer is accessible in both sync managers with the same ID
|
|
205
|
+
expect(node1.syncManager.peers[peer1.id]).toBeDefined();
|
|
206
|
+
expect(node2.syncManager.peers[peer1.id]).toBeDefined();
|
|
207
|
+
});
|
|
208
|
+
test("should handle delayed addPeer on accept side", async () => {
|
|
209
|
+
const { node: node1 } = setupTestNode();
|
|
210
|
+
const { node: node2 } = setupTestNode();
|
|
211
|
+
let peer2 = null;
|
|
212
|
+
const delay = new Promise((resolve) => setTimeout(resolve, 50));
|
|
213
|
+
const mockWorker = createMockWorkerWithAccept(async (port) => {
|
|
214
|
+
peer2 = await CojsonMessageChannel.acceptFromPort(port, {
|
|
215
|
+
role: "server",
|
|
216
|
+
});
|
|
217
|
+
// Deliberately delay adding the peer
|
|
218
|
+
await delay;
|
|
219
|
+
node2.syncManager.addPeer(peer2);
|
|
220
|
+
});
|
|
221
|
+
const peer1 = await CojsonMessageChannel.expose(mockWorker, {
|
|
222
|
+
role: "client",
|
|
223
|
+
});
|
|
224
|
+
node1.syncManager.addPeer(peer1);
|
|
225
|
+
// Create data on node1 immediately (before node2 has added the peer)
|
|
226
|
+
const group = node1.createGroup();
|
|
227
|
+
group.addMember("everyone", "writer");
|
|
228
|
+
const map = group.createMap();
|
|
229
|
+
map.set("key", "value", "trusting");
|
|
230
|
+
await delay;
|
|
231
|
+
// Verify data synced despite the delay
|
|
232
|
+
const mapOnNode2 = await loadCoValueOrFail(node2, map.id);
|
|
233
|
+
expect(mapOnNode2.get("key")).toBe("value");
|
|
234
|
+
});
|
|
235
|
+
});
|
|
236
|
+
//# sourceMappingURL=CojsonMessageChannel.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"CojsonMessageChannel.test.js","sourceRoot":"","sources":["../../src/tests/CojsonMessageChannel.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,12 +1,14 @@
|
|
|
1
1
|
import { assert, beforeEach, describe, expect, test, vi } from "vitest";
|
|
2
2
|
import { setGarbageCollectorMaxAge } from "../config";
|
|
3
|
-
import { TEST_NODE_CONFIG, setupTestAccount, setupTestNode } from "./testUtils";
|
|
3
|
+
import { blockMessageTypeOnOutgoingPeer, TEST_NODE_CONFIG, setupTestAccount, setupTestNode, } from "./testUtils";
|
|
4
|
+
import { createSyncStorage } from "./testStorage.js";
|
|
4
5
|
// We want to simulate a real world communication that happens asynchronously
|
|
5
6
|
TEST_NODE_CONFIG.withAsyncPeers = true;
|
|
6
7
|
beforeEach(() => {
|
|
7
8
|
// We want to test what happens when the garbage collector kicks in and removes a coValue
|
|
8
9
|
// We set the max age to -1 to make it remove everything
|
|
9
10
|
setGarbageCollectorMaxAge(-1);
|
|
11
|
+
setupTestNode({ isSyncServer: true });
|
|
10
12
|
});
|
|
11
13
|
describe("garbage collector", () => {
|
|
12
14
|
test("coValues are garbage collected when maxAge is reached", async () => {
|
|
@@ -14,11 +16,12 @@ describe("garbage collector", () => {
|
|
|
14
16
|
client.addStorage({
|
|
15
17
|
ourName: "client",
|
|
16
18
|
});
|
|
19
|
+
client.connectToSyncServer();
|
|
17
20
|
client.node.enableGarbageCollector();
|
|
18
21
|
const group = client.node.createGroup();
|
|
19
22
|
const map = group.createMap();
|
|
20
23
|
map.set("hello", "world", "trusting");
|
|
21
|
-
await
|
|
24
|
+
await client.node.syncManager.waitForAllCoValuesSync();
|
|
22
25
|
client.node.garbageCollector?.collect();
|
|
23
26
|
const coValue = client.node.getCoValue(map.id);
|
|
24
27
|
expect(coValue.isAvailable()).toBe(false);
|
|
@@ -28,6 +31,7 @@ describe("garbage collector", () => {
|
|
|
28
31
|
client.addStorage({
|
|
29
32
|
ourName: "client",
|
|
30
33
|
});
|
|
34
|
+
client.connectToSyncServer();
|
|
31
35
|
client.node.enableGarbageCollector();
|
|
32
36
|
const group = client.node.createGroup();
|
|
33
37
|
const map = group.createMap();
|
|
@@ -36,7 +40,7 @@ describe("garbage collector", () => {
|
|
|
36
40
|
const unsubscribe = map.subscribe(() => {
|
|
37
41
|
// This listener keeps the coValue alive
|
|
38
42
|
});
|
|
39
|
-
await
|
|
43
|
+
await client.node.syncManager.waitForAllCoValuesSync();
|
|
40
44
|
client.node.garbageCollector?.collect();
|
|
41
45
|
expect(client.node.getCoValue(map.id).isAvailable()).toBe(true);
|
|
42
46
|
// Clean up the listener
|
|
@@ -45,31 +49,100 @@ describe("garbage collector", () => {
|
|
|
45
49
|
client.node.garbageCollector?.collect();
|
|
46
50
|
expect(client.node.getCoValue(map.id).isAvailable()).toBe(false);
|
|
47
51
|
});
|
|
48
|
-
test("coValues are not garbage collected if they are
|
|
49
|
-
const client =
|
|
52
|
+
test("coValues are not garbage collected if they are not synced with server peers", async () => {
|
|
53
|
+
const client = setupTestNode();
|
|
50
54
|
client.addStorage({
|
|
51
55
|
ourName: "client",
|
|
52
56
|
});
|
|
53
|
-
client.node.enableGarbageCollector(
|
|
54
|
-
|
|
55
|
-
|
|
57
|
+
client.node.enableGarbageCollector();
|
|
58
|
+
const { peer: serverPeer } = client.connectToSyncServer();
|
|
59
|
+
// Block sync with server
|
|
60
|
+
const blocker = blockMessageTypeOnOutgoingPeer(serverPeer, "content", {});
|
|
56
61
|
const group = client.node.createGroup();
|
|
62
|
+
const map = group.createMap();
|
|
63
|
+
map.set("hello", "world", "trusting");
|
|
57
64
|
await new Promise((resolve) => setTimeout(resolve, 10));
|
|
58
65
|
client.node.garbageCollector?.collect();
|
|
59
|
-
expect(client.node.getCoValue(
|
|
66
|
+
expect(client.node.getCoValue(map.id).isAvailable()).toBe(true);
|
|
67
|
+
// Resume sync with server
|
|
68
|
+
blocker.sendBlockedMessages();
|
|
69
|
+
blocker.unblock();
|
|
70
|
+
await client.node.syncManager.waitForAllCoValuesSync();
|
|
71
|
+
// The coValue should now be collected
|
|
72
|
+
client.node.garbageCollector?.collect();
|
|
73
|
+
expect(client.node.getCoValue(map.id).isAvailable()).toBe(false);
|
|
74
|
+
});
|
|
75
|
+
test("coValues are garbage collected if there are no server peers", async () => {
|
|
76
|
+
const client = setupTestNode();
|
|
77
|
+
client.addStorage({
|
|
78
|
+
ourName: "client",
|
|
79
|
+
});
|
|
80
|
+
client.node.enableGarbageCollector();
|
|
81
|
+
// Client is not connected to the sync server
|
|
82
|
+
const group = client.node.createGroup();
|
|
83
|
+
const map = group.createMap();
|
|
84
|
+
map.set("hello", "world", "trusting");
|
|
85
|
+
await client.node.syncManager.waitForAllCoValuesSync();
|
|
86
|
+
client.node.garbageCollector?.collect();
|
|
87
|
+
expect(client.node.getCoValue(map.id).isAvailable()).toBe(false);
|
|
88
|
+
});
|
|
89
|
+
test("account coValues are not garbage collected if they have dependencies", async () => {
|
|
90
|
+
const client = await setupTestAccount({
|
|
91
|
+
// Add storage before creating the account so it's persisted
|
|
92
|
+
storage: createSyncStorage({
|
|
93
|
+
nodeName: "client",
|
|
94
|
+
storageName: "storage",
|
|
95
|
+
}),
|
|
96
|
+
});
|
|
97
|
+
// The account is created along with its profile, and the group that owns the profile
|
|
98
|
+
const profile = client.node.expectProfileLoaded(client.accountID);
|
|
99
|
+
const profileId = profile.id;
|
|
100
|
+
const profileOwnerId = profile.group.id;
|
|
101
|
+
client.connectToSyncServer();
|
|
102
|
+
client.node.enableGarbageCollector();
|
|
103
|
+
await client.node.syncManager.waitForAllCoValuesSync();
|
|
104
|
+
// First collect removes the profile
|
|
105
|
+
client.node.garbageCollector?.collect();
|
|
106
|
+
expect(client.node.getCoValue(profileId).isAvailable()).toBe(false);
|
|
107
|
+
expect(client.node.getCoValue(profileOwnerId).isAvailable()).toBe(true);
|
|
108
|
+
expect(client.node.getCoValue(client.accountID).isAvailable()).toBe(true);
|
|
109
|
+
// Second collect removes the profile owner
|
|
110
|
+
client.node.garbageCollector?.collect();
|
|
111
|
+
expect(client.node.getCoValue(profileOwnerId).isAvailable()).toBe(false);
|
|
112
|
+
expect(client.node.getCoValue(client.accountID).isAvailable()).toBe(true);
|
|
113
|
+
// Third collect removes the account
|
|
114
|
+
client.node.garbageCollector?.collect();
|
|
60
115
|
expect(client.node.getCoValue(client.accountID).isAvailable()).toBe(false);
|
|
61
116
|
});
|
|
62
|
-
test("group
|
|
63
|
-
const client =
|
|
117
|
+
test("group coValues are garbage collected if they have no dependencies", async () => {
|
|
118
|
+
const client = setupTestNode();
|
|
64
119
|
client.addStorage({
|
|
65
120
|
ourName: "client",
|
|
66
121
|
});
|
|
122
|
+
client.connectToSyncServer();
|
|
67
123
|
client.node.enableGarbageCollector();
|
|
68
124
|
const group = client.node.createGroup();
|
|
69
|
-
await
|
|
125
|
+
await client.node.syncManager.waitForAllCoValuesSync();
|
|
126
|
+
client.node.garbageCollector?.collect();
|
|
127
|
+
expect(client.node.getCoValue(group.id).isAvailable()).toBe(false);
|
|
128
|
+
});
|
|
129
|
+
test("group coValues are not garbage collected if they have dependencies", async () => {
|
|
130
|
+
const client = setupTestNode();
|
|
131
|
+
client.addStorage({
|
|
132
|
+
ourName: "client",
|
|
133
|
+
});
|
|
134
|
+
client.node.enableGarbageCollector();
|
|
135
|
+
const group = client.node.createGroup();
|
|
136
|
+
const map = group.createMap();
|
|
137
|
+
map.set("hello", "world", "trusting");
|
|
138
|
+
await client.node.syncManager.waitForAllCoValuesSync();
|
|
139
|
+
// First collect removes the map
|
|
70
140
|
client.node.garbageCollector?.collect();
|
|
71
141
|
expect(client.node.getCoValue(group.id).isAvailable()).toBe(true);
|
|
72
|
-
expect(client.node.getCoValue(
|
|
142
|
+
expect(client.node.getCoValue(map.id).isAvailable()).toBe(false);
|
|
143
|
+
// Second collect removes the group
|
|
144
|
+
client.node.garbageCollector?.collect();
|
|
145
|
+
expect(client.node.getCoValue(group.id).isAvailable()).toBe(false);
|
|
73
146
|
});
|
|
74
147
|
test("coValues are not garbage collected if the maxAge is not reached", async () => {
|
|
75
148
|
setGarbageCollectorMaxAge(1000);
|
|
@@ -77,6 +150,7 @@ describe("garbage collector", () => {
|
|
|
77
150
|
client.addStorage({
|
|
78
151
|
ourName: "client",
|
|
79
152
|
});
|
|
153
|
+
client.connectToSyncServer();
|
|
80
154
|
client.node.enableGarbageCollector();
|
|
81
155
|
const garbageCollector = client.node.garbageCollector;
|
|
82
156
|
assert(garbageCollector);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"GarbageCollector.test.js","sourceRoot":"","sources":["../../src/tests/GarbageCollector.test.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,UAAU,EAAE,QAAQ,EAAE,MAAM,EAAE,IAAI,EAAE,EAAE,EAAE,MAAM,QAAQ,CAAC;AAExE,OAAO,EAAE,yBAAyB,EAAE,MAAM,WAAW,CAAC;AACtD,OAAO,
|
|
1
|
+
{"version":3,"file":"GarbageCollector.test.js","sourceRoot":"","sources":["../../src/tests/GarbageCollector.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -58,7 +58,7 @@ async function createTestNode(dbPath) {
|
|
|
58
58
|
storageName: "test-storage",
|
|
59
59
|
});
|
|
60
60
|
onTestFinished(async () => {
|
|
61
|
-
node.gracefulShutdown();
|
|
61
|
+
await node.gracefulShutdown();
|
|
62
62
|
await storage.close();
|
|
63
63
|
});
|
|
64
64
|
return {
|
|
@@ -543,6 +543,38 @@ describe("StorageApiAsync", () => {
|
|
|
543
543
|
const mapOnNode = await loadCoValueOrFail(node, map.id);
|
|
544
544
|
expect(mapOnNode.get("test")).toEqual("value");
|
|
545
545
|
});
|
|
546
|
+
test("should load dependencies again if they were unmounted", async () => {
|
|
547
|
+
const { fixturesNode, dbPath } = await createFixturesNode();
|
|
548
|
+
const { node, storage } = await createTestNode(dbPath);
|
|
549
|
+
// Create a group and a map owned by that group
|
|
550
|
+
const group = fixturesNode.createGroup();
|
|
551
|
+
group.addMember("everyone", "reader");
|
|
552
|
+
const map = group.createMap({ test: "value" });
|
|
553
|
+
await group.core.waitForSync();
|
|
554
|
+
await map.core.waitForSync();
|
|
555
|
+
const callback = vi.fn((content) => node.syncManager.handleNewContent(content, "storage"));
|
|
556
|
+
const done = vi.fn();
|
|
557
|
+
// Load the map (and its group)
|
|
558
|
+
await storage.load(map.id, callback, done);
|
|
559
|
+
callback.mockClear();
|
|
560
|
+
done.mockClear();
|
|
561
|
+
// Unmount the map and its group
|
|
562
|
+
storage.onCoValueUnmounted(map.id);
|
|
563
|
+
storage.onCoValueUnmounted(group.id);
|
|
564
|
+
// Load the map. The group dependency should be loaded again
|
|
565
|
+
await storage.load(map.id, callback, done);
|
|
566
|
+
expect(callback).toHaveBeenCalledTimes(2);
|
|
567
|
+
expect(callback).toHaveBeenNthCalledWith(1, expect.objectContaining({
|
|
568
|
+
id: group.id,
|
|
569
|
+
}));
|
|
570
|
+
expect(callback).toHaveBeenNthCalledWith(2, expect.objectContaining({
|
|
571
|
+
id: map.id,
|
|
572
|
+
}));
|
|
573
|
+
expect(done).toHaveBeenCalledWith(true);
|
|
574
|
+
node.setStorage(storage);
|
|
575
|
+
const mapOnNode = await loadCoValueOrFail(node, map.id);
|
|
576
|
+
expect(mapOnNode.get("test")).toEqual("value");
|
|
577
|
+
});
|
|
546
578
|
});
|
|
547
579
|
describe("waitForSync", () => {
|
|
548
580
|
test("should resolve when the coValue is already synced", async () => {
|