cojson 0.9.19 → 0.10.0

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.
@@ -2,7 +2,13 @@ import { CoID } from "./coValue.js";
2
2
  import { CoValueCore, Transaction } from "./coValueCore.js";
3
3
  import { RawAccount, RawAccountID, RawProfile } from "./coValues/account.js";
4
4
  import { MapOpPayload } from "./coValues/coMap.js";
5
- import { EVERYONE, Everyone, RawGroup } from "./coValues/group.js";
5
+ import {
6
+ EVERYONE,
7
+ Everyone,
8
+ ParentGroupReferenceRole,
9
+ RawGroup,
10
+ isInheritableRole,
11
+ } from "./coValues/group.js";
6
12
  import { KeyID } from "./crypto/crypto.js";
7
13
  import {
8
14
  AgentID,
@@ -141,6 +147,7 @@ function resolveMemberStateFromParentReference(
141
147
  coValue: CoValueCore,
142
148
  memberState: MemberState,
143
149
  parentReference: ParentGroupReference,
150
+ roleMapping: ParentGroupReferenceRole,
144
151
  extendChain: Set<CoValueCore["id"]>,
145
152
  ) {
146
153
  const parentGroup = coValue.node.expectCoValueLoaded(
@@ -174,8 +181,12 @@ function resolveMemberStateFromParentReference(
174
181
  const parentRole = parentGroupMemberState[agent];
175
182
  const currentRole = memberState[agent];
176
183
 
177
- if (parentRole && isHigherRole(parentRole, currentRole)) {
178
- memberState[agent] = parentRole;
184
+ if (isInheritableRole(parentRole)) {
185
+ if (roleMapping !== "extend" && isHigherRole(roleMapping, currentRole)) {
186
+ memberState[agent] = roleMapping;
187
+ } else if (isHigherRole(parentRole, currentRole)) {
188
+ memberState[agent] = parentRole;
189
+ }
179
190
  }
180
191
  }
181
192
  }
@@ -317,6 +328,7 @@ function determineValidTransactionsForGroup(
317
328
  coValue,
318
329
  memberState,
319
330
  change.key,
331
+ change.value as ParentGroupReferenceRole,
320
332
  extendChain,
321
333
  );
322
334
 
@@ -1,43 +1,36 @@
1
- import { describe, expect, onTestFinished, test, vi } from "vitest";
1
+ import { beforeEach, describe, expect, onTestFinished, test, vi } from "vitest";
2
2
  import {
3
3
  GlobalSyncStateListenerCallback,
4
4
  PeerSyncStateListenerCallback,
5
5
  } from "../SyncStateManager.js";
6
- import { accountHeaderForInitialAgentSecret } from "../coValues/account.js";
7
6
  import { connectedPeers } from "../streamUtils.js";
8
7
  import { emptyKnownState } from "../sync.js";
9
8
  import {
10
9
  blockMessageTypeOnOutgoingPeer,
10
+ connectNodeToSyncServer,
11
11
  createTestNode,
12
- createTwoConnectedNodes,
13
12
  loadCoValueOrFail,
13
+ setupSyncServer,
14
14
  waitFor,
15
15
  } from "./testUtils.js";
16
16
 
17
+ let jazzCloud = setupSyncServer();
18
+
19
+ beforeEach(async () => {
20
+ jazzCloud = setupSyncServer();
21
+ });
22
+
17
23
  describe("SyncStateManager", () => {
18
24
  test("subscribeToUpdates receives updates when peer state changes", async () => {
19
25
  // Setup nodes
20
26
  const client = createTestNode();
21
- const jazzCloud = createTestNode();
27
+ const { nodeToServerPeer } = connectNodeToSyncServer(client);
22
28
 
23
29
  // Create test data
24
30
  const group = client.createGroup();
25
31
  const map = group.createMap();
26
32
  map.set("key1", "value1", "trusting");
27
33
 
28
- // Connect nodes
29
- const [clientAsPeer, jazzCloudAsPeer] = connectedPeers(
30
- "clientConnection",
31
- "jazzCloudConnection",
32
- {
33
- peer1role: "client",
34
- peer2role: "server",
35
- },
36
- );
37
-
38
- client.syncManager.addPeer(jazzCloudAsPeer);
39
- jazzCloud.syncManager.addPeer(clientAsPeer);
40
-
41
34
  const subscriptionManager = client.syncManager.syncState;
42
35
 
43
36
  const updateSpy: GlobalSyncStateListenerCallback = vi.fn();
@@ -46,21 +39,21 @@ describe("SyncStateManager", () => {
46
39
  await client.syncManager.actuallySyncCoValue(map.core);
47
40
 
48
41
  expect(updateSpy).toHaveBeenCalledWith(
49
- "jazzCloudConnection",
42
+ nodeToServerPeer.id,
50
43
  emptyKnownState(map.core.id),
51
44
  { uploaded: false },
52
45
  );
53
46
 
54
47
  await waitFor(() => {
55
48
  return subscriptionManager.getCurrentSyncState(
56
- "jazzCloudConnection",
49
+ nodeToServerPeer.id,
57
50
  map.core.id,
58
51
  ).uploaded;
59
52
  });
60
53
 
61
54
  expect(updateSpy).toHaveBeenCalledWith(
62
- "jazzCloudConnection",
63
- client.syncManager.peers["jazzCloudConnection"]!.knownStates.get(
55
+ nodeToServerPeer.id,
56
+ client.syncManager.peers[nodeToServerPeer.id]!.knownStates.get(
64
57
  map.core.id,
65
58
  )!,
66
59
  { uploaded: true },
@@ -73,42 +66,30 @@ describe("SyncStateManager", () => {
73
66
  test("subscribeToPeerUpdates receives updates only for specific peer", async () => {
74
67
  // Setup nodes
75
68
  const client = createTestNode();
76
- const jazzCloud = createTestNode();
69
+ const { nodeToServerPeer } = connectNodeToSyncServer(client);
77
70
 
78
71
  // Create test data
79
72
  const group = client.createGroup();
80
73
  const map = group.createMap();
81
74
  map.set("key1", "value1", "trusting");
82
75
 
83
- // Connect nodes
84
- const [clientAsPeer, jazzCloudAsPeer] = connectedPeers(
85
- "clientConnection",
86
- "jazzCloudConnection",
87
- {
88
- peer1role: "client",
89
- peer2role: "server",
90
- },
91
- );
92
-
93
76
  const [clientStoragePeer] = connectedPeers("clientStorage", "unusedPeer", {
94
77
  peer1role: "client",
95
78
  peer2role: "server",
96
79
  });
97
80
 
98
- client.syncManager.addPeer(jazzCloudAsPeer);
99
81
  client.syncManager.addPeer(clientStoragePeer);
100
- jazzCloud.syncManager.addPeer(clientAsPeer);
101
82
 
102
83
  const subscriptionManager = client.syncManager.syncState;
103
84
 
104
85
  const updateToJazzCloudSpy: PeerSyncStateListenerCallback = vi.fn();
105
86
  const updateToStorageSpy: PeerSyncStateListenerCallback = vi.fn();
106
87
  const unsubscribe1 = subscriptionManager.subscribeToPeerUpdates(
107
- "jazzCloudConnection",
88
+ nodeToServerPeer.id,
108
89
  updateToJazzCloudSpy,
109
90
  );
110
91
  const unsubscribe2 = subscriptionManager.subscribeToPeerUpdates(
111
- "clientStorage",
92
+ clientStoragePeer.id,
112
93
  updateToStorageSpy,
113
94
  );
114
95
 
@@ -126,13 +107,13 @@ describe("SyncStateManager", () => {
126
107
 
127
108
  await waitFor(() => {
128
109
  return subscriptionManager.getCurrentSyncState(
129
- "jazzCloudConnection",
110
+ nodeToServerPeer.id,
130
111
  map.core.id,
131
112
  ).uploaded;
132
113
  });
133
114
 
134
115
  expect(updateToJazzCloudSpy).toHaveBeenLastCalledWith(
135
- client.syncManager.peers["jazzCloudConnection"]!.knownStates.get(
116
+ client.syncManager.peers[nodeToServerPeer.id]!.knownStates.get(
136
117
  map.core.id,
137
118
  )!,
138
119
  { uploaded: true },
@@ -147,80 +128,50 @@ describe("SyncStateManager", () => {
147
128
  test("getIsCoValueFullyUploadedIntoPeer returns correct status", async () => {
148
129
  // Setup nodes
149
130
  const client = createTestNode();
150
- const jazzCloud = createTestNode();
131
+ const { nodeToServerPeer } = connectNodeToSyncServer(client);
151
132
 
152
133
  // Create test data
153
134
  const group = client.createGroup();
154
135
  const map = group.createMap();
155
136
  map.set("key1", "value1", "trusting");
156
137
 
157
- // Connect nodes
158
- const [clientAsPeer, jazzCloudAsPeer] = connectedPeers(
159
- "clientConnection",
160
- "jazzCloudConnection",
161
- {
162
- peer1role: "client",
163
- peer2role: "server",
164
- },
165
- );
166
-
167
- client.syncManager.addPeer(jazzCloudAsPeer);
168
- jazzCloud.syncManager.addPeer(clientAsPeer);
169
-
170
138
  await client.syncManager.actuallySyncCoValue(map.core);
171
139
 
172
140
  const subscriptionManager = client.syncManager.syncState;
173
141
 
174
142
  expect(
175
- subscriptionManager.getCurrentSyncState(
176
- "jazzCloudConnection",
177
- map.core.id,
178
- ).uploaded,
143
+ subscriptionManager.getCurrentSyncState(nodeToServerPeer.id, map.core.id)
144
+ .uploaded,
179
145
  ).toBe(false);
180
146
 
181
147
  await waitFor(() => {
182
148
  return subscriptionManager.getCurrentSyncState(
183
- "jazzCloudConnection",
149
+ nodeToServerPeer.id,
184
150
  map.core.id,
185
151
  ).uploaded;
186
152
  });
187
153
 
188
154
  expect(
189
- subscriptionManager.getCurrentSyncState(
190
- "jazzCloudConnection",
191
- map.core.id,
192
- ).uploaded,
155
+ subscriptionManager.getCurrentSyncState(nodeToServerPeer.id, map.core.id)
156
+ .uploaded,
193
157
  ).toBe(true);
194
158
  });
195
159
 
196
160
  test("unsubscribe stops receiving updates", async () => {
197
161
  // Setup nodes
198
162
  const client = createTestNode();
199
- const jazzCloud = createTestNode();
163
+ const { nodeToServerPeer } = connectNodeToSyncServer(client);
200
164
 
201
165
  // Create test data
202
166
  const group = client.createGroup();
203
167
  const map = group.createMap();
204
168
  map.set("key1", "value1", "trusting");
205
169
 
206
- // Connect nodes
207
- const [clientAsPeer, jazzCloudAsPeer] = connectedPeers(
208
- "clientConnection",
209
- "jazzCloudConnection",
210
- {
211
- peer1role: "client",
212
- peer2role: "server",
213
- },
214
- );
215
-
216
- client.syncManager.addPeer(jazzCloudAsPeer);
217
- jazzCloud.syncManager.addPeer(clientAsPeer);
218
-
219
170
  const subscriptionManager = client.syncManager.syncState;
220
171
  const anyUpdateSpy = vi.fn();
221
172
  const unsubscribe1 = subscriptionManager.subscribeToUpdates(anyUpdateSpy);
222
173
  const unsubscribe2 = subscriptionManager.subscribeToPeerUpdates(
223
- "jazzCloudConnection",
174
+ nodeToServerPeer.id,
224
175
  anyUpdateSpy,
225
176
  );
226
177
 
@@ -233,7 +184,7 @@ describe("SyncStateManager", () => {
233
184
 
234
185
  await waitFor(() => {
235
186
  return subscriptionManager.getCurrentSyncState(
236
- "jazzCloudConnection",
187
+ nodeToServerPeer.id,
237
188
  map.core.id,
238
189
  ).uploaded;
239
190
  });
@@ -243,22 +194,21 @@ describe("SyncStateManager", () => {
243
194
 
244
195
  test("getCurrentSyncState should return the correct state", async () => {
245
196
  // Setup nodes
197
+ const clientNode = createTestNode();
198
+ const serverNode = jazzCloud;
246
199
  const {
247
- node1: clientNode,
248
- node2: serverNode,
249
- node1ToNode2Peer: clientToServerPeer,
250
- node2ToNode1Peer: serverToClientPeer,
251
- } = await createTwoConnectedNodes("client", "server");
252
-
200
+ nodeToServerPeer: clientToServerPeer,
201
+ serverToNodePeer: serverToClientPeer,
202
+ } = connectNodeToSyncServer(clientNode);
253
203
  // Create test data
254
- const group = clientNode.node.createGroup();
204
+ const group = clientNode.createGroup();
255
205
  const map = group.createMap();
256
206
  map.set("key1", "value1", "trusting");
257
207
  group.addMember("everyone", "writer");
258
208
 
259
209
  // Initially should not be synced
260
210
  expect(
261
- clientNode.node.syncManager.syncState.getCurrentSyncState(
211
+ clientNode.syncManager.syncState.getCurrentSyncState(
262
212
  clientToServerPeer.id,
263
213
  map.core.id,
264
214
  ),
@@ -268,13 +218,13 @@ describe("SyncStateManager", () => {
268
218
  await map.core.waitForSync();
269
219
 
270
220
  expect(
271
- clientNode.node.syncManager.syncState.getCurrentSyncState(
221
+ clientNode.syncManager.syncState.getCurrentSyncState(
272
222
  clientToServerPeer.id,
273
223
  map.core.id,
274
224
  ),
275
225
  ).toEqual({ uploaded: true });
276
226
 
277
- const mapOnServer = await loadCoValueOrFail(serverNode.node, map.id);
227
+ const mapOnServer = await loadCoValueOrFail(serverNode, map.id);
278
228
 
279
229
  // Block the content messages so the client won't fully sync immediately
280
230
  const outgoing = blockMessageTypeOnOutgoingPeer(
@@ -285,14 +235,14 @@ describe("SyncStateManager", () => {
285
235
  mapOnServer.set("key2", "value2", "trusting");
286
236
 
287
237
  expect(
288
- clientNode.node.syncManager.syncState.getCurrentSyncState(
238
+ clientNode.syncManager.syncState.getCurrentSyncState(
289
239
  clientToServerPeer.id,
290
240
  map.core.id,
291
241
  ),
292
242
  ).toEqual({ uploaded: true });
293
243
 
294
244
  expect(
295
- serverNode.node.syncManager.syncState.getCurrentSyncState(
245
+ serverNode.syncManager.syncState.getCurrentSyncState(
296
246
  serverToClientPeer.id,
297
247
  map.core.id,
298
248
  ),
@@ -304,14 +254,14 @@ describe("SyncStateManager", () => {
304
254
  await mapOnServer.core.waitForSync();
305
255
 
306
256
  expect(
307
- clientNode.node.syncManager.syncState.getCurrentSyncState(
257
+ clientNode.syncManager.syncState.getCurrentSyncState(
308
258
  clientToServerPeer.id,
309
259
  map.core.id,
310
260
  ),
311
261
  ).toEqual({ uploaded: true });
312
262
 
313
263
  expect(
314
- serverNode.node.syncManager.syncState.getCurrentSyncState(
264
+ serverNode.syncManager.syncState.getCurrentSyncState(
315
265
  serverToClientPeer.id,
316
266
  map.core.id,
317
267
  ),
@@ -1,10 +1,24 @@
1
- import { describe, expect, test, vi } from "vitest";
1
+ import { beforeEach, describe, expect, onTestFinished, test, vi } from "vitest";
2
2
  import { PeerState } from "../PeerState";
3
3
  import { CoValueCore } from "../coValueCore";
4
- import { CO_VALUE_LOADING_MAX_RETRIES, CoValueState } from "../coValueState";
4
+ import { CO_VALUE_LOADING_CONFIG, CoValueState } from "../coValueState";
5
5
  import { RawCoID } from "../ids";
6
6
  import { Peer } from "../sync";
7
7
 
8
+ const initialMaxRetries = CO_VALUE_LOADING_CONFIG.MAX_RETRIES;
9
+
10
+ function mockMaxRetries(maxRetries: number) {
11
+ CO_VALUE_LOADING_CONFIG.MAX_RETRIES = maxRetries;
12
+
13
+ onTestFinished(() => {
14
+ CO_VALUE_LOADING_CONFIG.MAX_RETRIES = initialMaxRetries;
15
+ });
16
+ }
17
+
18
+ beforeEach(() => {
19
+ mockMaxRetries(5);
20
+ });
21
+
8
22
  describe("CoValueState", () => {
9
23
  const mockCoValueId = "co_test123" as RawCoID;
10
24
 
@@ -92,18 +106,18 @@ describe("CoValueState", () => {
92
106
  const state = CoValueState.Unknown(mockCoValueId);
93
107
  const loadPromise = state.loadFromPeers(mockPeers);
94
108
 
95
- // Should attempt CO_VALUE_LOADING_MAX_RETRIES retries
96
- for (let i = 0; i < CO_VALUE_LOADING_MAX_RETRIES; i++) {
109
+ // Should attempt CO_VALUE_LOADING_CONFIG.MAX_RETRIES retries
110
+ for (let i = 0; i < CO_VALUE_LOADING_CONFIG.MAX_RETRIES; i++) {
97
111
  await vi.runAllTimersAsync();
98
112
  }
99
113
 
100
114
  await loadPromise;
101
115
 
102
116
  expect(peer1.pushOutgoingMessage).toHaveBeenCalledTimes(
103
- CO_VALUE_LOADING_MAX_RETRIES,
117
+ CO_VALUE_LOADING_CONFIG.MAX_RETRIES,
104
118
  );
105
119
  expect(peer2.pushOutgoingMessage).toHaveBeenCalledTimes(
106
- CO_VALUE_LOADING_MAX_RETRIES,
120
+ CO_VALUE_LOADING_CONFIG.MAX_RETRIES,
107
121
  );
108
122
  expect(state.state.type).toBe("unavailable");
109
123
  await expect(state.getCoValue()).resolves.toBe("unavailable");
@@ -145,8 +159,8 @@ describe("CoValueState", () => {
145
159
  const state = CoValueState.Unknown(mockCoValueId);
146
160
  const loadPromise = state.loadFromPeers(mockPeers);
147
161
 
148
- // Should attempt CO_VALUE_LOADING_MAX_RETRIES retries
149
- for (let i = 0; i < CO_VALUE_LOADING_MAX_RETRIES; i++) {
162
+ // Should attempt CO_VALUE_LOADING_CONFIG.MAX_RETRIES retries
163
+ for (let i = 0; i < CO_VALUE_LOADING_CONFIG.MAX_RETRIES; i++) {
150
164
  await vi.runAllTimersAsync();
151
165
  }
152
166
 
@@ -154,7 +168,7 @@ describe("CoValueState", () => {
154
168
 
155
169
  expect(peer1.pushOutgoingMessage).toHaveBeenCalledTimes(1);
156
170
  expect(peer2.pushOutgoingMessage).toHaveBeenCalledTimes(
157
- CO_VALUE_LOADING_MAX_RETRIES,
171
+ CO_VALUE_LOADING_CONFIG.MAX_RETRIES,
158
172
  );
159
173
  expect(state.state.type).toBe("unavailable");
160
174
  await expect(state.getCoValue()).resolves.toBe("unavailable");
@@ -194,8 +208,8 @@ describe("CoValueState", () => {
194
208
  const state = CoValueState.Unknown(mockCoValueId);
195
209
  const loadPromise = state.loadFromPeers(mockPeers);
196
210
 
197
- // Should attempt CO_VALUE_LOADING_MAX_RETRIES retries
198
- for (let i = 0; i < CO_VALUE_LOADING_MAX_RETRIES; i++) {
211
+ // Should attempt CO_VALUE_LOADING_CONFIG.MAX_RETRIES retries
212
+ for (let i = 0; i < CO_VALUE_LOADING_CONFIG.MAX_RETRIES; i++) {
199
213
  await vi.runAllTimersAsync();
200
214
  }
201
215
 
@@ -203,7 +217,7 @@ describe("CoValueState", () => {
203
217
 
204
218
  expect(peer1.pushOutgoingMessage).toHaveBeenCalledTimes(1);
205
219
  expect(peer2.pushOutgoingMessage).toHaveBeenCalledTimes(
206
- CO_VALUE_LOADING_MAX_RETRIES,
220
+ CO_VALUE_LOADING_CONFIG.MAX_RETRIES,
207
221
  );
208
222
  expect(state.state.type).toBe("unavailable");
209
223
  await expect(state.getCoValue()).resolves.toEqual("unavailable");
@@ -214,6 +228,8 @@ describe("CoValueState", () => {
214
228
  test("should handle the coValues that become available in between of the retries", async () => {
215
229
  vi.useFakeTimers();
216
230
 
231
+ mockMaxRetries(5);
232
+
217
233
  let retries = 0;
218
234
 
219
235
  const peer1 = createMockPeerState(
@@ -244,8 +260,8 @@ describe("CoValueState", () => {
244
260
  const state = CoValueState.Unknown(mockCoValueId);
245
261
  const loadPromise = state.loadFromPeers(mockPeers);
246
262
 
247
- // Should attempt CO_VALUE_LOADING_MAX_RETRIES retries
248
- for (let i = 0; i < CO_VALUE_LOADING_MAX_RETRIES + 1; i++) {
263
+ // Should attempt CO_VALUE_LOADING_CONFIG.MAX_RETRIES retries
264
+ for (let i = 0; i < CO_VALUE_LOADING_CONFIG.MAX_RETRIES + 1; i++) {
249
265
  await vi.runAllTimersAsync();
250
266
  }
251
267
 
@@ -278,8 +294,8 @@ describe("CoValueState", () => {
278
294
  const state = CoValueState.Unknown(mockCoValueId);
279
295
  const loadPromise = state.loadFromPeers(mockPeers);
280
296
 
281
- // Should attempt CO_VALUE_LOADING_MAX_RETRIES retries
282
- for (let i = 0; i < CO_VALUE_LOADING_MAX_RETRIES; i++) {
297
+ // Should attempt CO_VALUE_LOADING_CONFIG.MAX_RETRIES retries
298
+ for (let i = 0; i < CO_VALUE_LOADING_CONFIG.MAX_RETRIES; i++) {
283
299
  await vi.runAllTimersAsync();
284
300
  }
285
301
 
@@ -290,7 +306,9 @@ describe("CoValueState", () => {
290
306
 
291
307
  await loadPromise;
292
308
 
293
- expect(peer1.pushOutgoingMessage).toHaveBeenCalledTimes(5);
309
+ expect(peer1.pushOutgoingMessage).toHaveBeenCalledTimes(
310
+ CO_VALUE_LOADING_CONFIG.MAX_RETRIES,
311
+ );
294
312
  expect(state.state.type).toBe("available");
295
313
  await expect(state.getCoValue()).resolves.toEqual({ id: mockCoValueId });
296
314
 
@@ -300,6 +318,8 @@ describe("CoValueState", () => {
300
318
  test("should stop retrying when value becomes available", async () => {
301
319
  vi.useFakeTimers();
302
320
 
321
+ mockMaxRetries(5);
322
+
303
323
  let run = 1;
304
324
 
305
325
  const peer1 = createMockPeerState(
@@ -327,7 +347,7 @@ describe("CoValueState", () => {
327
347
  const state = CoValueState.Unknown(mockCoValueId);
328
348
  const loadPromise = state.loadFromPeers(mockPeers);
329
349
 
330
- for (let i = 0; i < CO_VALUE_LOADING_MAX_RETRIES; i++) {
350
+ for (let i = 0; i < CO_VALUE_LOADING_CONFIG.MAX_RETRIES; i++) {
331
351
  await vi.runAllTimersAsync();
332
352
  }
333
353
  await loadPromise;
@@ -372,7 +392,7 @@ describe("CoValueState", () => {
372
392
  const state = CoValueState.Unknown(mockCoValueId);
373
393
  const loadPromise = state.loadFromPeers([peer1, peer2]);
374
394
 
375
- for (let i = 0; i < CO_VALUE_LOADING_MAX_RETRIES; i++) {
395
+ for (let i = 0; i < CO_VALUE_LOADING_CONFIG.MAX_RETRIES; i++) {
376
396
  await vi.runAllTimersAsync();
377
397
  }
378
398
  await loadPromise;
@@ -421,7 +441,7 @@ describe("CoValueState", () => {
421
441
  const state = CoValueState.Unknown(mockCoValueId);
422
442
  const loadPromise = state.loadFromPeers([peer1, peer2]);
423
443
 
424
- for (let i = 0; i < CO_VALUE_LOADING_MAX_RETRIES; i++) {
444
+ for (let i = 0; i < CO_VALUE_LOADING_CONFIG.MAX_RETRIES; i++) {
425
445
  await vi.runAllTimersAsync();
426
446
  }
427
447
  await loadPromise;
@@ -449,12 +469,14 @@ describe("CoValueState", () => {
449
469
  const state = CoValueState.Unknown(mockCoValueId);
450
470
  const loadPromise = state.loadFromPeers([peer1]);
451
471
 
452
- for (let i = 0; i < CO_VALUE_LOADING_MAX_RETRIES * 2; i++) {
472
+ for (let i = 0; i < CO_VALUE_LOADING_CONFIG.MAX_RETRIES * 2; i++) {
453
473
  await vi.runAllTimersAsync();
454
474
  }
455
475
  await loadPromise;
456
476
 
457
- expect(peer1.pushOutgoingMessage).toHaveBeenCalledTimes(5);
477
+ expect(peer1.pushOutgoingMessage).toHaveBeenCalledTimes(
478
+ CO_VALUE_LOADING_CONFIG.MAX_RETRIES,
479
+ );
458
480
 
459
481
  expect(state.state.type).toBe("unavailable");
460
482
  await expect(state.getCoValue()).resolves.toEqual("unavailable");