cojson 0.13.16 → 0.13.17
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 +7 -0
- package/dist/coValue.d.ts +2 -0
- package/dist/coValue.d.ts.map +1 -1
- package/dist/coValue.js +1 -0
- package/dist/coValue.js.map +1 -1
- package/dist/coValueCore.d.ts +1 -0
- package/dist/coValueCore.d.ts.map +1 -1
- package/dist/coValueCore.js.map +1 -1
- package/dist/coValueState.d.ts.map +1 -1
- package/dist/coValueState.js +58 -96
- package/dist/coValueState.js.map +1 -1
- package/dist/coValues/coList.d.ts +7 -3
- package/dist/coValues/coList.d.ts.map +1 -1
- package/dist/coValues/coList.js +35 -12
- package/dist/coValues/coList.js.map +1 -1
- package/dist/coValues/coMap.d.ts +1 -0
- package/dist/coValues/coMap.d.ts.map +1 -1
- package/dist/coValues/coMap.js +2 -0
- package/dist/coValues/coMap.js.map +1 -1
- package/dist/coValues/coPlainText.d.ts.map +1 -1
- package/dist/coValues/coPlainText.js +1 -1
- package/dist/coValues/coPlainText.js.map +1 -1
- package/dist/coValues/coStream.d.ts +2 -1
- package/dist/coValues/coStream.d.ts.map +1 -1
- package/dist/coValues/coStream.js +2 -0
- package/dist/coValues/coStream.js.map +1 -1
- package/dist/coreToCoValue.d.ts +2 -1
- package/dist/coreToCoValue.d.ts.map +1 -1
- package/dist/localNode.d.ts.map +1 -1
- package/dist/localNode.js +21 -14
- package/dist/localNode.js.map +1 -1
- package/dist/tests/coList.test.js +119 -2
- package/dist/tests/coList.test.js.map +1 -1
- package/dist/tests/coMap.test.js +32 -2
- package/dist/tests/coMap.test.js.map +1 -1
- package/dist/tests/coStream.test.js +28 -2
- package/dist/tests/coStream.test.js.map +1 -1
- package/dist/tests/coValueState.test.js +10 -143
- package/dist/tests/coValueState.test.js.map +1 -1
- package/dist/tests/sync.load.test.js +59 -1
- package/dist/tests/sync.load.test.js.map +1 -1
- package/dist/tests/sync.mesh.test.js +48 -1
- package/dist/tests/sync.mesh.test.js.map +1 -1
- package/package.json +1 -1
- package/src/coValue.ts +3 -0
- package/src/coValueCore.ts +1 -0
- package/src/coValueState.ts +67 -122
- package/src/coValues/coList.ts +51 -23
- package/src/coValues/coMap.ts +4 -0
- package/src/coValues/coPlainText.ts +1 -2
- package/src/coValues/coStream.ts +3 -1
- package/src/localNode.ts +29 -18
- package/src/tests/coList.test.ts +184 -2
- package/src/tests/coMap.test.ts +54 -2
- package/src/tests/coStream.test.ts +56 -2
- package/src/tests/coValueState.test.ts +9 -207
- package/src/tests/sync.load.test.ts +78 -1
- package/src/tests/sync.mesh.test.ts +67 -0
package/src/tests/coList.test.ts
CHANGED
|
@@ -1,11 +1,20 @@
|
|
|
1
|
-
import { expect, test } from "vitest";
|
|
1
|
+
import { beforeEach, expect, test } from "vitest";
|
|
2
2
|
import { expectList } from "../coValue.js";
|
|
3
3
|
import { WasmCrypto } from "../crypto/WasmCrypto.js";
|
|
4
4
|
import { LocalNode } from "../localNode.js";
|
|
5
|
-
import {
|
|
5
|
+
import {
|
|
6
|
+
loadCoValueOrFail,
|
|
7
|
+
randomAnonymousAccountAndSessionID,
|
|
8
|
+
setupTestNode,
|
|
9
|
+
waitFor,
|
|
10
|
+
} from "./testUtils.js";
|
|
6
11
|
|
|
7
12
|
const Crypto = await WasmCrypto.create();
|
|
8
13
|
|
|
14
|
+
beforeEach(async () => {
|
|
15
|
+
setupTestNode({ isSyncServer: true });
|
|
16
|
+
});
|
|
17
|
+
|
|
9
18
|
test("Empty CoList works", () => {
|
|
10
19
|
const node = new LocalNode(...randomAnonymousAccountAndSessionID(), Crypto);
|
|
11
20
|
|
|
@@ -221,3 +230,176 @@ test("Items prepended to start appear with latest first", () => {
|
|
|
221
230
|
|
|
222
231
|
expect(content.toJSON()).toEqual(["third", "second", "first"]);
|
|
223
232
|
});
|
|
233
|
+
|
|
234
|
+
test("mixing prepend and append", () => {
|
|
235
|
+
const node = new LocalNode(...randomAnonymousAccountAndSessionID(), Crypto);
|
|
236
|
+
|
|
237
|
+
const coValue = node.createCoValue({
|
|
238
|
+
type: "colist",
|
|
239
|
+
ruleset: { type: "unsafeAllowAll" },
|
|
240
|
+
meta: null,
|
|
241
|
+
...Crypto.createdNowUnique(),
|
|
242
|
+
});
|
|
243
|
+
|
|
244
|
+
const list = expectList(coValue.getCurrentContent());
|
|
245
|
+
|
|
246
|
+
list.append(2, undefined, "trusting");
|
|
247
|
+
list.prepend(1, undefined, "trusting");
|
|
248
|
+
list.append(3, undefined, "trusting");
|
|
249
|
+
|
|
250
|
+
expect(list.toJSON()).toEqual([1, 2, 3]);
|
|
251
|
+
});
|
|
252
|
+
|
|
253
|
+
test("Items appended to start", () => {
|
|
254
|
+
const node = new LocalNode(...randomAnonymousAccountAndSessionID(), Crypto);
|
|
255
|
+
|
|
256
|
+
const coValue = node.createCoValue({
|
|
257
|
+
type: "colist",
|
|
258
|
+
ruleset: { type: "unsafeAllowAll" },
|
|
259
|
+
meta: null,
|
|
260
|
+
...Crypto.createdNowUnique(),
|
|
261
|
+
});
|
|
262
|
+
|
|
263
|
+
const content = expectList(coValue.getCurrentContent());
|
|
264
|
+
|
|
265
|
+
content.append("first", 0, "trusting");
|
|
266
|
+
content.append("second", 0, "trusting");
|
|
267
|
+
content.append("third", 0, "trusting");
|
|
268
|
+
|
|
269
|
+
// This result is correct because "third" is appended after "first"
|
|
270
|
+
// Using the Array methods this would be the same as doing content.splice(1, 0, "third")
|
|
271
|
+
expect(content.toJSON()).toEqual(["first", "third", "second"]);
|
|
272
|
+
});
|
|
273
|
+
|
|
274
|
+
test("syncing appends with an older timestamp", async () => {
|
|
275
|
+
const client = setupTestNode({
|
|
276
|
+
connected: true,
|
|
277
|
+
});
|
|
278
|
+
const otherClient = setupTestNode({});
|
|
279
|
+
|
|
280
|
+
const otherClientConnection = otherClient.connectToSyncServer();
|
|
281
|
+
|
|
282
|
+
const coValue = client.node.createCoValue({
|
|
283
|
+
type: "colist",
|
|
284
|
+
ruleset: { type: "unsafeAllowAll" },
|
|
285
|
+
meta: null,
|
|
286
|
+
...Crypto.createdNowUnique(),
|
|
287
|
+
});
|
|
288
|
+
|
|
289
|
+
const list = expectList(coValue.getCurrentContent());
|
|
290
|
+
|
|
291
|
+
list.append(1, undefined, "trusting");
|
|
292
|
+
list.append(2, undefined, "trusting");
|
|
293
|
+
|
|
294
|
+
const listOnOtherClient = await loadCoValueOrFail(otherClient.node, list.id);
|
|
295
|
+
|
|
296
|
+
otherClientConnection.peerState.gracefulShutdown();
|
|
297
|
+
|
|
298
|
+
listOnOtherClient.append(3, undefined, "trusting");
|
|
299
|
+
|
|
300
|
+
await new Promise((resolve) => setTimeout(resolve, 50));
|
|
301
|
+
|
|
302
|
+
list.append(4, undefined, "trusting");
|
|
303
|
+
|
|
304
|
+
await new Promise((resolve) => setTimeout(resolve, 50));
|
|
305
|
+
|
|
306
|
+
listOnOtherClient.append(5, undefined, "trusting");
|
|
307
|
+
|
|
308
|
+
await new Promise((resolve) => setTimeout(resolve, 50));
|
|
309
|
+
|
|
310
|
+
list.append(6, undefined, "trusting");
|
|
311
|
+
|
|
312
|
+
otherClient.connectToSyncServer();
|
|
313
|
+
|
|
314
|
+
await waitFor(() => {
|
|
315
|
+
expect(list.toJSON()).toEqual([1, 2, 4, 6, 3, 5]);
|
|
316
|
+
});
|
|
317
|
+
|
|
318
|
+
expect(listOnOtherClient.toJSON()).toEqual(list.toJSON());
|
|
319
|
+
});
|
|
320
|
+
|
|
321
|
+
test("syncing prepends with an older timestamp", async () => {
|
|
322
|
+
const client = setupTestNode({
|
|
323
|
+
connected: true,
|
|
324
|
+
});
|
|
325
|
+
const otherClient = setupTestNode({});
|
|
326
|
+
|
|
327
|
+
const otherClientConnection = otherClient.connectToSyncServer();
|
|
328
|
+
|
|
329
|
+
const coValue = client.node.createCoValue({
|
|
330
|
+
type: "colist",
|
|
331
|
+
ruleset: { type: "unsafeAllowAll" },
|
|
332
|
+
meta: null,
|
|
333
|
+
...Crypto.createdNowUnique(),
|
|
334
|
+
});
|
|
335
|
+
|
|
336
|
+
const list = expectList(coValue.getCurrentContent());
|
|
337
|
+
|
|
338
|
+
list.prepend(1, undefined, "trusting");
|
|
339
|
+
list.prepend(2, undefined, "trusting");
|
|
340
|
+
|
|
341
|
+
const listOnOtherClient = await loadCoValueOrFail(otherClient.node, list.id);
|
|
342
|
+
|
|
343
|
+
otherClientConnection.peerState.gracefulShutdown();
|
|
344
|
+
|
|
345
|
+
listOnOtherClient.prepend(3, undefined, "trusting");
|
|
346
|
+
|
|
347
|
+
await new Promise((resolve) => setTimeout(resolve, 50));
|
|
348
|
+
|
|
349
|
+
list.prepend(4, undefined, "trusting");
|
|
350
|
+
|
|
351
|
+
await new Promise((resolve) => setTimeout(resolve, 50));
|
|
352
|
+
|
|
353
|
+
listOnOtherClient.prepend(5, undefined, "trusting");
|
|
354
|
+
|
|
355
|
+
await new Promise((resolve) => setTimeout(resolve, 50));
|
|
356
|
+
|
|
357
|
+
list.prepend(6, undefined, "trusting");
|
|
358
|
+
|
|
359
|
+
otherClient.connectToSyncServer();
|
|
360
|
+
|
|
361
|
+
await waitFor(() => {
|
|
362
|
+
expect(list.toJSON()).toEqual([6, 4, 5, 3, 2, 1]);
|
|
363
|
+
});
|
|
364
|
+
|
|
365
|
+
expect(listOnOtherClient.toJSON()).toEqual(list.toJSON());
|
|
366
|
+
});
|
|
367
|
+
|
|
368
|
+
test("totalValidTransactions should return the number of valid transactions processed", async () => {
|
|
369
|
+
const client = setupTestNode({
|
|
370
|
+
connected: true,
|
|
371
|
+
});
|
|
372
|
+
const otherClient = setupTestNode({});
|
|
373
|
+
|
|
374
|
+
const otherClientConnection = otherClient.connectToSyncServer();
|
|
375
|
+
|
|
376
|
+
const group = client.node.createGroup();
|
|
377
|
+
group.addMember("everyone", "reader");
|
|
378
|
+
|
|
379
|
+
const list = group.createList([1, 2]);
|
|
380
|
+
|
|
381
|
+
const listOnOtherClient = await loadCoValueOrFail(otherClient.node, list.id);
|
|
382
|
+
|
|
383
|
+
otherClientConnection.peerState.gracefulShutdown();
|
|
384
|
+
|
|
385
|
+
group.addMember("everyone", "writer");
|
|
386
|
+
|
|
387
|
+
await new Promise((resolve) => setTimeout(resolve, 50));
|
|
388
|
+
|
|
389
|
+
listOnOtherClient.append(3, undefined, "trusting");
|
|
390
|
+
|
|
391
|
+
expect(listOnOtherClient.toJSON()).toEqual([1, 2]);
|
|
392
|
+
expect(listOnOtherClient.totalValidTransactions).toEqual(1);
|
|
393
|
+
|
|
394
|
+
otherClient.connectToSyncServer();
|
|
395
|
+
|
|
396
|
+
await waitFor(() => {
|
|
397
|
+
expect(listOnOtherClient.core.getCurrentContent().toJSON()).toEqual([
|
|
398
|
+
1, 2, 3,
|
|
399
|
+
]);
|
|
400
|
+
});
|
|
401
|
+
|
|
402
|
+
expect(
|
|
403
|
+
listOnOtherClient.core.getCurrentContent().totalValidTransactions,
|
|
404
|
+
).toEqual(2);
|
|
405
|
+
});
|
package/src/tests/coMap.test.ts
CHANGED
|
@@ -1,13 +1,23 @@
|
|
|
1
|
-
import { expect, test } from "vitest";
|
|
1
|
+
import { beforeEach, expect, test } from "vitest";
|
|
2
2
|
import { expectMap } from "../coValue.js";
|
|
3
3
|
import { operationToEditEntry } from "../coValues/coMap.js";
|
|
4
4
|
import { WasmCrypto } from "../crypto/WasmCrypto.js";
|
|
5
5
|
import { LocalNode } from "../localNode.js";
|
|
6
6
|
import { accountOrAgentIDfromSessionID } from "../typeUtils/accountOrAgentIDfromSessionID.js";
|
|
7
|
-
import {
|
|
7
|
+
import {
|
|
8
|
+
hotSleep,
|
|
9
|
+
loadCoValueOrFail,
|
|
10
|
+
randomAnonymousAccountAndSessionID,
|
|
11
|
+
setupTestNode,
|
|
12
|
+
waitFor,
|
|
13
|
+
} from "./testUtils.js";
|
|
8
14
|
|
|
9
15
|
const Crypto = await WasmCrypto.create();
|
|
10
16
|
|
|
17
|
+
beforeEach(async () => {
|
|
18
|
+
setupTestNode({ isSyncServer: true });
|
|
19
|
+
});
|
|
20
|
+
|
|
11
21
|
test("Empty CoMap works", () => {
|
|
12
22
|
const node = new LocalNode(...randomAnonymousAccountAndSessionID(), Crypto);
|
|
13
23
|
|
|
@@ -207,3 +217,45 @@ test("Can set items in bulk with assign", () => {
|
|
|
207
217
|
key3: "assign3",
|
|
208
218
|
});
|
|
209
219
|
});
|
|
220
|
+
|
|
221
|
+
test("totalValidTransactions should return the number of valid transactions processed", async () => {
|
|
222
|
+
const client = setupTestNode({
|
|
223
|
+
connected: true,
|
|
224
|
+
});
|
|
225
|
+
const otherClient = setupTestNode({});
|
|
226
|
+
|
|
227
|
+
const otherClientConnection = otherClient.connectToSyncServer();
|
|
228
|
+
|
|
229
|
+
const group = client.node.createGroup();
|
|
230
|
+
group.addMember("everyone", "reader");
|
|
231
|
+
|
|
232
|
+
const map = group.createMap({ fromClient: true });
|
|
233
|
+
|
|
234
|
+
const mapOnOtherClient = await loadCoValueOrFail(otherClient.node, map.id);
|
|
235
|
+
|
|
236
|
+
otherClientConnection.peerState.gracefulShutdown();
|
|
237
|
+
|
|
238
|
+
group.addMember("everyone", "writer");
|
|
239
|
+
|
|
240
|
+
await new Promise((resolve) => setTimeout(resolve, 50));
|
|
241
|
+
|
|
242
|
+
mapOnOtherClient.set("fromOtherClient", true, "trusting");
|
|
243
|
+
|
|
244
|
+
expect(mapOnOtherClient.totalValidTransactions).toEqual(1);
|
|
245
|
+
expect(mapOnOtherClient.toJSON()).toEqual({
|
|
246
|
+
fromClient: true,
|
|
247
|
+
});
|
|
248
|
+
|
|
249
|
+
otherClient.connectToSyncServer();
|
|
250
|
+
|
|
251
|
+
await waitFor(() => {
|
|
252
|
+
expect(mapOnOtherClient.core.getCurrentContent().toJSON()).toEqual({
|
|
253
|
+
fromClient: true,
|
|
254
|
+
fromOtherClient: true,
|
|
255
|
+
});
|
|
256
|
+
});
|
|
257
|
+
|
|
258
|
+
expect(
|
|
259
|
+
mapOnOtherClient.core.getCurrentContent().totalValidTransactions,
|
|
260
|
+
).toEqual(2);
|
|
261
|
+
});
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { describe, expect, test } from "vitest";
|
|
1
|
+
import { beforeEach, describe, expect, test } from "vitest";
|
|
2
2
|
import { expectStream } from "../coValue.js";
|
|
3
3
|
import { MAX_RECOMMENDED_TX_SIZE } from "../coValueCore.js";
|
|
4
4
|
import {
|
|
@@ -10,10 +10,19 @@ import {
|
|
|
10
10
|
import { WasmCrypto } from "../crypto/WasmCrypto.js";
|
|
11
11
|
import { SessionID } from "../ids.js";
|
|
12
12
|
import { LocalNode } from "../localNode.js";
|
|
13
|
-
import {
|
|
13
|
+
import {
|
|
14
|
+
loadCoValueOrFail,
|
|
15
|
+
randomAnonymousAccountAndSessionID,
|
|
16
|
+
setupTestNode,
|
|
17
|
+
waitFor,
|
|
18
|
+
} from "./testUtils.js";
|
|
14
19
|
|
|
15
20
|
const Crypto = await WasmCrypto.create();
|
|
16
21
|
|
|
22
|
+
beforeEach(async () => {
|
|
23
|
+
setupTestNode({ isSyncServer: true });
|
|
24
|
+
});
|
|
25
|
+
|
|
17
26
|
test("Empty CoStream works", () => {
|
|
18
27
|
const node = new LocalNode(...randomAnonymousAccountAndSessionID(), Crypto);
|
|
19
28
|
|
|
@@ -252,6 +261,51 @@ test("When adding large transactions (bigger than MAX_RECOMMENDED_TX_SIZE), we s
|
|
|
252
261
|
);
|
|
253
262
|
});
|
|
254
263
|
|
|
264
|
+
test("totalValidTransactions should return the number of valid transactions processed", async () => {
|
|
265
|
+
const client = setupTestNode({
|
|
266
|
+
connected: true,
|
|
267
|
+
});
|
|
268
|
+
const otherClient = setupTestNode({});
|
|
269
|
+
|
|
270
|
+
const otherClientConnection = otherClient.connectToSyncServer();
|
|
271
|
+
|
|
272
|
+
const group = client.node.createGroup();
|
|
273
|
+
group.addMember("everyone", "reader");
|
|
274
|
+
|
|
275
|
+
const stream = group.createStream();
|
|
276
|
+
stream.push(1, "trusting");
|
|
277
|
+
|
|
278
|
+
const streamOnOtherClient = await loadCoValueOrFail(
|
|
279
|
+
otherClient.node,
|
|
280
|
+
stream.id,
|
|
281
|
+
);
|
|
282
|
+
|
|
283
|
+
otherClientConnection.peerState.gracefulShutdown();
|
|
284
|
+
|
|
285
|
+
group.addMember("everyone", "writer");
|
|
286
|
+
|
|
287
|
+
await new Promise((resolve) => setTimeout(resolve, 50));
|
|
288
|
+
|
|
289
|
+
streamOnOtherClient.push(2, "trusting");
|
|
290
|
+
|
|
291
|
+
expect(streamOnOtherClient.totalValidTransactions).toEqual(1);
|
|
292
|
+
expect(Object.keys(streamOnOtherClient.toJSON()).length).toEqual(1);
|
|
293
|
+
|
|
294
|
+
otherClient.connectToSyncServer();
|
|
295
|
+
|
|
296
|
+
await waitFor(() => {
|
|
297
|
+
expect(
|
|
298
|
+
Object.keys(
|
|
299
|
+
streamOnOtherClient.core.getCurrentContent().toJSON() as object,
|
|
300
|
+
).length,
|
|
301
|
+
).toEqual(2);
|
|
302
|
+
});
|
|
303
|
+
|
|
304
|
+
expect(
|
|
305
|
+
streamOnOtherClient.core.getCurrentContent().totalValidTransactions,
|
|
306
|
+
).toEqual(2);
|
|
307
|
+
});
|
|
308
|
+
|
|
255
309
|
describe("isBinaryStreamEnded", () => {
|
|
256
310
|
function setup() {
|
|
257
311
|
const node = new LocalNode(...randomAnonymousAccountAndSessionID(), Crypto);
|
|
@@ -10,26 +10,15 @@ import {
|
|
|
10
10
|
} from "vitest";
|
|
11
11
|
import { PeerState } from "../PeerState";
|
|
12
12
|
import { CoValueCore } from "../coValueCore";
|
|
13
|
-
import {
|
|
13
|
+
import { CoValueState } from "../coValueState";
|
|
14
14
|
import { RawCoID } from "../ids";
|
|
15
15
|
import { Peer } from "../sync";
|
|
16
16
|
import { createTestMetricReader, tearDownTestMetricReader } from "./testUtils";
|
|
17
17
|
|
|
18
|
-
const initialMaxRetries = CO_VALUE_LOADING_CONFIG.MAX_RETRIES;
|
|
19
|
-
|
|
20
|
-
function mockMaxRetries(maxRetries: number) {
|
|
21
|
-
CO_VALUE_LOADING_CONFIG.MAX_RETRIES = maxRetries;
|
|
22
|
-
|
|
23
|
-
onTestFinished(() => {
|
|
24
|
-
CO_VALUE_LOADING_CONFIG.MAX_RETRIES = initialMaxRetries;
|
|
25
|
-
});
|
|
26
|
-
}
|
|
27
|
-
|
|
28
18
|
let metricReader: ReturnType<typeof createTestMetricReader>;
|
|
29
19
|
|
|
30
20
|
beforeEach(() => {
|
|
31
21
|
metricReader = createTestMetricReader();
|
|
32
|
-
mockMaxRetries(5);
|
|
33
22
|
});
|
|
34
23
|
|
|
35
24
|
afterEach(() => {
|
|
@@ -122,51 +111,6 @@ describe("CoValueState", () => {
|
|
|
122
111
|
).toBe(0);
|
|
123
112
|
});
|
|
124
113
|
|
|
125
|
-
test("should retry loading from peers when unsuccessful", async () => {
|
|
126
|
-
vi.useFakeTimers();
|
|
127
|
-
|
|
128
|
-
const peer1 = createMockPeerState(
|
|
129
|
-
{
|
|
130
|
-
id: "peer1",
|
|
131
|
-
role: "server",
|
|
132
|
-
},
|
|
133
|
-
async () => {
|
|
134
|
-
state.markNotFoundInPeer("peer1");
|
|
135
|
-
},
|
|
136
|
-
);
|
|
137
|
-
const peer2 = createMockPeerState(
|
|
138
|
-
{
|
|
139
|
-
id: "peer2",
|
|
140
|
-
role: "server",
|
|
141
|
-
},
|
|
142
|
-
async () => {
|
|
143
|
-
state.markNotFoundInPeer("peer2");
|
|
144
|
-
},
|
|
145
|
-
);
|
|
146
|
-
const mockPeers = [peer1, peer2] as unknown as PeerState[];
|
|
147
|
-
|
|
148
|
-
const state = new CoValueState(mockCoValueId);
|
|
149
|
-
const loadPromise = state.loadFromPeers(mockPeers);
|
|
150
|
-
|
|
151
|
-
// Should attempt CO_VALUE_LOADING_CONFIG.MAX_RETRIES retries
|
|
152
|
-
for (let i = 0; i < CO_VALUE_LOADING_CONFIG.MAX_RETRIES; i++) {
|
|
153
|
-
await vi.runAllTimersAsync();
|
|
154
|
-
}
|
|
155
|
-
|
|
156
|
-
await loadPromise;
|
|
157
|
-
|
|
158
|
-
expect(peer1.pushOutgoingMessage).toHaveBeenCalledTimes(
|
|
159
|
-
CO_VALUE_LOADING_CONFIG.MAX_RETRIES,
|
|
160
|
-
);
|
|
161
|
-
expect(peer2.pushOutgoingMessage).toHaveBeenCalledTimes(
|
|
162
|
-
CO_VALUE_LOADING_CONFIG.MAX_RETRIES,
|
|
163
|
-
);
|
|
164
|
-
expect(state.highLevelState).toBe("unavailable");
|
|
165
|
-
await expect(state.getCoValue()).resolves.toBe("unavailable");
|
|
166
|
-
|
|
167
|
-
vi.useRealTimers();
|
|
168
|
-
});
|
|
169
|
-
|
|
170
114
|
test("should skip errored coValues when loading from peers", async () => {
|
|
171
115
|
vi.useFakeTimers();
|
|
172
116
|
|
|
@@ -194,108 +138,18 @@ describe("CoValueState", () => {
|
|
|
194
138
|
const state = new CoValueState(mockCoValueId);
|
|
195
139
|
const loadPromise = state.loadFromPeers(mockPeers);
|
|
196
140
|
|
|
197
|
-
|
|
198
|
-
for (let i = 0; i < CO_VALUE_LOADING_CONFIG.MAX_RETRIES; i++) {
|
|
199
|
-
await vi.runAllTimersAsync();
|
|
200
|
-
}
|
|
141
|
+
await vi.runAllTimersAsync();
|
|
201
142
|
|
|
202
143
|
await loadPromise;
|
|
203
144
|
|
|
204
145
|
expect(peer1.pushOutgoingMessage).toHaveBeenCalledTimes(1);
|
|
205
|
-
expect(peer2.pushOutgoingMessage).toHaveBeenCalledTimes(
|
|
206
|
-
CO_VALUE_LOADING_CONFIG.MAX_RETRIES,
|
|
207
|
-
);
|
|
146
|
+
expect(peer2.pushOutgoingMessage).toHaveBeenCalledTimes(1);
|
|
208
147
|
expect(state.highLevelState).toBe("unavailable");
|
|
209
148
|
await expect(state.getCoValue()).resolves.toBe("unavailable");
|
|
210
149
|
|
|
211
150
|
vi.useRealTimers();
|
|
212
151
|
});
|
|
213
152
|
|
|
214
|
-
test("should retry only on server peers", async () => {
|
|
215
|
-
vi.useFakeTimers();
|
|
216
|
-
|
|
217
|
-
const peer1 = createMockPeerState(
|
|
218
|
-
{
|
|
219
|
-
id: "peer1",
|
|
220
|
-
role: "storage",
|
|
221
|
-
},
|
|
222
|
-
async () => {
|
|
223
|
-
state.markNotFoundInPeer("peer1");
|
|
224
|
-
},
|
|
225
|
-
);
|
|
226
|
-
const peer2 = createMockPeerState(
|
|
227
|
-
{
|
|
228
|
-
id: "peer2",
|
|
229
|
-
role: "server",
|
|
230
|
-
},
|
|
231
|
-
async () => {
|
|
232
|
-
state.markNotFoundInPeer("peer2");
|
|
233
|
-
},
|
|
234
|
-
);
|
|
235
|
-
const mockPeers = [peer1, peer2] as unknown as PeerState[];
|
|
236
|
-
|
|
237
|
-
const state = new CoValueState(mockCoValueId);
|
|
238
|
-
const loadPromise = state.loadFromPeers(mockPeers);
|
|
239
|
-
|
|
240
|
-
// Should attempt CO_VALUE_LOADING_CONFIG.MAX_RETRIES retries
|
|
241
|
-
for (let i = 0; i < CO_VALUE_LOADING_CONFIG.MAX_RETRIES; i++) {
|
|
242
|
-
await vi.runAllTimersAsync();
|
|
243
|
-
}
|
|
244
|
-
|
|
245
|
-
await loadPromise;
|
|
246
|
-
|
|
247
|
-
expect(peer1.pushOutgoingMessage).toHaveBeenCalledTimes(1);
|
|
248
|
-
expect(peer2.pushOutgoingMessage).toHaveBeenCalledTimes(
|
|
249
|
-
CO_VALUE_LOADING_CONFIG.MAX_RETRIES,
|
|
250
|
-
);
|
|
251
|
-
expect(state.highLevelState).toBe("unavailable");
|
|
252
|
-
await expect(state.getCoValue()).resolves.toEqual("unavailable");
|
|
253
|
-
|
|
254
|
-
vi.useRealTimers();
|
|
255
|
-
});
|
|
256
|
-
|
|
257
|
-
test("should handle the coValues that become available in between of the retries", async () => {
|
|
258
|
-
vi.useFakeTimers();
|
|
259
|
-
|
|
260
|
-
mockMaxRetries(5);
|
|
261
|
-
|
|
262
|
-
let retries = 0;
|
|
263
|
-
|
|
264
|
-
const peer1 = createMockPeerState(
|
|
265
|
-
{
|
|
266
|
-
id: "peer1",
|
|
267
|
-
role: "server",
|
|
268
|
-
},
|
|
269
|
-
async () => {
|
|
270
|
-
retries++;
|
|
271
|
-
state.markNotFoundInPeer("peer1");
|
|
272
|
-
|
|
273
|
-
if (retries === 2) {
|
|
274
|
-
setTimeout(() => {
|
|
275
|
-
state.markAvailable(createMockCoValueCore(mockCoValueId), "peer1");
|
|
276
|
-
}, 100);
|
|
277
|
-
}
|
|
278
|
-
},
|
|
279
|
-
);
|
|
280
|
-
|
|
281
|
-
const mockPeers = [peer1] as unknown as PeerState[];
|
|
282
|
-
|
|
283
|
-
const state = new CoValueState(mockCoValueId);
|
|
284
|
-
const loadPromise = state.loadFromPeers(mockPeers);
|
|
285
|
-
|
|
286
|
-
// Should attempt CO_VALUE_LOADING_CONFIG.MAX_RETRIES retries
|
|
287
|
-
for (let i = 0; i < CO_VALUE_LOADING_CONFIG.MAX_RETRIES + 1; i++) {
|
|
288
|
-
await vi.runAllTimersAsync();
|
|
289
|
-
}
|
|
290
|
-
|
|
291
|
-
await loadPromise;
|
|
292
|
-
|
|
293
|
-
expect(peer1.pushOutgoingMessage).toHaveBeenCalledTimes(2);
|
|
294
|
-
expect(state.highLevelState).toBe("available");
|
|
295
|
-
await expect(state.getCoValue()).resolves.toEqual({ id: mockCoValueId });
|
|
296
|
-
vi.useRealTimers();
|
|
297
|
-
});
|
|
298
|
-
|
|
299
153
|
test("should have a coValue as value property when becomes available after that have been marked as unavailable", async () => {
|
|
300
154
|
vi.useFakeTimers();
|
|
301
155
|
|
|
@@ -314,57 +168,13 @@ describe("CoValueState", () => {
|
|
|
314
168
|
const state = new CoValueState(mockCoValueId);
|
|
315
169
|
const loadPromise = state.loadFromPeers(mockPeers);
|
|
316
170
|
|
|
317
|
-
|
|
318
|
-
for (let i = 0; i < CO_VALUE_LOADING_CONFIG.MAX_RETRIES; i++) {
|
|
319
|
-
await vi.runAllTimersAsync();
|
|
320
|
-
}
|
|
171
|
+
await vi.runAllTimersAsync();
|
|
321
172
|
|
|
322
173
|
state.internalMarkMagicallyAvailable(createMockCoValueCore(mockCoValueId));
|
|
323
174
|
|
|
324
175
|
await loadPromise;
|
|
325
176
|
|
|
326
|
-
expect(peer1.pushOutgoingMessage).toHaveBeenCalledTimes(
|
|
327
|
-
CO_VALUE_LOADING_CONFIG.MAX_RETRIES,
|
|
328
|
-
);
|
|
329
|
-
expect(state.highLevelState).toBe("available");
|
|
330
|
-
await expect(state.getCoValue()).resolves.toEqual({ id: mockCoValueId });
|
|
331
|
-
|
|
332
|
-
vi.useRealTimers();
|
|
333
|
-
});
|
|
334
|
-
|
|
335
|
-
test("should stop retrying when value becomes available", async () => {
|
|
336
|
-
vi.useFakeTimers();
|
|
337
|
-
|
|
338
|
-
mockMaxRetries(5);
|
|
339
|
-
|
|
340
|
-
let run = 1;
|
|
341
|
-
|
|
342
|
-
const peer1 = createMockPeerState(
|
|
343
|
-
{
|
|
344
|
-
id: "peer1",
|
|
345
|
-
role: "server",
|
|
346
|
-
},
|
|
347
|
-
async () => {
|
|
348
|
-
if (run > 2) {
|
|
349
|
-
state.markAvailable(createMockCoValueCore(mockCoValueId), "peer1");
|
|
350
|
-
} else {
|
|
351
|
-
state.markNotFoundInPeer("peer1");
|
|
352
|
-
run++;
|
|
353
|
-
}
|
|
354
|
-
},
|
|
355
|
-
);
|
|
356
|
-
|
|
357
|
-
const mockPeers = [peer1] as unknown as PeerState[];
|
|
358
|
-
|
|
359
|
-
const state = new CoValueState(mockCoValueId);
|
|
360
|
-
const loadPromise = state.loadFromPeers(mockPeers);
|
|
361
|
-
|
|
362
|
-
for (let i = 0; i < CO_VALUE_LOADING_CONFIG.MAX_RETRIES; i++) {
|
|
363
|
-
await vi.runAllTimersAsync();
|
|
364
|
-
}
|
|
365
|
-
await loadPromise;
|
|
366
|
-
|
|
367
|
-
expect(peer1.pushOutgoingMessage).toHaveBeenCalledTimes(3);
|
|
177
|
+
expect(peer1.pushOutgoingMessage).toHaveBeenCalledTimes(1);
|
|
368
178
|
expect(state.highLevelState).toBe("available");
|
|
369
179
|
await expect(state.getCoValue()).resolves.toEqual({ id: mockCoValueId });
|
|
370
180
|
|
|
@@ -398,9 +208,7 @@ describe("CoValueState", () => {
|
|
|
398
208
|
const state = new CoValueState(mockCoValueId);
|
|
399
209
|
const loadPromise = state.loadFromPeers([peer1, peer2]);
|
|
400
210
|
|
|
401
|
-
|
|
402
|
-
await vi.runAllTimersAsync();
|
|
403
|
-
}
|
|
211
|
+
await vi.runAllTimersAsync();
|
|
404
212
|
await loadPromise;
|
|
405
213
|
|
|
406
214
|
expect(peer1.pushOutgoingMessage).toHaveBeenCalledTimes(1);
|
|
@@ -444,9 +252,7 @@ describe("CoValueState", () => {
|
|
|
444
252
|
const state = new CoValueState(mockCoValueId);
|
|
445
253
|
const loadPromise = state.loadFromPeers([peer1, peer2]);
|
|
446
254
|
|
|
447
|
-
|
|
448
|
-
await vi.runAllTimersAsync();
|
|
449
|
-
}
|
|
255
|
+
await vi.runAllTimersAsync();
|
|
450
256
|
await loadPromise;
|
|
451
257
|
|
|
452
258
|
expect(peer1.pushOutgoingMessage).toHaveBeenCalledTimes(0);
|
|
@@ -472,14 +278,10 @@ describe("CoValueState", () => {
|
|
|
472
278
|
const state = new CoValueState(mockCoValueId);
|
|
473
279
|
const loadPromise = state.loadFromPeers([peer1]);
|
|
474
280
|
|
|
475
|
-
|
|
476
|
-
await vi.runAllTimersAsync();
|
|
477
|
-
}
|
|
281
|
+
await vi.runAllTimersAsync();
|
|
478
282
|
await loadPromise;
|
|
479
283
|
|
|
480
|
-
expect(peer1.pushOutgoingMessage).toHaveBeenCalledTimes(
|
|
481
|
-
CO_VALUE_LOADING_CONFIG.MAX_RETRIES,
|
|
482
|
-
);
|
|
284
|
+
expect(peer1.pushOutgoingMessage).toHaveBeenCalledTimes(1);
|
|
483
285
|
|
|
484
286
|
expect(state.highLevelState).toBe("unavailable");
|
|
485
287
|
await expect(state.getCoValue()).resolves.toEqual("unavailable");
|