cojson 0.17.11 → 0.17.13
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 +17 -0
- package/dist/coValueCore/SessionMap.d.ts +4 -3
- package/dist/coValueCore/SessionMap.d.ts.map +1 -1
- package/dist/coValueCore/SessionMap.js +15 -4
- package/dist/coValueCore/SessionMap.js.map +1 -1
- package/dist/coValueCore/coValueCore.d.ts +2 -2
- package/dist/coValueCore/coValueCore.d.ts.map +1 -1
- package/dist/coValueCore/coValueCore.js +33 -32
- package/dist/coValueCore/coValueCore.js.map +1 -1
- package/dist/coValueCore/utils.d.ts.map +1 -1
- package/dist/coValueCore/utils.js.map +1 -1
- package/dist/coValueCore/verifiedState.d.ts +8 -2
- package/dist/coValueCore/verifiedState.d.ts.map +1 -1
- package/dist/coValueCore/verifiedState.js +7 -4
- package/dist/coValueCore/verifiedState.js.map +1 -1
- package/dist/crypto/PureJSCrypto.d.ts +4 -3
- package/dist/crypto/PureJSCrypto.d.ts.map +1 -1
- package/dist/crypto/PureJSCrypto.js +34 -2
- package/dist/crypto/PureJSCrypto.js.map +1 -1
- package/dist/crypto/WasmCrypto.d.ts +4 -3
- package/dist/crypto/WasmCrypto.d.ts.map +1 -1
- package/dist/crypto/WasmCrypto.js +10 -4
- package/dist/crypto/WasmCrypto.js.map +1 -1
- package/dist/crypto/crypto.d.ts +4 -3
- package/dist/crypto/crypto.d.ts.map +1 -1
- package/dist/localNode.js +1 -1
- package/dist/localNode.js.map +1 -1
- package/dist/queue/LocalTransactionsSyncQueue.d.ts +15 -0
- package/dist/queue/LocalTransactionsSyncQueue.d.ts.map +1 -1
- package/dist/queue/LocalTransactionsSyncQueue.js +25 -0
- package/dist/queue/LocalTransactionsSyncQueue.js.map +1 -1
- package/dist/sync.d.ts +10 -7
- package/dist/sync.d.ts.map +1 -1
- package/dist/sync.js +33 -31
- package/dist/sync.js.map +1 -1
- package/dist/tests/PureJSCrypto.test.js +43 -0
- package/dist/tests/PureJSCrypto.test.js.map +1 -1
- package/dist/tests/WasmCrypto.test.js +55 -0
- package/dist/tests/WasmCrypto.test.js.map +1 -1
- package/dist/tests/coList.test.js +13 -0
- package/dist/tests/coList.test.js.map +1 -1
- package/dist/tests/coMap.test.js +14 -0
- package/dist/tests/coMap.test.js.map +1 -1
- package/dist/tests/coPlainText.test.js +13 -0
- package/dist/tests/coPlainText.test.js.map +1 -1
- package/dist/tests/coStream.test.js +25 -0
- package/dist/tests/coStream.test.js.map +1 -1
- package/dist/tests/coValueCore.test.js +28 -2
- package/dist/tests/coValueCore.test.js.map +1 -1
- package/dist/tests/coreWasm.test.js +1 -1
- package/dist/tests/coreWasm.test.js.map +1 -1
- package/dist/tests/sync.known.test.d.ts +2 -0
- package/dist/tests/sync.known.test.d.ts.map +1 -0
- package/dist/tests/sync.known.test.js +78 -0
- package/dist/tests/sync.known.test.js.map +1 -0
- package/dist/tests/sync.sharding.test.d.ts +2 -0
- package/dist/tests/sync.sharding.test.d.ts.map +1 -0
- package/dist/tests/sync.sharding.test.js +85 -0
- package/dist/tests/sync.sharding.test.js.map +1 -0
- package/dist/tests/sync.storage.test.js +31 -1
- package/dist/tests/sync.storage.test.js.map +1 -1
- package/dist/tests/sync.storageAsync.test.js +1 -1
- package/dist/tests/sync.storageAsync.test.js.map +1 -1
- package/dist/tests/sync.test.js +31 -2
- package/dist/tests/sync.test.js.map +1 -1
- package/dist/tests/sync.upload.test.js +26 -0
- package/dist/tests/sync.upload.test.js.map +1 -1
- package/dist/tests/testUtils.d.ts.map +1 -1
- package/dist/tests/testUtils.js +3 -1
- package/dist/tests/testUtils.js.map +1 -1
- package/package.json +2 -2
- package/src/coValueCore/SessionMap.ts +24 -1
- package/src/coValueCore/coValueCore.ts +46 -41
- package/src/coValueCore/utils.ts +0 -1
- package/src/coValueCore/verifiedState.ts +14 -3
- package/src/crypto/PureJSCrypto.ts +49 -1
- package/src/crypto/WasmCrypto.ts +15 -1
- package/src/crypto/crypto.ts +7 -1
- package/src/localNode.ts +1 -1
- package/src/queue/LocalTransactionsSyncQueue.ts +32 -1
- package/src/sync.ts +50 -36
- package/src/tests/PureJSCrypto.test.ts +66 -0
- package/src/tests/WasmCrypto.test.ts +88 -0
- package/src/tests/coList.test.ts +19 -0
- package/src/tests/coMap.test.ts +21 -0
- package/src/tests/coPlainText.test.ts +18 -0
- package/src/tests/coStream.test.ts +36 -0
- package/src/tests/coValueCore.test.ts +49 -0
- package/src/tests/coreWasm.test.ts +1 -0
- package/src/tests/sync.known.test.ts +109 -0
- package/src/tests/sync.sharding.test.ts +119 -0
- package/src/tests/sync.storage.test.ts +43 -1
- package/src/tests/sync.storageAsync.test.ts +1 -1
- package/src/tests/sync.test.ts +49 -2
- package/src/tests/sync.upload.test.ts +35 -0
- package/src/tests/testUtils.ts +3 -1
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
import { beforeEach, describe, expect, test } from "vitest";
|
|
2
|
+
import { setCoValueLoadingRetryDelay } from "../config";
|
|
3
|
+
import {
|
|
4
|
+
SyncMessagesLog,
|
|
5
|
+
TEST_NODE_CONFIG,
|
|
6
|
+
blockMessageTypeOnOutgoingPeer,
|
|
7
|
+
connectedPeersWithMessagesTracking,
|
|
8
|
+
getSyncServerConnectedPeer,
|
|
9
|
+
loadCoValueOrFail,
|
|
10
|
+
setupTestAccount,
|
|
11
|
+
setupTestNode,
|
|
12
|
+
} from "./testUtils";
|
|
13
|
+
import { Peer } from "../exports";
|
|
14
|
+
import { ServerPeerSelector } from "../sync";
|
|
15
|
+
|
|
16
|
+
beforeEach(async () => {
|
|
17
|
+
// We want to simulate a real world communication that happens asynchronously
|
|
18
|
+
TEST_NODE_CONFIG.withAsyncPeers = true;
|
|
19
|
+
|
|
20
|
+
SyncMessagesLog.clear();
|
|
21
|
+
});
|
|
22
|
+
|
|
23
|
+
describe("sharding", () => {
|
|
24
|
+
test("server peers are not filtered by default", async () => {
|
|
25
|
+
const { node: client } = setupTestNode({
|
|
26
|
+
connected: false,
|
|
27
|
+
});
|
|
28
|
+
const group = client.createGroup();
|
|
29
|
+
|
|
30
|
+
const allPeers: Peer[] = [];
|
|
31
|
+
for (let i = 0; i < 5; i++) {
|
|
32
|
+
const syncServer = await setupTestAccount({ isSyncServer: true });
|
|
33
|
+
|
|
34
|
+
const { peer } = getSyncServerConnectedPeer({
|
|
35
|
+
peerId: client.getCurrentAgent().id,
|
|
36
|
+
syncServer: syncServer.node,
|
|
37
|
+
});
|
|
38
|
+
|
|
39
|
+
client.syncManager.addPeer(peer);
|
|
40
|
+
allPeers.push(peer);
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
const serverPeers = client.syncManager.getServerPeers(group.id);
|
|
44
|
+
expect(serverPeers.map((p) => p.id)).toEqual(allPeers.map((p) => p.id));
|
|
45
|
+
});
|
|
46
|
+
|
|
47
|
+
test("server peers are filtered when a serverPeerSelector is set", async () => {
|
|
48
|
+
const firstAlphabetical: ServerPeerSelector = (id, serverPeers) => {
|
|
49
|
+
return serverPeers.sort((a, b) => a.id.localeCompare(b.id)).slice(0, 1);
|
|
50
|
+
};
|
|
51
|
+
const { node: client } = setupTestNode({
|
|
52
|
+
connected: false,
|
|
53
|
+
});
|
|
54
|
+
client.syncManager.serverPeerSelector = firstAlphabetical;
|
|
55
|
+
const group = client.createGroup();
|
|
56
|
+
|
|
57
|
+
const allPeers: Peer[] = [];
|
|
58
|
+
for (let i = 0; i < 5; i++) {
|
|
59
|
+
const syncServer = await setupTestAccount({ isSyncServer: true });
|
|
60
|
+
|
|
61
|
+
const { peer } = getSyncServerConnectedPeer({
|
|
62
|
+
peerId: client.getCurrentAgent().id,
|
|
63
|
+
syncServer: syncServer.node,
|
|
64
|
+
});
|
|
65
|
+
|
|
66
|
+
client.syncManager.addPeer(peer);
|
|
67
|
+
allPeers.push(peer);
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
const serverPeers = client.syncManager.getServerPeers(group.id);
|
|
71
|
+
expect(serverPeers.length).toBe(1);
|
|
72
|
+
expect(serverPeers[0]!.id).toEqual(
|
|
73
|
+
allPeers.sort((a, b) => a.id.localeCompare(b.id))[0]!.id,
|
|
74
|
+
);
|
|
75
|
+
});
|
|
76
|
+
|
|
77
|
+
test("getPeers respects the serverPeerSelector", async () => {
|
|
78
|
+
const firstPeer: ServerPeerSelector = (id, serverPeers) => {
|
|
79
|
+
return serverPeers.slice(0, 1);
|
|
80
|
+
};
|
|
81
|
+
const { node: edge } = setupTestNode({
|
|
82
|
+
connected: false,
|
|
83
|
+
});
|
|
84
|
+
edge.syncManager.serverPeerSelector = firstPeer;
|
|
85
|
+
|
|
86
|
+
// Connect 2 clients to edge
|
|
87
|
+
for (let i = 0; i < 2; i++) {
|
|
88
|
+
const client = await setupTestAccount({});
|
|
89
|
+
const { peer1, peer2 } = connectedPeersWithMessagesTracking({
|
|
90
|
+
peer1: {
|
|
91
|
+
id: client.node.getCurrentAgent().id,
|
|
92
|
+
role: "client",
|
|
93
|
+
},
|
|
94
|
+
peer2: {
|
|
95
|
+
id: edge.getCurrentAgent().id,
|
|
96
|
+
role: "server",
|
|
97
|
+
},
|
|
98
|
+
});
|
|
99
|
+
|
|
100
|
+
edge.syncManager.addPeer(peer1);
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
// Connect edge to 3 core nodes
|
|
104
|
+
for (let i = 0; i < 3; i++) {
|
|
105
|
+
const syncServer = await setupTestAccount({ isSyncServer: true });
|
|
106
|
+
|
|
107
|
+
const { peer } = getSyncServerConnectedPeer({
|
|
108
|
+
peerId: edge.getCurrentAgent().id,
|
|
109
|
+
syncServer: syncServer.node,
|
|
110
|
+
});
|
|
111
|
+
|
|
112
|
+
edge.syncManager.addPeer(peer);
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
expect(edge.syncManager.getPeers("co_z12345").length).toBe(
|
|
116
|
+
2 + 1, // 2 clients + 1 selected core
|
|
117
|
+
);
|
|
118
|
+
});
|
|
119
|
+
});
|
|
@@ -20,6 +20,7 @@ import {
|
|
|
20
20
|
waitFor,
|
|
21
21
|
} from "./testUtils";
|
|
22
22
|
import { stableStringify } from "../jsonStringify";
|
|
23
|
+
import { determineValidTransactions } from "../permissions";
|
|
23
24
|
|
|
24
25
|
// We want to simulate a real world communication that happens asynchronously
|
|
25
26
|
TEST_NODE_CONFIG.withAsyncPeers = true;
|
|
@@ -151,6 +152,47 @@ describe("client with storage syncs with server", () => {
|
|
|
151
152
|
`);
|
|
152
153
|
});
|
|
153
154
|
|
|
155
|
+
test("persists meta information", async () => {
|
|
156
|
+
const client = setupTestNode();
|
|
157
|
+
|
|
158
|
+
const { storage } = client.addStorage();
|
|
159
|
+
|
|
160
|
+
const group = client.node.createGroup();
|
|
161
|
+
const map = group.createMap();
|
|
162
|
+
map.core.makeTransaction([], "trusting", {
|
|
163
|
+
meta: true,
|
|
164
|
+
});
|
|
165
|
+
|
|
166
|
+
await map.core.waitForSync();
|
|
167
|
+
|
|
168
|
+
client.restart();
|
|
169
|
+
|
|
170
|
+
client.addStorage({
|
|
171
|
+
storage,
|
|
172
|
+
});
|
|
173
|
+
|
|
174
|
+
const loadedValue = await loadCoValueOrFail(client.node, map.id);
|
|
175
|
+
|
|
176
|
+
const validTransactions = determineValidTransactions(loadedValue.core);
|
|
177
|
+
|
|
178
|
+
expect(validTransactions[0]?.tx.meta).toBe(`{"meta":true}`);
|
|
179
|
+
|
|
180
|
+
expect(
|
|
181
|
+
SyncMessagesLog.getMessages({
|
|
182
|
+
Group: group.core,
|
|
183
|
+
Map: map.core,
|
|
184
|
+
}),
|
|
185
|
+
).toMatchInlineSnapshot(`
|
|
186
|
+
[
|
|
187
|
+
"client -> storage | CONTENT Group header: true new: After: 0 New: 3",
|
|
188
|
+
"client -> storage | CONTENT Map header: true new: After: 0 New: 1",
|
|
189
|
+
"client -> storage | LOAD Map sessions: empty",
|
|
190
|
+
"storage -> client | CONTENT Group header: true new: After: 0 New: 3",
|
|
191
|
+
"storage -> client | CONTENT Map header: true new: After: 0 New: 1",
|
|
192
|
+
]
|
|
193
|
+
`);
|
|
194
|
+
});
|
|
195
|
+
|
|
154
196
|
test("updating a coValue while offline", async () => {
|
|
155
197
|
const client = setupTestNode();
|
|
156
198
|
|
|
@@ -164,7 +206,7 @@ describe("client with storage syncs with server", () => {
|
|
|
164
206
|
const mapOnClient = await loadCoValueOrFail(client.node, map.id);
|
|
165
207
|
expect(mapOnClient.get("hello")).toEqual("world");
|
|
166
208
|
|
|
167
|
-
client.node.syncManager.getPeers()[0]?.gracefulShutdown();
|
|
209
|
+
client.node.syncManager.getPeers(map.id)[0]?.gracefulShutdown();
|
|
168
210
|
|
|
169
211
|
SyncMessagesLog.clear();
|
|
170
212
|
map.set("hello", "updated", "trusting");
|
|
@@ -156,7 +156,7 @@ describe("client with storage syncs with server", () => {
|
|
|
156
156
|
const mapOnClient = await loadCoValueOrFail(client.node, map.id);
|
|
157
157
|
expect(mapOnClient.get("hello")).toEqual("world");
|
|
158
158
|
|
|
159
|
-
client.node.syncManager.getPeers()[0]?.gracefulShutdown();
|
|
159
|
+
client.node.syncManager.getPeers(map.id)[0]?.gracefulShutdown();
|
|
160
160
|
|
|
161
161
|
SyncMessagesLog.clear();
|
|
162
162
|
map.set("hello", "updated", "trusting");
|
package/src/tests/sync.test.ts
CHANGED
|
@@ -599,8 +599,12 @@ describe("SyncManager - knownStates vs optimisticKnownStates", () => {
|
|
|
599
599
|
// Wait for the full sync to complete
|
|
600
600
|
await mapOnClient.core.waitForSync();
|
|
601
601
|
|
|
602
|
-
const peerStateClient = client.syncManager.getPeers(
|
|
603
|
-
|
|
602
|
+
const peerStateClient = client.syncManager.getPeers(
|
|
603
|
+
mapOnClient.core.id,
|
|
604
|
+
)[0]!;
|
|
605
|
+
const peerStateJazzCloud = jazzCloud.node.syncManager.getPeers(
|
|
606
|
+
mapOnClient.core.id,
|
|
607
|
+
)[0]!;
|
|
604
608
|
|
|
605
609
|
// The optimisticKnownStates should be the same as the knownStates after the full sync is complete
|
|
606
610
|
expect(
|
|
@@ -1115,3 +1119,46 @@ describe("SyncManager.handleSyncMessage", () => {
|
|
|
1115
1119
|
expect(peerState.knownStates.has(group.id)).toBe(true);
|
|
1116
1120
|
});
|
|
1117
1121
|
});
|
|
1122
|
+
|
|
1123
|
+
describe("SyncManager.trackDirtyCoValues", () => {
|
|
1124
|
+
test("should track the dirty coValues", async () => {
|
|
1125
|
+
const node = createTestNode();
|
|
1126
|
+
|
|
1127
|
+
const tracking = node.syncManager.trackDirtyCoValues();
|
|
1128
|
+
|
|
1129
|
+
const group = node.createGroup();
|
|
1130
|
+
const map = group.createMap();
|
|
1131
|
+
map.set("key1", "value1", "trusting");
|
|
1132
|
+
|
|
1133
|
+
const trackedValues = tracking.done();
|
|
1134
|
+
expect(trackedValues.size).toBe(2);
|
|
1135
|
+
expect(trackedValues.has(map.id)).toBe(true);
|
|
1136
|
+
expect(trackedValues.has(group.id)).toBe(true);
|
|
1137
|
+
});
|
|
1138
|
+
|
|
1139
|
+
test("should track the dirty coValues only when active", async () => {
|
|
1140
|
+
const node = createTestNode();
|
|
1141
|
+
|
|
1142
|
+
const group = node.createGroup();
|
|
1143
|
+
|
|
1144
|
+
const tracking1 = node.syncManager.trackDirtyCoValues();
|
|
1145
|
+
|
|
1146
|
+
const map1 = group.createMap();
|
|
1147
|
+
map1.set("key1", "value1", "trusting");
|
|
1148
|
+
|
|
1149
|
+
const tracking2 = node.syncManager.trackDirtyCoValues();
|
|
1150
|
+
|
|
1151
|
+
const map2 = group.createMap();
|
|
1152
|
+
map2.set("key2", "value2", "trusting");
|
|
1153
|
+
|
|
1154
|
+
const tracked1 = tracking1.done();
|
|
1155
|
+
|
|
1156
|
+
const map3 = group.createMap();
|
|
1157
|
+
map3.set("key3", "value3", "trusting");
|
|
1158
|
+
|
|
1159
|
+
const tracked2 = tracking2.done();
|
|
1160
|
+
|
|
1161
|
+
expect(Array.from(tracked1)).toEqual([map1.id, map2.id]);
|
|
1162
|
+
expect(Array.from(tracked2)).toEqual([map2.id, map3.id]);
|
|
1163
|
+
});
|
|
1164
|
+
});
|
|
@@ -9,6 +9,7 @@ import {
|
|
|
9
9
|
setupTestNode,
|
|
10
10
|
waitFor,
|
|
11
11
|
} from "./testUtils";
|
|
12
|
+
import { determineValidTransactions } from "../permissions";
|
|
12
13
|
|
|
13
14
|
// We want to simulate a real world communication that happens asynchronously
|
|
14
15
|
TEST_NODE_CONFIG.withAsyncPeers = true;
|
|
@@ -51,6 +52,40 @@ describe("client to server upload", () => {
|
|
|
51
52
|
`);
|
|
52
53
|
});
|
|
53
54
|
|
|
55
|
+
test("syncs meta information", async () => {
|
|
56
|
+
const client = setupTestNode({
|
|
57
|
+
connected: true,
|
|
58
|
+
});
|
|
59
|
+
|
|
60
|
+
const group = client.node.createGroup();
|
|
61
|
+
const map = group.createMap();
|
|
62
|
+
map.core.makeTransaction([], "trusting", {
|
|
63
|
+
meta: true,
|
|
64
|
+
});
|
|
65
|
+
|
|
66
|
+
await map.core.waitForSync();
|
|
67
|
+
|
|
68
|
+
const loadedValue = await loadCoValueOrFail(jazzCloud.node, map.id);
|
|
69
|
+
|
|
70
|
+
const validTransactions = determineValidTransactions(loadedValue.core);
|
|
71
|
+
|
|
72
|
+
expect(validTransactions[0]?.tx.meta).toBe(`{"meta":true}`);
|
|
73
|
+
|
|
74
|
+
expect(
|
|
75
|
+
SyncMessagesLog.getMessages({
|
|
76
|
+
Group: group.core,
|
|
77
|
+
Map: map.core,
|
|
78
|
+
}),
|
|
79
|
+
).toMatchInlineSnapshot(`
|
|
80
|
+
[
|
|
81
|
+
"client -> server | CONTENT Group header: true new: After: 0 New: 3",
|
|
82
|
+
"client -> server | CONTENT Map header: true new: After: 0 New: 1",
|
|
83
|
+
"server -> client | KNOWN Group sessions: header/3",
|
|
84
|
+
"server -> client | KNOWN Map sessions: header/1",
|
|
85
|
+
]
|
|
86
|
+
`);
|
|
87
|
+
});
|
|
88
|
+
|
|
54
89
|
test("coValue with parent groups uploading", async () => {
|
|
55
90
|
const client = setupTestNode({
|
|
56
91
|
connected: true,
|
package/src/tests/testUtils.ts
CHANGED
|
@@ -669,9 +669,11 @@ export async function setupTestAccount(
|
|
|
669
669
|
addStorage,
|
|
670
670
|
addAsyncStorage,
|
|
671
671
|
disconnect: () => {
|
|
672
|
-
ctx.node.syncManager.getPeers(
|
|
672
|
+
const allPeers = ctx.node.syncManager.getPeers(ctx.accountID);
|
|
673
|
+
allPeers.forEach((peer) => {
|
|
673
674
|
peer.gracefulShutdown();
|
|
674
675
|
});
|
|
676
|
+
ctx.node.syncManager.peers = {};
|
|
675
677
|
},
|
|
676
678
|
};
|
|
677
679
|
}
|