cojson 0.18.32 → 0.18.34
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 +18 -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 +22 -12
- 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 +65 -51
- package/dist/coValueCore/coValueCore.js.map +1 -1
- package/dist/coValueCore/verifiedState.d.ts +5 -3
- package/dist/coValueCore/verifiedState.d.ts.map +1 -1
- package/dist/coValueCore/verifiedState.js +93 -76
- 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 +9 -1
- package/dist/knownState.d.ts.map +1 -1
- package/dist/knownState.js +29 -3
- package/dist/knownState.js.map +1 -1
- package/dist/localNode.d.ts.map +1 -1
- package/dist/localNode.js +3 -3
- package/dist/localNode.js.map +1 -1
- package/dist/queue/LocalTransactionsSyncQueue.d.ts +10 -9
- package/dist/queue/LocalTransactionsSyncQueue.d.ts.map +1 -1
- package/dist/queue/LocalTransactionsSyncQueue.js +53 -32
- 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 +1 -2
- package/dist/sync.d.ts.map +1 -1
- package/dist/sync.js +8 -3
- 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 +13 -14
- package/dist/tests/coPlainText.test.js.map +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 +422 -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 +232 -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 +83 -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 +67 -4
- package/dist/tests/sync.load.test.js.map +1 -1
- package/dist/tests/sync.mesh.test.js +41 -40
- 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 +29 -28
- package/dist/tests/sync.storage.test.js.map +1 -1
- package/dist/tests/sync.storageAsync.test.js +26 -25
- 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 +12 -8
- package/dist/tests/testUtils.d.ts.map +1 -1
- package/dist/tests/testUtils.js +39 -8
- package/dist/tests/testUtils.js.map +1 -1
- package/package.json +3 -3
- package/src/SyncStateManager.ts +5 -2
- package/src/coValueCore/SessionMap.ts +39 -12
- package/src/coValueCore/coValueCore.ts +81 -66
- package/src/coValueCore/verifiedState.ts +139 -109
- package/src/coValues/group.ts +27 -4
- package/src/knownState.ts +49 -5
- package/src/localNode.ts +7 -5
- package/src/queue/LocalTransactionsSyncQueue.ts +77 -68
- package/src/storage/knownState.ts +2 -2
- package/src/sync.ts +7 -3
- 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 +13 -14
- package/src/tests/coStream.test.ts +12 -12
- package/src/tests/coValueCore.isCompletelyDownloaded.test.ts +590 -0
- package/src/tests/coValueCore.isStreaming.test.ts +353 -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 +108 -11
- package/src/tests/sync.auth.test.ts +6 -6
- package/src/tests/sync.load.test.ts +79 -4
- package/src/tests/sync.mesh.test.ts +41 -40
- package/src/tests/sync.peerReconciliation.test.ts +1 -1
- package/src/tests/sync.storage.test.ts +29 -28
- package/src/tests/sync.storageAsync.test.ts +26 -25
- package/src/tests/sync.upload.test.ts +106 -40
- package/src/tests/testUtils.ts +43 -9
|
@@ -0,0 +1,353 @@
|
|
|
1
|
+
import { assert, beforeEach, describe, expect, test } from "vitest";
|
|
2
|
+
import {
|
|
3
|
+
SyncMessagesLog,
|
|
4
|
+
TEST_NODE_CONFIG,
|
|
5
|
+
loadCoValueOrFail,
|
|
6
|
+
setupTestAccount,
|
|
7
|
+
setupTestNode,
|
|
8
|
+
waitFor,
|
|
9
|
+
} from "./testUtils";
|
|
10
|
+
import type { RawCoMap } from "../exports";
|
|
11
|
+
import type { CoID } from "../coValue";
|
|
12
|
+
|
|
13
|
+
let jazzCloud: ReturnType<typeof setupTestNode>;
|
|
14
|
+
|
|
15
|
+
beforeEach(async () => {
|
|
16
|
+
// We want to simulate a real world communication that happens asynchronously
|
|
17
|
+
TEST_NODE_CONFIG.withAsyncPeers = true;
|
|
18
|
+
|
|
19
|
+
SyncMessagesLog.clear();
|
|
20
|
+
jazzCloud = setupTestNode({ isSyncServer: true });
|
|
21
|
+
});
|
|
22
|
+
|
|
23
|
+
describe("isStreaming", () => {
|
|
24
|
+
test("loading a small value should not be streaming", async () => {
|
|
25
|
+
const client = setupTestNode({
|
|
26
|
+
connected: true,
|
|
27
|
+
});
|
|
28
|
+
|
|
29
|
+
const group = jazzCloud.node.createGroup();
|
|
30
|
+
group.addMember("everyone", "writer");
|
|
31
|
+
|
|
32
|
+
const map = group.createMap();
|
|
33
|
+
map.set("hello", "world", "trusting");
|
|
34
|
+
|
|
35
|
+
const newSession = client.spawnNewSession();
|
|
36
|
+
const mapInNewSession = await loadCoValueOrFail(newSession.node, map.id);
|
|
37
|
+
|
|
38
|
+
// For a small value, isStreaming should always be false
|
|
39
|
+
expect(mapInNewSession.core.isStreaming()).toBe(false);
|
|
40
|
+
});
|
|
41
|
+
|
|
42
|
+
test("loading a large value should be streaming until all chunks are sent", async () => {
|
|
43
|
+
const client = setupTestNode({
|
|
44
|
+
connected: true,
|
|
45
|
+
});
|
|
46
|
+
|
|
47
|
+
const group = client.node.createGroup();
|
|
48
|
+
|
|
49
|
+
await group.core.waitForSync();
|
|
50
|
+
client.disconnect();
|
|
51
|
+
|
|
52
|
+
const map = group.createMap();
|
|
53
|
+
|
|
54
|
+
// Generate a large amount of data that requires multiple chunks
|
|
55
|
+
const dataSize = 1 * 1024 * 100;
|
|
56
|
+
const chunkSize = 1024; // 1KB chunks
|
|
57
|
+
const chunks = dataSize / chunkSize;
|
|
58
|
+
|
|
59
|
+
const value = Buffer.alloc(chunkSize, `value$`).toString("base64");
|
|
60
|
+
|
|
61
|
+
for (let i = 0; i < chunks; i++) {
|
|
62
|
+
const key = `key${i}`;
|
|
63
|
+
map.set(key, value, "trusting");
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
const newSession = client.spawnNewSession();
|
|
67
|
+
|
|
68
|
+
await loadCoValueOrFail(client.node, group.id);
|
|
69
|
+
|
|
70
|
+
const content = map.core.verified.newContentSince(undefined);
|
|
71
|
+
assert(content);
|
|
72
|
+
const lastChunk = content.pop();
|
|
73
|
+
assert(lastChunk);
|
|
74
|
+
|
|
75
|
+
for (const chunk of content) {
|
|
76
|
+
newSession.node.syncManager.handleNewContent(chunk, "import");
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
const mapInNewSession = await loadCoValueOrFail(newSession.node, map.id);
|
|
80
|
+
|
|
81
|
+
expect(mapInNewSession.core.isStreaming()).toBe(true);
|
|
82
|
+
|
|
83
|
+
newSession.node.syncManager.handleNewContent(lastChunk, "import");
|
|
84
|
+
|
|
85
|
+
expect(mapInNewSession.core.isStreaming()).toBe(false);
|
|
86
|
+
});
|
|
87
|
+
|
|
88
|
+
test("loading a large content update should be streaming until all chunks are sent", async () => {
|
|
89
|
+
const client = setupTestNode({
|
|
90
|
+
connected: true,
|
|
91
|
+
});
|
|
92
|
+
|
|
93
|
+
const group = client.node.createGroup();
|
|
94
|
+
const map = group.createMap();
|
|
95
|
+
|
|
96
|
+
map.set("hello", "world", "trusting");
|
|
97
|
+
|
|
98
|
+
const knownState = map.core.knownState();
|
|
99
|
+
|
|
100
|
+
await map.core.waitForSync();
|
|
101
|
+
client.disconnect();
|
|
102
|
+
|
|
103
|
+
// Generate a large amount of data that requires multiple chunks
|
|
104
|
+
const dataSize = 1 * 1024 * 100;
|
|
105
|
+
const chunkSize = 1024; // 1KB chunks
|
|
106
|
+
const chunks = dataSize / chunkSize;
|
|
107
|
+
|
|
108
|
+
const value = Buffer.alloc(chunkSize, `value$`).toString("base64");
|
|
109
|
+
|
|
110
|
+
for (let i = 0; i < chunks; i++) {
|
|
111
|
+
const key = `key${i}`;
|
|
112
|
+
map.set(key, value, "trusting");
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
const newSession = client.spawnNewSession();
|
|
116
|
+
|
|
117
|
+
await loadCoValueOrFail(client.node, group.id);
|
|
118
|
+
|
|
119
|
+
const content = map.core.verified.newContentSince(knownState);
|
|
120
|
+
assert(content);
|
|
121
|
+
const lastChunk = content.pop();
|
|
122
|
+
assert(lastChunk);
|
|
123
|
+
|
|
124
|
+
const mapInNewSession = await loadCoValueOrFail(newSession.node, map.id);
|
|
125
|
+
|
|
126
|
+
for (const chunk of content) {
|
|
127
|
+
newSession.node.syncManager.handleNewContent(chunk, "import");
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
expect(mapInNewSession.core.isStreaming()).toBe(true);
|
|
131
|
+
|
|
132
|
+
newSession.node.syncManager.handleNewContent(lastChunk, "import");
|
|
133
|
+
|
|
134
|
+
expect(mapInNewSession.core.isStreaming()).toBe(false);
|
|
135
|
+
});
|
|
136
|
+
|
|
137
|
+
test("streaming a large value between two clients should be streaming until all chunks are sent", async () => {
|
|
138
|
+
const client = setupTestNode();
|
|
139
|
+
client.connectToSyncServer({
|
|
140
|
+
ourName: "initialClient",
|
|
141
|
+
});
|
|
142
|
+
const streamingClient = client.spawnNewSession();
|
|
143
|
+
streamingClient.connectToSyncServer({
|
|
144
|
+
ourName: "streamingClient",
|
|
145
|
+
});
|
|
146
|
+
|
|
147
|
+
const group = client.node.createGroup();
|
|
148
|
+
|
|
149
|
+
await group.core.waitForSync();
|
|
150
|
+
client.disconnect();
|
|
151
|
+
|
|
152
|
+
const map = group.createMap();
|
|
153
|
+
|
|
154
|
+
// Generate a large amount of data that requires multiple chunks
|
|
155
|
+
const dataSize = 1 * 1024 * 100;
|
|
156
|
+
const chunkSize = 1024; // 1KB chunks
|
|
157
|
+
const chunks = dataSize / chunkSize;
|
|
158
|
+
|
|
159
|
+
const value = Buffer.alloc(chunkSize, `value$`).toString("base64");
|
|
160
|
+
|
|
161
|
+
for (let i = 0; i < chunks; i++) {
|
|
162
|
+
const key = `key${i}`;
|
|
163
|
+
map.set(key, value, "trusting");
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
const loadingClient = client.spawnNewSession();
|
|
167
|
+
loadingClient.connectToSyncServer({
|
|
168
|
+
ourName: "loadingClient",
|
|
169
|
+
});
|
|
170
|
+
|
|
171
|
+
await loadCoValueOrFail(loadingClient.node, group.id);
|
|
172
|
+
|
|
173
|
+
const content = map.core.verified.newContentSince(undefined);
|
|
174
|
+
assert(content);
|
|
175
|
+
const lastChunk = content.pop();
|
|
176
|
+
assert(lastChunk);
|
|
177
|
+
|
|
178
|
+
for (const chunk of content) {
|
|
179
|
+
streamingClient.node.syncManager.handleNewContent(chunk, "import");
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
await streamingClient.node.syncManager.waitForAllCoValuesSync();
|
|
183
|
+
|
|
184
|
+
const mapInLoadingClient = await loadCoValueOrFail(
|
|
185
|
+
loadingClient.node,
|
|
186
|
+
map.id,
|
|
187
|
+
);
|
|
188
|
+
|
|
189
|
+
expect(mapInLoadingClient.core.isStreaming()).toBe(true);
|
|
190
|
+
|
|
191
|
+
streamingClient.node.syncManager.handleNewContent(lastChunk, "import");
|
|
192
|
+
|
|
193
|
+
await waitFor(() => {
|
|
194
|
+
expect(mapInLoadingClient.core.knownState()).toEqual(
|
|
195
|
+
map.core.knownState(),
|
|
196
|
+
);
|
|
197
|
+
});
|
|
198
|
+
|
|
199
|
+
expect(mapInLoadingClient.core.isStreaming()).toBe(false);
|
|
200
|
+
});
|
|
201
|
+
|
|
202
|
+
test("should be false when getting streaming content that is already in the known state", async () => {
|
|
203
|
+
const client = setupTestNode({
|
|
204
|
+
connected: true,
|
|
205
|
+
});
|
|
206
|
+
|
|
207
|
+
const group = client.node.createGroup();
|
|
208
|
+
|
|
209
|
+
await group.core.waitForSync();
|
|
210
|
+
|
|
211
|
+
const map = group.createMap();
|
|
212
|
+
|
|
213
|
+
// Generate a large amount of data that requires multiple chunks
|
|
214
|
+
const dataSize = 1 * 1024 * 100;
|
|
215
|
+
const chunkSize = 1024; // 1KB chunks
|
|
216
|
+
const chunks = dataSize / chunkSize;
|
|
217
|
+
|
|
218
|
+
const value = Buffer.alloc(chunkSize, `value$`).toString("base64");
|
|
219
|
+
|
|
220
|
+
for (let i = 0; i < chunks; i++) {
|
|
221
|
+
const key = `key${i}`;
|
|
222
|
+
map.set(key, value, "trusting");
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
await map.core.waitForSync();
|
|
226
|
+
const newSession = client.spawnNewSession();
|
|
227
|
+
|
|
228
|
+
const mapInNewSession1 = await loadCoValueOrFail(newSession.node, map.id);
|
|
229
|
+
await mapInNewSession1.core.waitForFullStreaming();
|
|
230
|
+
|
|
231
|
+
const content = map.core.verified.newContentSince(undefined);
|
|
232
|
+
assert(content);
|
|
233
|
+
const lastChunk = content.pop();
|
|
234
|
+
assert(lastChunk);
|
|
235
|
+
|
|
236
|
+
for (const chunk of content) {
|
|
237
|
+
newSession.node.syncManager.handleNewContent(chunk, "import");
|
|
238
|
+
}
|
|
239
|
+
|
|
240
|
+
const mapInNewSession = await loadCoValueOrFail(newSession.node, map.id);
|
|
241
|
+
|
|
242
|
+
expect(mapInNewSession.core.isStreaming()).toBe(false);
|
|
243
|
+
});
|
|
244
|
+
|
|
245
|
+
test("should be false when getting streaming content that's not really streaming", async () => {
|
|
246
|
+
const client = setupTestNode({
|
|
247
|
+
connected: true,
|
|
248
|
+
});
|
|
249
|
+
|
|
250
|
+
const group = client.node.createGroup();
|
|
251
|
+
|
|
252
|
+
await group.core.waitForSync();
|
|
253
|
+
client.disconnect();
|
|
254
|
+
|
|
255
|
+
const map = group.createMap();
|
|
256
|
+
map.set("hello", "world", "trusting");
|
|
257
|
+
|
|
258
|
+
const newSession = client.spawnNewSession();
|
|
259
|
+
|
|
260
|
+
await loadCoValueOrFail(client.node, group.id);
|
|
261
|
+
|
|
262
|
+
const content = map.core.verified.newContentSince(undefined);
|
|
263
|
+
assert(content);
|
|
264
|
+
|
|
265
|
+
content[0]!.expectContentUntil = map.core.knownState().sessions;
|
|
266
|
+
|
|
267
|
+
for (const chunk of content) {
|
|
268
|
+
newSession.node.syncManager.handleNewContent(chunk, "import");
|
|
269
|
+
}
|
|
270
|
+
|
|
271
|
+
const mapInNewSession = await loadCoValueOrFail(newSession.node, map.id);
|
|
272
|
+
|
|
273
|
+
expect(mapInNewSession.core.isStreaming()).toBe(false);
|
|
274
|
+
});
|
|
275
|
+
|
|
276
|
+
test("mixed updates should not leave isStreaming to true (3 sessions)", async () => {
|
|
277
|
+
const aliceLaptop = await setupTestAccount({
|
|
278
|
+
connected: true,
|
|
279
|
+
});
|
|
280
|
+
|
|
281
|
+
const group = aliceLaptop.node.createGroup();
|
|
282
|
+
const map = group.createMap();
|
|
283
|
+
|
|
284
|
+
map.set("count", 0, "trusting");
|
|
285
|
+
map.set("count", 1, "trusting");
|
|
286
|
+
|
|
287
|
+
await map.core.waitForSync();
|
|
288
|
+
|
|
289
|
+
const alicePhone = await aliceLaptop.spawnNewSession();
|
|
290
|
+
|
|
291
|
+
const mapOnPhone = await loadCoValueOrFail(alicePhone.node, map.id);
|
|
292
|
+
|
|
293
|
+
mapOnPhone.set("count", 2, "trusting");
|
|
294
|
+
mapOnPhone.set("count", 3, "trusting");
|
|
295
|
+
mapOnPhone.set("count", 4, "trusting");
|
|
296
|
+
|
|
297
|
+
await mapOnPhone.core.waitForSync();
|
|
298
|
+
|
|
299
|
+
const aliceTablet = await alicePhone.spawnNewSession();
|
|
300
|
+
const mapOnTablet = await loadCoValueOrFail(aliceTablet.node, map.id);
|
|
301
|
+
|
|
302
|
+
mapOnTablet.set("count", 5, "trusting");
|
|
303
|
+
mapOnTablet.set("count", 6, "trusting");
|
|
304
|
+
mapOnTablet.set("count", 7, "trusting");
|
|
305
|
+
|
|
306
|
+
await mapOnTablet.core.waitForSync();
|
|
307
|
+
|
|
308
|
+
map.set("count", 8, "trusting");
|
|
309
|
+
map.set("count", 9, "trusting");
|
|
310
|
+
map.set("count", 10, "trusting");
|
|
311
|
+
|
|
312
|
+
mapOnPhone.set("count", 11, "trusting");
|
|
313
|
+
mapOnTablet.set("count", 12, "trusting");
|
|
314
|
+
|
|
315
|
+
await map.core.waitForSync();
|
|
316
|
+
await mapOnPhone.core.waitForSync();
|
|
317
|
+
await mapOnTablet.core.waitForSync();
|
|
318
|
+
|
|
319
|
+
expect(map.core.isStreaming()).toBe(false);
|
|
320
|
+
expect(mapOnPhone.core.isStreaming()).toBe(false);
|
|
321
|
+
expect(mapOnTablet.core.isStreaming()).toBe(false);
|
|
322
|
+
|
|
323
|
+
const mapBranch = map.core.createBranch("test-branch");
|
|
324
|
+
|
|
325
|
+
const aliceTv = await aliceTablet.spawnNewSession();
|
|
326
|
+
|
|
327
|
+
const mapBranchOnTv = await loadCoValueOrFail(
|
|
328
|
+
aliceTv.node,
|
|
329
|
+
mapBranch.id as unknown as CoID<RawCoMap>,
|
|
330
|
+
);
|
|
331
|
+
|
|
332
|
+
mapBranchOnTv.set("count", 13, "trusting");
|
|
333
|
+
mapBranchOnTv.set("count", 14, "trusting");
|
|
334
|
+
mapBranchOnTv.set("count", 15, "trusting");
|
|
335
|
+
|
|
336
|
+
await mapBranchOnTv.core.waitForSync();
|
|
337
|
+
|
|
338
|
+
group.addMember("everyone", "reader");
|
|
339
|
+
|
|
340
|
+
const bob = await setupTestAccount({
|
|
341
|
+
connected: true,
|
|
342
|
+
});
|
|
343
|
+
|
|
344
|
+
const mapBranchOnBob = await loadCoValueOrFail(bob.node, mapBranchOnTv.id);
|
|
345
|
+
|
|
346
|
+
expect(mapBranchOnBob.core.isStreaming()).toBe(false);
|
|
347
|
+
expect(map.core.isStreaming()).toBe(false);
|
|
348
|
+
expect(mapOnPhone.core.isStreaming()).toBe(false);
|
|
349
|
+
expect(mapOnTablet.core.isStreaming()).toBe(false);
|
|
350
|
+
|
|
351
|
+
expect(mapBranchOnBob.get("count")).toBe(15);
|
|
352
|
+
});
|
|
353
|
+
});
|