cojson 0.18.32 → 0.18.33
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 +9 -0
- package/dist/SyncStateManager.d.ts.map +1 -1
- package/dist/SyncStateManager.js +2 -2
- package/dist/SyncStateManager.js.map +1 -1
- package/dist/coValueCore/SessionMap.d.ts +1 -0
- package/dist/coValueCore/SessionMap.d.ts.map +1 -1
- package/dist/coValueCore/SessionMap.js +17 -1
- package/dist/coValueCore/SessionMap.js.map +1 -1
- package/dist/coValueCore/coValueCore.d.ts +14 -9
- package/dist/coValueCore/coValueCore.d.ts.map +1 -1
- package/dist/coValueCore/coValueCore.js +62 -47
- package/dist/coValueCore/coValueCore.js.map +1 -1
- package/dist/coValueCore/verifiedState.d.ts +2 -2
- package/dist/coValueCore/verifiedState.d.ts.map +1 -1
- package/dist/coValueCore/verifiedState.js +86 -75
- package/dist/coValueCore/verifiedState.js.map +1 -1
- package/dist/coValues/group.d.ts +1 -0
- package/dist/coValues/group.d.ts.map +1 -1
- package/dist/coValues/group.js +24 -4
- package/dist/coValues/group.js.map +1 -1
- package/dist/knownState.d.ts +1 -1
- package/dist/knownState.d.ts.map +1 -1
- package/dist/knownState.js +1 -1
- package/dist/knownState.js.map +1 -1
- package/dist/localNode.d.ts.map +1 -1
- package/dist/localNode.js +1 -2
- package/dist/localNode.js.map +1 -1
- package/dist/queue/LocalTransactionsSyncQueue.d.ts.map +1 -1
- package/dist/queue/LocalTransactionsSyncQueue.js +16 -1
- package/dist/queue/LocalTransactionsSyncQueue.js.map +1 -1
- package/dist/storage/knownState.js +2 -2
- package/dist/storage/knownState.js.map +1 -1
- package/dist/sync.d.ts.map +1 -1
- package/dist/sync.js +8 -2
- package/dist/sync.js.map +1 -1
- package/dist/tests/PureJSCrypto.test.js +1 -1
- package/dist/tests/PureJSCrypto.test.js.map +1 -1
- package/dist/tests/StorageApiAsync.test.js +11 -11
- package/dist/tests/StorageApiAsync.test.js.map +1 -1
- package/dist/tests/StorageApiSync.test.js +3 -3
- package/dist/tests/StorageApiSync.test.js.map +1 -1
- package/dist/tests/WasmCrypto.test.js +1 -1
- package/dist/tests/WasmCrypto.test.js.map +1 -1
- package/dist/tests/coPlainText.test.js +1 -1
- package/dist/tests/coStream.test.js +12 -12
- package/dist/tests/coStream.test.js.map +1 -1
- package/dist/tests/coValueCore.isCompletelyDownloaded.test.d.ts +2 -0
- package/dist/tests/coValueCore.isCompletelyDownloaded.test.d.ts.map +1 -0
- package/dist/tests/coValueCore.isCompletelyDownloaded.test.js +421 -0
- package/dist/tests/coValueCore.isCompletelyDownloaded.test.js.map +1 -0
- package/dist/tests/coValueCore.isStreaming.test.d.ts +2 -0
- package/dist/tests/coValueCore.isStreaming.test.d.ts.map +1 -0
- package/dist/tests/coValueCore.isStreaming.test.js +181 -0
- package/dist/tests/coValueCore.isStreaming.test.js.map +1 -0
- package/dist/tests/coValueCore.newContentSince.test.d.ts +2 -0
- package/dist/tests/coValueCore.newContentSince.test.d.ts.map +1 -0
- package/dist/tests/coValueCore.newContentSince.test.js +808 -0
- package/dist/tests/coValueCore.newContentSince.test.js.map +1 -0
- package/dist/tests/coreWasm.test.js +2 -2
- package/dist/tests/coreWasm.test.js.map +1 -1
- package/dist/tests/group.childKeyRotation.test.d.ts +2 -0
- package/dist/tests/group.childKeyRotation.test.d.ts.map +1 -0
- package/dist/tests/group.childKeyRotation.test.js +261 -0
- package/dist/tests/group.childKeyRotation.test.js.map +1 -0
- package/dist/tests/group.removeMember.test.js +1 -114
- package/dist/tests/group.removeMember.test.js.map +1 -1
- package/dist/tests/knownState.test.js +11 -11
- package/dist/tests/knownState.test.js.map +1 -1
- package/dist/tests/sync.auth.test.js +6 -6
- package/dist/tests/sync.load.test.js +68 -5
- package/dist/tests/sync.load.test.js.map +1 -1
- package/dist/tests/sync.mesh.test.js +11 -17
- package/dist/tests/sync.mesh.test.js.map +1 -1
- package/dist/tests/sync.peerReconciliation.test.js +1 -1
- package/dist/tests/sync.storage.test.js +7 -7
- package/dist/tests/sync.storage.test.js.map +1 -1
- package/dist/tests/sync.storageAsync.test.js +4 -4
- package/dist/tests/sync.storageAsync.test.js.map +1 -1
- package/dist/tests/sync.upload.test.js +96 -40
- package/dist/tests/sync.upload.test.js.map +1 -1
- package/dist/tests/testUtils.d.ts +2 -0
- package/dist/tests/testUtils.d.ts.map +1 -1
- package/dist/tests/testUtils.js +22 -1
- package/dist/tests/testUtils.js.map +1 -1
- package/package.json +3 -3
- package/src/SyncStateManager.ts +2 -5
- package/src/coValueCore/SessionMap.ts +24 -0
- package/src/coValueCore/coValueCore.ts +77 -55
- package/src/coValueCore/verifiedState.ts +123 -108
- package/src/coValues/group.ts +27 -4
- package/src/knownState.ts +1 -1
- package/src/localNode.ts +1 -2
- package/src/queue/LocalTransactionsSyncQueue.ts +25 -0
- package/src/storage/knownState.ts +2 -2
- package/src/sync.ts +7 -2
- package/src/tests/PureJSCrypto.test.ts +1 -2
- package/src/tests/StorageApiAsync.test.ts +11 -11
- package/src/tests/StorageApiSync.test.ts +3 -3
- package/src/tests/WasmCrypto.test.ts +1 -2
- package/src/tests/coPlainText.test.ts +1 -1
- package/src/tests/coStream.test.ts +12 -12
- package/src/tests/coValueCore.isCompletelyDownloaded.test.ts +589 -0
- package/src/tests/coValueCore.isStreaming.test.ts +271 -0
- package/src/tests/coValueCore.newContentSince.test.ts +966 -0
- package/src/tests/coreWasm.test.ts +2 -2
- package/src/tests/group.childKeyRotation.test.ts +431 -0
- package/src/tests/group.removeMember.test.ts +1 -184
- package/src/tests/knownState.test.ts +11 -11
- package/src/tests/sync.auth.test.ts +6 -6
- package/src/tests/sync.load.test.ts +80 -5
- package/src/tests/sync.mesh.test.ts +11 -17
- package/src/tests/sync.peerReconciliation.test.ts +1 -1
- package/src/tests/sync.storage.test.ts +7 -7
- package/src/tests/sync.storageAsync.test.ts +4 -4
- package/src/tests/sync.upload.test.ts +106 -40
- package/src/tests/testUtils.ts +24 -2
|
@@ -0,0 +1,271 @@
|
|
|
1
|
+
import { assert, beforeEach, describe, expect, test } from "vitest";
|
|
2
|
+
import {
|
|
3
|
+
SyncMessagesLog,
|
|
4
|
+
TEST_NODE_CONFIG,
|
|
5
|
+
loadCoValueOrFail,
|
|
6
|
+
setupTestNode,
|
|
7
|
+
waitFor,
|
|
8
|
+
} from "./testUtils";
|
|
9
|
+
|
|
10
|
+
let jazzCloud: ReturnType<typeof setupTestNode>;
|
|
11
|
+
|
|
12
|
+
beforeEach(async () => {
|
|
13
|
+
// We want to simulate a real world communication that happens asynchronously
|
|
14
|
+
TEST_NODE_CONFIG.withAsyncPeers = true;
|
|
15
|
+
|
|
16
|
+
SyncMessagesLog.clear();
|
|
17
|
+
jazzCloud = setupTestNode({ isSyncServer: true });
|
|
18
|
+
});
|
|
19
|
+
|
|
20
|
+
describe("isStreaming", () => {
|
|
21
|
+
test("loading a small value should not be streaming", async () => {
|
|
22
|
+
const client = setupTestNode({
|
|
23
|
+
connected: true,
|
|
24
|
+
});
|
|
25
|
+
|
|
26
|
+
const group = jazzCloud.node.createGroup();
|
|
27
|
+
group.addMember("everyone", "writer");
|
|
28
|
+
|
|
29
|
+
const map = group.createMap();
|
|
30
|
+
map.set("hello", "world", "trusting");
|
|
31
|
+
|
|
32
|
+
const newSession = client.spawnNewSession();
|
|
33
|
+
const mapInNewSession = await loadCoValueOrFail(newSession.node, map.id);
|
|
34
|
+
|
|
35
|
+
// For a small value, isStreaming should always be false
|
|
36
|
+
expect(mapInNewSession.core.isStreaming()).toBe(false);
|
|
37
|
+
});
|
|
38
|
+
|
|
39
|
+
test("loading a large value should be streaming until all chunks are sent", async () => {
|
|
40
|
+
const client = setupTestNode({
|
|
41
|
+
connected: true,
|
|
42
|
+
});
|
|
43
|
+
|
|
44
|
+
const group = client.node.createGroup();
|
|
45
|
+
|
|
46
|
+
await group.core.waitForSync();
|
|
47
|
+
client.disconnect();
|
|
48
|
+
|
|
49
|
+
const map = group.createMap();
|
|
50
|
+
|
|
51
|
+
// Generate a large amount of data that requires multiple chunks
|
|
52
|
+
const dataSize = 1 * 1024 * 100;
|
|
53
|
+
const chunkSize = 1024; // 1KB chunks
|
|
54
|
+
const chunks = dataSize / chunkSize;
|
|
55
|
+
|
|
56
|
+
const value = Buffer.alloc(chunkSize, `value$`).toString("base64");
|
|
57
|
+
|
|
58
|
+
for (let i = 0; i < chunks; i++) {
|
|
59
|
+
const key = `key${i}`;
|
|
60
|
+
map.set(key, value, "trusting");
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
const newSession = client.spawnNewSession();
|
|
64
|
+
|
|
65
|
+
await loadCoValueOrFail(client.node, group.id);
|
|
66
|
+
|
|
67
|
+
const content = map.core.verified.newContentSince(undefined);
|
|
68
|
+
assert(content);
|
|
69
|
+
const lastChunk = content.pop();
|
|
70
|
+
assert(lastChunk);
|
|
71
|
+
|
|
72
|
+
for (const chunk of content) {
|
|
73
|
+
newSession.node.syncManager.handleNewContent(chunk, "import");
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
const mapInNewSession = await loadCoValueOrFail(newSession.node, map.id);
|
|
77
|
+
|
|
78
|
+
expect(mapInNewSession.core.isStreaming()).toBe(true);
|
|
79
|
+
|
|
80
|
+
newSession.node.syncManager.handleNewContent(lastChunk, "import");
|
|
81
|
+
|
|
82
|
+
expect(mapInNewSession.core.isStreaming()).toBe(false);
|
|
83
|
+
});
|
|
84
|
+
|
|
85
|
+
test("loading a large content update should be streaming until all chunks are sent", async () => {
|
|
86
|
+
const client = setupTestNode({
|
|
87
|
+
connected: true,
|
|
88
|
+
});
|
|
89
|
+
|
|
90
|
+
const group = client.node.createGroup();
|
|
91
|
+
const map = group.createMap();
|
|
92
|
+
|
|
93
|
+
map.set("hello", "world", "trusting");
|
|
94
|
+
|
|
95
|
+
const knownState = map.core.knownState();
|
|
96
|
+
|
|
97
|
+
await map.core.waitForSync();
|
|
98
|
+
client.disconnect();
|
|
99
|
+
|
|
100
|
+
// Generate a large amount of data that requires multiple chunks
|
|
101
|
+
const dataSize = 1 * 1024 * 100;
|
|
102
|
+
const chunkSize = 1024; // 1KB chunks
|
|
103
|
+
const chunks = dataSize / chunkSize;
|
|
104
|
+
|
|
105
|
+
const value = Buffer.alloc(chunkSize, `value$`).toString("base64");
|
|
106
|
+
|
|
107
|
+
for (let i = 0; i < chunks; i++) {
|
|
108
|
+
const key = `key${i}`;
|
|
109
|
+
map.set(key, value, "trusting");
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
const newSession = client.spawnNewSession();
|
|
113
|
+
|
|
114
|
+
await loadCoValueOrFail(client.node, group.id);
|
|
115
|
+
|
|
116
|
+
const content = map.core.verified.newContentSince(knownState);
|
|
117
|
+
assert(content);
|
|
118
|
+
const lastChunk = content.pop();
|
|
119
|
+
assert(lastChunk);
|
|
120
|
+
|
|
121
|
+
const mapInNewSession = await loadCoValueOrFail(newSession.node, map.id);
|
|
122
|
+
|
|
123
|
+
for (const chunk of content) {
|
|
124
|
+
newSession.node.syncManager.handleNewContent(chunk, "import");
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
expect(mapInNewSession.core.isStreaming()).toBe(true);
|
|
128
|
+
|
|
129
|
+
newSession.node.syncManager.handleNewContent(lastChunk, "import");
|
|
130
|
+
|
|
131
|
+
expect(mapInNewSession.core.isStreaming()).toBe(false);
|
|
132
|
+
});
|
|
133
|
+
|
|
134
|
+
test("streaming a large value between two clients should be streaming until all chunks are sent", async () => {
|
|
135
|
+
const client = setupTestNode();
|
|
136
|
+
client.connectToSyncServer({
|
|
137
|
+
ourName: "initialClient",
|
|
138
|
+
});
|
|
139
|
+
const streamingClient = client.spawnNewSession();
|
|
140
|
+
streamingClient.connectToSyncServer({
|
|
141
|
+
ourName: "streamingClient",
|
|
142
|
+
});
|
|
143
|
+
|
|
144
|
+
const group = client.node.createGroup();
|
|
145
|
+
|
|
146
|
+
await group.core.waitForSync();
|
|
147
|
+
client.disconnect();
|
|
148
|
+
|
|
149
|
+
const map = group.createMap();
|
|
150
|
+
|
|
151
|
+
// Generate a large amount of data that requires multiple chunks
|
|
152
|
+
const dataSize = 1 * 1024 * 100;
|
|
153
|
+
const chunkSize = 1024; // 1KB chunks
|
|
154
|
+
const chunks = dataSize / chunkSize;
|
|
155
|
+
|
|
156
|
+
const value = Buffer.alloc(chunkSize, `value$`).toString("base64");
|
|
157
|
+
|
|
158
|
+
for (let i = 0; i < chunks; i++) {
|
|
159
|
+
const key = `key${i}`;
|
|
160
|
+
map.set(key, value, "trusting");
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
const loadingClient = client.spawnNewSession();
|
|
164
|
+
loadingClient.connectToSyncServer({
|
|
165
|
+
ourName: "loadingClient",
|
|
166
|
+
});
|
|
167
|
+
|
|
168
|
+
await loadCoValueOrFail(loadingClient.node, group.id);
|
|
169
|
+
|
|
170
|
+
const content = map.core.verified.newContentSince(undefined);
|
|
171
|
+
assert(content);
|
|
172
|
+
const lastChunk = content.pop();
|
|
173
|
+
assert(lastChunk);
|
|
174
|
+
|
|
175
|
+
for (const chunk of content) {
|
|
176
|
+
streamingClient.node.syncManager.handleNewContent(chunk, "import");
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
await streamingClient.node.syncManager.waitForAllCoValuesSync();
|
|
180
|
+
|
|
181
|
+
const mapInLoadingClient = await loadCoValueOrFail(
|
|
182
|
+
loadingClient.node,
|
|
183
|
+
map.id,
|
|
184
|
+
);
|
|
185
|
+
|
|
186
|
+
expect(mapInLoadingClient.core.isStreaming()).toBe(true);
|
|
187
|
+
|
|
188
|
+
streamingClient.node.syncManager.handleNewContent(lastChunk, "import");
|
|
189
|
+
|
|
190
|
+
await waitFor(() => {
|
|
191
|
+
expect(mapInLoadingClient.core.knownState()).toEqual(
|
|
192
|
+
map.core.knownState(),
|
|
193
|
+
);
|
|
194
|
+
});
|
|
195
|
+
|
|
196
|
+
expect(mapInLoadingClient.core.isStreaming()).toBe(false);
|
|
197
|
+
});
|
|
198
|
+
|
|
199
|
+
test("should be false when getting streaming content that is already in the known state", async () => {
|
|
200
|
+
const client = setupTestNode({
|
|
201
|
+
connected: true,
|
|
202
|
+
});
|
|
203
|
+
|
|
204
|
+
const group = client.node.createGroup();
|
|
205
|
+
|
|
206
|
+
await group.core.waitForSync();
|
|
207
|
+
|
|
208
|
+
const map = group.createMap();
|
|
209
|
+
|
|
210
|
+
// Generate a large amount of data that requires multiple chunks
|
|
211
|
+
const dataSize = 1 * 1024 * 100;
|
|
212
|
+
const chunkSize = 1024; // 1KB chunks
|
|
213
|
+
const chunks = dataSize / chunkSize;
|
|
214
|
+
|
|
215
|
+
const value = Buffer.alloc(chunkSize, `value$`).toString("base64");
|
|
216
|
+
|
|
217
|
+
for (let i = 0; i < chunks; i++) {
|
|
218
|
+
const key = `key${i}`;
|
|
219
|
+
map.set(key, value, "trusting");
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
await map.core.waitForSync();
|
|
223
|
+
const newSession = client.spawnNewSession();
|
|
224
|
+
|
|
225
|
+
await loadCoValueOrFail(newSession.node, map.id);
|
|
226
|
+
|
|
227
|
+
const content = map.core.verified.newContentSince(undefined);
|
|
228
|
+
assert(content);
|
|
229
|
+
const lastChunk = content.pop();
|
|
230
|
+
assert(lastChunk);
|
|
231
|
+
|
|
232
|
+
for (const chunk of content) {
|
|
233
|
+
newSession.node.syncManager.handleNewContent(chunk, "import");
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
const mapInNewSession = await loadCoValueOrFail(newSession.node, map.id);
|
|
237
|
+
|
|
238
|
+
expect(mapInNewSession.core.isStreaming()).toBe(false);
|
|
239
|
+
});
|
|
240
|
+
|
|
241
|
+
test("should be false when getting streaming content that's not really streaming", async () => {
|
|
242
|
+
const client = setupTestNode({
|
|
243
|
+
connected: true,
|
|
244
|
+
});
|
|
245
|
+
|
|
246
|
+
const group = client.node.createGroup();
|
|
247
|
+
|
|
248
|
+
await group.core.waitForSync();
|
|
249
|
+
client.disconnect();
|
|
250
|
+
|
|
251
|
+
const map = group.createMap();
|
|
252
|
+
map.set("hello", "world", "trusting");
|
|
253
|
+
|
|
254
|
+
const newSession = client.spawnNewSession();
|
|
255
|
+
|
|
256
|
+
await loadCoValueOrFail(client.node, group.id);
|
|
257
|
+
|
|
258
|
+
const content = map.core.verified.newContentSince(undefined);
|
|
259
|
+
assert(content);
|
|
260
|
+
|
|
261
|
+
content[0]!.expectContentUntil = map.core.knownState().sessions;
|
|
262
|
+
|
|
263
|
+
for (const chunk of content) {
|
|
264
|
+
newSession.node.syncManager.handleNewContent(chunk, "import");
|
|
265
|
+
}
|
|
266
|
+
|
|
267
|
+
const mapInNewSession = await loadCoValueOrFail(newSession.node, map.id);
|
|
268
|
+
|
|
269
|
+
expect(mapInNewSession.core.isStreaming()).toBe(false);
|
|
270
|
+
});
|
|
271
|
+
});
|