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.
Files changed (117) hide show
  1. package/.turbo/turbo-build.log +1 -1
  2. package/CHANGELOG.md +9 -0
  3. package/dist/SyncStateManager.d.ts.map +1 -1
  4. package/dist/SyncStateManager.js +2 -2
  5. package/dist/SyncStateManager.js.map +1 -1
  6. package/dist/coValueCore/SessionMap.d.ts +1 -0
  7. package/dist/coValueCore/SessionMap.d.ts.map +1 -1
  8. package/dist/coValueCore/SessionMap.js +17 -1
  9. package/dist/coValueCore/SessionMap.js.map +1 -1
  10. package/dist/coValueCore/coValueCore.d.ts +14 -9
  11. package/dist/coValueCore/coValueCore.d.ts.map +1 -1
  12. package/dist/coValueCore/coValueCore.js +62 -47
  13. package/dist/coValueCore/coValueCore.js.map +1 -1
  14. package/dist/coValueCore/verifiedState.d.ts +2 -2
  15. package/dist/coValueCore/verifiedState.d.ts.map +1 -1
  16. package/dist/coValueCore/verifiedState.js +86 -75
  17. package/dist/coValueCore/verifiedState.js.map +1 -1
  18. package/dist/coValues/group.d.ts +1 -0
  19. package/dist/coValues/group.d.ts.map +1 -1
  20. package/dist/coValues/group.js +24 -4
  21. package/dist/coValues/group.js.map +1 -1
  22. package/dist/knownState.d.ts +1 -1
  23. package/dist/knownState.d.ts.map +1 -1
  24. package/dist/knownState.js +1 -1
  25. package/dist/knownState.js.map +1 -1
  26. package/dist/localNode.d.ts.map +1 -1
  27. package/dist/localNode.js +1 -2
  28. package/dist/localNode.js.map +1 -1
  29. package/dist/queue/LocalTransactionsSyncQueue.d.ts.map +1 -1
  30. package/dist/queue/LocalTransactionsSyncQueue.js +16 -1
  31. package/dist/queue/LocalTransactionsSyncQueue.js.map +1 -1
  32. package/dist/storage/knownState.js +2 -2
  33. package/dist/storage/knownState.js.map +1 -1
  34. package/dist/sync.d.ts.map +1 -1
  35. package/dist/sync.js +8 -2
  36. package/dist/sync.js.map +1 -1
  37. package/dist/tests/PureJSCrypto.test.js +1 -1
  38. package/dist/tests/PureJSCrypto.test.js.map +1 -1
  39. package/dist/tests/StorageApiAsync.test.js +11 -11
  40. package/dist/tests/StorageApiAsync.test.js.map +1 -1
  41. package/dist/tests/StorageApiSync.test.js +3 -3
  42. package/dist/tests/StorageApiSync.test.js.map +1 -1
  43. package/dist/tests/WasmCrypto.test.js +1 -1
  44. package/dist/tests/WasmCrypto.test.js.map +1 -1
  45. package/dist/tests/coPlainText.test.js +1 -1
  46. package/dist/tests/coStream.test.js +12 -12
  47. package/dist/tests/coStream.test.js.map +1 -1
  48. package/dist/tests/coValueCore.isCompletelyDownloaded.test.d.ts +2 -0
  49. package/dist/tests/coValueCore.isCompletelyDownloaded.test.d.ts.map +1 -0
  50. package/dist/tests/coValueCore.isCompletelyDownloaded.test.js +421 -0
  51. package/dist/tests/coValueCore.isCompletelyDownloaded.test.js.map +1 -0
  52. package/dist/tests/coValueCore.isStreaming.test.d.ts +2 -0
  53. package/dist/tests/coValueCore.isStreaming.test.d.ts.map +1 -0
  54. package/dist/tests/coValueCore.isStreaming.test.js +181 -0
  55. package/dist/tests/coValueCore.isStreaming.test.js.map +1 -0
  56. package/dist/tests/coValueCore.newContentSince.test.d.ts +2 -0
  57. package/dist/tests/coValueCore.newContentSince.test.d.ts.map +1 -0
  58. package/dist/tests/coValueCore.newContentSince.test.js +808 -0
  59. package/dist/tests/coValueCore.newContentSince.test.js.map +1 -0
  60. package/dist/tests/coreWasm.test.js +2 -2
  61. package/dist/tests/coreWasm.test.js.map +1 -1
  62. package/dist/tests/group.childKeyRotation.test.d.ts +2 -0
  63. package/dist/tests/group.childKeyRotation.test.d.ts.map +1 -0
  64. package/dist/tests/group.childKeyRotation.test.js +261 -0
  65. package/dist/tests/group.childKeyRotation.test.js.map +1 -0
  66. package/dist/tests/group.removeMember.test.js +1 -114
  67. package/dist/tests/group.removeMember.test.js.map +1 -1
  68. package/dist/tests/knownState.test.js +11 -11
  69. package/dist/tests/knownState.test.js.map +1 -1
  70. package/dist/tests/sync.auth.test.js +6 -6
  71. package/dist/tests/sync.load.test.js +68 -5
  72. package/dist/tests/sync.load.test.js.map +1 -1
  73. package/dist/tests/sync.mesh.test.js +11 -17
  74. package/dist/tests/sync.mesh.test.js.map +1 -1
  75. package/dist/tests/sync.peerReconciliation.test.js +1 -1
  76. package/dist/tests/sync.storage.test.js +7 -7
  77. package/dist/tests/sync.storage.test.js.map +1 -1
  78. package/dist/tests/sync.storageAsync.test.js +4 -4
  79. package/dist/tests/sync.storageAsync.test.js.map +1 -1
  80. package/dist/tests/sync.upload.test.js +96 -40
  81. package/dist/tests/sync.upload.test.js.map +1 -1
  82. package/dist/tests/testUtils.d.ts +2 -0
  83. package/dist/tests/testUtils.d.ts.map +1 -1
  84. package/dist/tests/testUtils.js +22 -1
  85. package/dist/tests/testUtils.js.map +1 -1
  86. package/package.json +3 -3
  87. package/src/SyncStateManager.ts +2 -5
  88. package/src/coValueCore/SessionMap.ts +24 -0
  89. package/src/coValueCore/coValueCore.ts +77 -55
  90. package/src/coValueCore/verifiedState.ts +123 -108
  91. package/src/coValues/group.ts +27 -4
  92. package/src/knownState.ts +1 -1
  93. package/src/localNode.ts +1 -2
  94. package/src/queue/LocalTransactionsSyncQueue.ts +25 -0
  95. package/src/storage/knownState.ts +2 -2
  96. package/src/sync.ts +7 -2
  97. package/src/tests/PureJSCrypto.test.ts +1 -2
  98. package/src/tests/StorageApiAsync.test.ts +11 -11
  99. package/src/tests/StorageApiSync.test.ts +3 -3
  100. package/src/tests/WasmCrypto.test.ts +1 -2
  101. package/src/tests/coPlainText.test.ts +1 -1
  102. package/src/tests/coStream.test.ts +12 -12
  103. package/src/tests/coValueCore.isCompletelyDownloaded.test.ts +589 -0
  104. package/src/tests/coValueCore.isStreaming.test.ts +271 -0
  105. package/src/tests/coValueCore.newContentSince.test.ts +966 -0
  106. package/src/tests/coreWasm.test.ts +2 -2
  107. package/src/tests/group.childKeyRotation.test.ts +431 -0
  108. package/src/tests/group.removeMember.test.ts +1 -184
  109. package/src/tests/knownState.test.ts +11 -11
  110. package/src/tests/sync.auth.test.ts +6 -6
  111. package/src/tests/sync.load.test.ts +80 -5
  112. package/src/tests/sync.mesh.test.ts +11 -17
  113. package/src/tests/sync.peerReconciliation.test.ts +1 -1
  114. package/src/tests/sync.storage.test.ts +7 -7
  115. package/src/tests/sync.storageAsync.test.ts +4 -4
  116. package/src/tests/sync.upload.test.ts +106 -40
  117. 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
+ });