cojson 0.13.16 → 0.13.18
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 +16 -0
- package/dist/PeerState.d.ts +3 -0
- package/dist/PeerState.d.ts.map +1 -1
- package/dist/PeerState.js +9 -0
- package/dist/PeerState.js.map +1 -1
- package/dist/SyncStateManager.d.ts.map +1 -1
- package/dist/SyncStateManager.js +2 -3
- package/dist/SyncStateManager.js.map +1 -1
- package/dist/coValue.d.ts +6 -4
- package/dist/coValue.d.ts.map +1 -1
- package/dist/coValue.js +5 -4
- package/dist/coValue.js.map +1 -1
- package/dist/coValueCore/coValueCore.d.ts +143 -0
- package/dist/coValueCore/coValueCore.d.ts.map +1 -0
- package/dist/{coValueCore.js → coValueCore/coValueCore.js} +314 -246
- package/dist/coValueCore/coValueCore.js.map +1 -0
- package/dist/coValueCore/verifiedState.d.ts +65 -0
- package/dist/coValueCore/verifiedState.d.ts.map +1 -0
- package/dist/coValueCore/verifiedState.js +210 -0
- package/dist/coValueCore/verifiedState.js.map +1 -0
- package/dist/coValues/account.d.ts +8 -10
- package/dist/coValues/account.d.ts.map +1 -1
- package/dist/coValues/account.js +12 -13
- package/dist/coValues/account.js.map +1 -1
- package/dist/coValues/coList.d.ts +10 -6
- package/dist/coValues/coList.d.ts.map +1 -1
- package/dist/coValues/coList.js +41 -15
- package/dist/coValues/coList.js.map +1 -1
- package/dist/coValues/coMap.d.ts +4 -3
- package/dist/coValues/coMap.d.ts.map +1 -1
- package/dist/coValues/coMap.js +5 -3
- package/dist/coValues/coMap.js.map +1 -1
- package/dist/coValues/coPlainText.d.ts +2 -2
- package/dist/coValues/coPlainText.d.ts.map +1 -1
- package/dist/coValues/coPlainText.js +5 -5
- package/dist/coValues/coPlainText.js.map +1 -1
- package/dist/coValues/coStream.d.ts +5 -4
- package/dist/coValues/coStream.d.ts.map +1 -1
- package/dist/coValues/coStream.js +5 -3
- package/dist/coValues/coStream.js.map +1 -1
- package/dist/coValues/group.d.ts +7 -2
- package/dist/coValues/group.d.ts.map +1 -1
- package/dist/coValues/group.js +29 -26
- package/dist/coValues/group.js.map +1 -1
- package/dist/coreToCoValue.d.ts +4 -3
- package/dist/coreToCoValue.d.ts.map +1 -1
- package/dist/coreToCoValue.js +10 -14
- package/dist/coreToCoValue.js.map +1 -1
- package/dist/exports.d.ts +6 -5
- package/dist/exports.d.ts.map +1 -1
- package/dist/exports.js +3 -4
- package/dist/exports.js.map +1 -1
- package/dist/localNode.d.ts +30 -24
- package/dist/localNode.d.ts.map +1 -1
- package/dist/localNode.js +153 -177
- package/dist/localNode.js.map +1 -1
- package/dist/permissions.d.ts +2 -1
- package/dist/permissions.d.ts.map +1 -1
- package/dist/permissions.js +15 -11
- package/dist/permissions.js.map +1 -1
- package/dist/priority.d.ts +1 -1
- package/dist/priority.d.ts.map +1 -1
- package/dist/sync.d.ts +2 -2
- package/dist/sync.d.ts.map +1 -1
- package/dist/sync.js +86 -55
- package/dist/sync.js.map +1 -1
- package/dist/tests/coList.test.js +133 -13
- package/dist/tests/coList.test.js.map +1 -1
- package/dist/tests/coMap.test.js +43 -14
- package/dist/tests/coMap.test.js.map +1 -1
- package/dist/tests/coPlainText.test.js +9 -10
- package/dist/tests/coPlainText.test.js.map +1 -1
- package/dist/tests/coStream.test.js +49 -18
- package/dist/tests/coStream.test.js.map +1 -1
- package/dist/tests/coValueCore.test.js +22 -28
- package/dist/tests/coValueCore.test.js.map +1 -1
- package/dist/tests/coValueCoreLoadingState.test.d.ts +2 -0
- package/dist/tests/coValueCoreLoadingState.test.d.ts.map +1 -0
- package/dist/tests/coValueCoreLoadingState.test.js +227 -0
- package/dist/tests/coValueCoreLoadingState.test.js.map +1 -0
- package/dist/tests/group.test.js +42 -43
- package/dist/tests/group.test.js.map +1 -1
- package/dist/tests/messagesTestUtils.d.ts +2 -2
- package/dist/tests/messagesTestUtils.d.ts.map +1 -1
- package/dist/tests/messagesTestUtils.js +1 -1
- package/dist/tests/messagesTestUtils.js.map +1 -1
- package/dist/tests/permissions.test.js +224 -292
- package/dist/tests/permissions.test.js.map +1 -1
- package/dist/tests/priority.test.js +13 -14
- package/dist/tests/priority.test.js.map +1 -1
- package/dist/tests/sync.auth.test.d.ts +2 -0
- package/dist/tests/sync.auth.test.d.ts.map +1 -0
- package/dist/tests/sync.auth.test.js +141 -0
- package/dist/tests/sync.auth.test.js.map +1 -0
- package/dist/tests/sync.load.test.js +60 -2
- package/dist/tests/sync.load.test.js.map +1 -1
- package/dist/tests/sync.mesh.test.js +70 -10
- package/dist/tests/sync.mesh.test.js.map +1 -1
- package/dist/tests/sync.peerReconciliation.test.js +19 -19
- package/dist/tests/sync.peerReconciliation.test.js.map +1 -1
- package/dist/tests/sync.storage.test.js +20 -13
- package/dist/tests/sync.storage.test.js.map +1 -1
- package/dist/tests/sync.test.js +32 -39
- package/dist/tests/sync.test.js.map +1 -1
- package/dist/tests/sync.upload.test.js +126 -37
- package/dist/tests/sync.upload.test.js.map +1 -1
- package/dist/tests/testUtils.d.ts +24 -15
- package/dist/tests/testUtils.d.ts.map +1 -1
- package/dist/tests/testUtils.js +88 -61
- package/dist/tests/testUtils.js.map +1 -1
- package/dist/typeUtils/expectGroup.js +1 -1
- package/dist/typeUtils/expectGroup.js.map +1 -1
- package/package.json +1 -1
- package/src/PeerState.ts +11 -0
- package/src/SyncStateManager.ts +2 -3
- package/src/coValue.ts +14 -8
- package/src/{coValueCore.ts → coValueCore/coValueCore.ts} +470 -413
- package/src/coValueCore/verifiedState.ts +376 -0
- package/src/coValues/account.ts +20 -25
- package/src/coValues/coList.ts +63 -29
- package/src/coValues/coMap.ts +13 -6
- package/src/coValues/coPlainText.ts +10 -8
- package/src/coValues/coStream.ts +12 -7
- package/src/coValues/group.ts +50 -28
- package/src/coreToCoValue.ts +14 -15
- package/src/exports.ts +9 -7
- package/src/localNode.ts +248 -283
- package/src/permissions.ts +18 -12
- package/src/priority.ts +1 -1
- package/src/sync.ts +96 -63
- package/src/tests/coList.test.ts +200 -12
- package/src/tests/coMap.test.ts +65 -14
- package/src/tests/coPlainText.test.ts +12 -9
- package/src/tests/coStream.test.ts +80 -17
- package/src/tests/coValueCore.test.ts +30 -27
- package/src/tests/coValueCoreLoadingState.test.ts +337 -0
- package/src/tests/group.test.ts +44 -68
- package/src/tests/messagesTestUtils.ts +3 -8
- package/src/tests/permissions.test.ts +283 -449
- package/src/tests/priority.test.ts +17 -13
- package/src/tests/sync.auth.test.ts +188 -0
- package/src/tests/sync.load.test.ts +79 -2
- package/src/tests/sync.mesh.test.ts +89 -9
- package/src/tests/sync.peerReconciliation.test.ts +25 -25
- package/src/tests/sync.storage.test.ts +20 -13
- package/src/tests/sync.test.ts +43 -43
- package/src/tests/sync.upload.test.ts +157 -37
- package/src/tests/testUtils.ts +120 -74
- package/src/typeUtils/expectGroup.ts +1 -1
- package/dist/CoValuesStore.d.ts +0 -14
- package/dist/CoValuesStore.d.ts.map +0 -1
- package/dist/CoValuesStore.js +0 -32
- package/dist/CoValuesStore.js.map +0 -1
- package/dist/coValueCore.d.ts +0 -141
- package/dist/coValueCore.d.ts.map +0 -1
- package/dist/coValueCore.js.map +0 -1
- package/dist/coValueState.d.ts +0 -34
- package/dist/coValueState.d.ts.map +0 -1
- package/dist/coValueState.js +0 -228
- package/dist/coValueState.js.map +0 -1
- package/dist/tests/coValueState.test.d.ts +0 -2
- package/dist/tests/coValueState.test.d.ts.map +0 -1
- package/dist/tests/coValueState.test.js +0 -344
- package/dist/tests/coValueState.test.js.map +0 -1
- package/src/CoValuesStore.ts +0 -41
- package/src/coValueState.ts +0 -300
- package/src/tests/coValueState.test.ts +0 -525
|
@@ -1,525 +0,0 @@
|
|
|
1
|
-
import {
|
|
2
|
-
assert,
|
|
3
|
-
afterEach,
|
|
4
|
-
beforeEach,
|
|
5
|
-
describe,
|
|
6
|
-
expect,
|
|
7
|
-
onTestFinished,
|
|
8
|
-
test,
|
|
9
|
-
vi,
|
|
10
|
-
} from "vitest";
|
|
11
|
-
import { PeerState } from "../PeerState";
|
|
12
|
-
import { CoValueCore } from "../coValueCore";
|
|
13
|
-
import { CO_VALUE_LOADING_CONFIG, CoValueState } from "../coValueState";
|
|
14
|
-
import { RawCoID } from "../ids";
|
|
15
|
-
import { Peer } from "../sync";
|
|
16
|
-
import { createTestMetricReader, tearDownTestMetricReader } from "./testUtils";
|
|
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
|
-
let metricReader: ReturnType<typeof createTestMetricReader>;
|
|
29
|
-
|
|
30
|
-
beforeEach(() => {
|
|
31
|
-
metricReader = createTestMetricReader();
|
|
32
|
-
mockMaxRetries(5);
|
|
33
|
-
});
|
|
34
|
-
|
|
35
|
-
afterEach(() => {
|
|
36
|
-
tearDownTestMetricReader();
|
|
37
|
-
});
|
|
38
|
-
|
|
39
|
-
describe("CoValueState", () => {
|
|
40
|
-
const mockCoValueId = "co_test123" as RawCoID;
|
|
41
|
-
|
|
42
|
-
test("should create unknown state", async () => {
|
|
43
|
-
const state = new CoValueState(mockCoValueId);
|
|
44
|
-
|
|
45
|
-
expect(state.id).toBe(mockCoValueId);
|
|
46
|
-
expect(state.highLevelState).toBe("unknown");
|
|
47
|
-
expect(
|
|
48
|
-
await metricReader.getMetricValue("jazz.covalues.loaded", {
|
|
49
|
-
state: "unknown",
|
|
50
|
-
}),
|
|
51
|
-
).toBe(1);
|
|
52
|
-
});
|
|
53
|
-
|
|
54
|
-
test("should create loading state", async () => {
|
|
55
|
-
const state = new CoValueState(mockCoValueId);
|
|
56
|
-
state.loadFromPeers([
|
|
57
|
-
createMockPeerState({ id: "peer1", role: "server" }),
|
|
58
|
-
createMockPeerState({ id: "peer2", role: "server" }),
|
|
59
|
-
]);
|
|
60
|
-
|
|
61
|
-
expect(state.id).toBe(mockCoValueId);
|
|
62
|
-
expect(state.highLevelState).toBe("loading");
|
|
63
|
-
expect(
|
|
64
|
-
await metricReader.getMetricValue("jazz.covalues.loaded", {
|
|
65
|
-
state: "loading",
|
|
66
|
-
}),
|
|
67
|
-
).toBe(1);
|
|
68
|
-
});
|
|
69
|
-
|
|
70
|
-
test("should create available state", async () => {
|
|
71
|
-
const mockCoValue = createMockCoValueCore(mockCoValueId);
|
|
72
|
-
const state = new CoValueState(mockCoValueId);
|
|
73
|
-
state.internalMarkMagicallyAvailable(mockCoValue);
|
|
74
|
-
|
|
75
|
-
expect(state.id).toBe(mockCoValueId);
|
|
76
|
-
expect(state.highLevelState).toBe("available");
|
|
77
|
-
expect(state.core).toBe(mockCoValue);
|
|
78
|
-
await expect(state.getCoValue()).resolves.toEqual(mockCoValue);
|
|
79
|
-
expect(
|
|
80
|
-
await metricReader.getMetricValue("jazz.covalues.loaded", {
|
|
81
|
-
state: "available",
|
|
82
|
-
}),
|
|
83
|
-
).toBe(1);
|
|
84
|
-
});
|
|
85
|
-
|
|
86
|
-
test("should handle found action", async () => {
|
|
87
|
-
const mockCoValue = createMockCoValueCore(mockCoValueId);
|
|
88
|
-
const state = new CoValueState(mockCoValueId);
|
|
89
|
-
state.loadFromPeers([
|
|
90
|
-
createMockPeerState({ id: "peer1", role: "server" }),
|
|
91
|
-
createMockPeerState({ id: "peer2", role: "server" }),
|
|
92
|
-
]);
|
|
93
|
-
|
|
94
|
-
expect(
|
|
95
|
-
await metricReader.getMetricValue("jazz.covalues.loaded", {
|
|
96
|
-
state: "available",
|
|
97
|
-
}),
|
|
98
|
-
).toBe(undefined);
|
|
99
|
-
expect(
|
|
100
|
-
await metricReader.getMetricValue("jazz.covalues.loaded", {
|
|
101
|
-
state: "loading",
|
|
102
|
-
}),
|
|
103
|
-
).toBe(1);
|
|
104
|
-
|
|
105
|
-
const stateValuePromise = state.getCoValue();
|
|
106
|
-
|
|
107
|
-
state.internalMarkMagicallyAvailable(mockCoValue);
|
|
108
|
-
|
|
109
|
-
const result = await state.getCoValue();
|
|
110
|
-
expect(result).toBe(mockCoValue);
|
|
111
|
-
await expect(stateValuePromise).resolves.toBe(mockCoValue);
|
|
112
|
-
|
|
113
|
-
expect(
|
|
114
|
-
await metricReader.getMetricValue("jazz.covalues.loaded", {
|
|
115
|
-
state: "available",
|
|
116
|
-
}),
|
|
117
|
-
).toBe(1);
|
|
118
|
-
expect(
|
|
119
|
-
await metricReader.getMetricValue("jazz.covalues.loaded", {
|
|
120
|
-
state: "loading",
|
|
121
|
-
}),
|
|
122
|
-
).toBe(0);
|
|
123
|
-
});
|
|
124
|
-
|
|
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
|
-
test("should skip errored coValues when loading from peers", async () => {
|
|
171
|
-
vi.useFakeTimers();
|
|
172
|
-
|
|
173
|
-
const peer1 = createMockPeerState(
|
|
174
|
-
{
|
|
175
|
-
id: "peer1",
|
|
176
|
-
role: "server",
|
|
177
|
-
},
|
|
178
|
-
async () => {
|
|
179
|
-
state.markErrored("peer1", {} as any);
|
|
180
|
-
},
|
|
181
|
-
);
|
|
182
|
-
const peer2 = createMockPeerState(
|
|
183
|
-
{
|
|
184
|
-
id: "peer2",
|
|
185
|
-
role: "server",
|
|
186
|
-
},
|
|
187
|
-
async () => {
|
|
188
|
-
state.markNotFoundInPeer("peer2");
|
|
189
|
-
},
|
|
190
|
-
);
|
|
191
|
-
|
|
192
|
-
const mockPeers = [peer1, peer2] as unknown as PeerState[];
|
|
193
|
-
|
|
194
|
-
const state = new CoValueState(mockCoValueId);
|
|
195
|
-
const loadPromise = state.loadFromPeers(mockPeers);
|
|
196
|
-
|
|
197
|
-
// Should attempt CO_VALUE_LOADING_CONFIG.MAX_RETRIES retries
|
|
198
|
-
for (let i = 0; i < CO_VALUE_LOADING_CONFIG.MAX_RETRIES; i++) {
|
|
199
|
-
await vi.runAllTimersAsync();
|
|
200
|
-
}
|
|
201
|
-
|
|
202
|
-
await loadPromise;
|
|
203
|
-
|
|
204
|
-
expect(peer1.pushOutgoingMessage).toHaveBeenCalledTimes(1);
|
|
205
|
-
expect(peer2.pushOutgoingMessage).toHaveBeenCalledTimes(
|
|
206
|
-
CO_VALUE_LOADING_CONFIG.MAX_RETRIES,
|
|
207
|
-
);
|
|
208
|
-
expect(state.highLevelState).toBe("unavailable");
|
|
209
|
-
await expect(state.getCoValue()).resolves.toBe("unavailable");
|
|
210
|
-
|
|
211
|
-
vi.useRealTimers();
|
|
212
|
-
});
|
|
213
|
-
|
|
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
|
-
test("should have a coValue as value property when becomes available after that have been marked as unavailable", async () => {
|
|
300
|
-
vi.useFakeTimers();
|
|
301
|
-
|
|
302
|
-
const peer1 = createMockPeerState(
|
|
303
|
-
{
|
|
304
|
-
id: "peer1",
|
|
305
|
-
role: "server",
|
|
306
|
-
},
|
|
307
|
-
async () => {
|
|
308
|
-
state.markNotFoundInPeer("peer1");
|
|
309
|
-
},
|
|
310
|
-
);
|
|
311
|
-
|
|
312
|
-
const mockPeers = [peer1] as unknown as PeerState[];
|
|
313
|
-
|
|
314
|
-
const state = new CoValueState(mockCoValueId);
|
|
315
|
-
const loadPromise = state.loadFromPeers(mockPeers);
|
|
316
|
-
|
|
317
|
-
// Should attempt CO_VALUE_LOADING_CONFIG.MAX_RETRIES retries
|
|
318
|
-
for (let i = 0; i < CO_VALUE_LOADING_CONFIG.MAX_RETRIES; i++) {
|
|
319
|
-
await vi.runAllTimersAsync();
|
|
320
|
-
}
|
|
321
|
-
|
|
322
|
-
state.internalMarkMagicallyAvailable(createMockCoValueCore(mockCoValueId));
|
|
323
|
-
|
|
324
|
-
await loadPromise;
|
|
325
|
-
|
|
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);
|
|
368
|
-
expect(state.highLevelState).toBe("available");
|
|
369
|
-
await expect(state.getCoValue()).resolves.toEqual({ id: mockCoValueId });
|
|
370
|
-
|
|
371
|
-
vi.useRealTimers();
|
|
372
|
-
});
|
|
373
|
-
|
|
374
|
-
test("should start sending the known state to peers when available", async () => {
|
|
375
|
-
vi.useFakeTimers();
|
|
376
|
-
|
|
377
|
-
const mockCoValue = createMockCoValueCore(mockCoValueId);
|
|
378
|
-
|
|
379
|
-
const peer1 = createMockPeerState(
|
|
380
|
-
{
|
|
381
|
-
id: "peer1",
|
|
382
|
-
role: "storage",
|
|
383
|
-
},
|
|
384
|
-
async () => {
|
|
385
|
-
state.markAvailable(mockCoValue, "peer1");
|
|
386
|
-
},
|
|
387
|
-
);
|
|
388
|
-
const peer2 = createMockPeerState(
|
|
389
|
-
{
|
|
390
|
-
id: "peer2",
|
|
391
|
-
role: "server",
|
|
392
|
-
},
|
|
393
|
-
async () => {
|
|
394
|
-
state.markNotFoundInPeer("peer2");
|
|
395
|
-
},
|
|
396
|
-
);
|
|
397
|
-
|
|
398
|
-
const state = new CoValueState(mockCoValueId);
|
|
399
|
-
const loadPromise = state.loadFromPeers([peer1, peer2]);
|
|
400
|
-
|
|
401
|
-
for (let i = 0; i < CO_VALUE_LOADING_CONFIG.MAX_RETRIES; i++) {
|
|
402
|
-
await vi.runAllTimersAsync();
|
|
403
|
-
}
|
|
404
|
-
await loadPromise;
|
|
405
|
-
|
|
406
|
-
expect(peer1.pushOutgoingMessage).toHaveBeenCalledTimes(1);
|
|
407
|
-
expect(peer2.pushOutgoingMessage).toHaveBeenCalledTimes(1);
|
|
408
|
-
expect(peer2.pushOutgoingMessage).toHaveBeenCalledWith({
|
|
409
|
-
action: "load",
|
|
410
|
-
...mockCoValue.knownState(),
|
|
411
|
-
});
|
|
412
|
-
expect(state.highLevelState).toBe("available");
|
|
413
|
-
await expect(state.getCoValue()).resolves.toEqual({ id: mockCoValueId });
|
|
414
|
-
|
|
415
|
-
vi.useRealTimers();
|
|
416
|
-
});
|
|
417
|
-
|
|
418
|
-
test("should skip closed peers", async () => {
|
|
419
|
-
vi.useFakeTimers();
|
|
420
|
-
|
|
421
|
-
const mockCoValue = createMockCoValueCore(mockCoValueId);
|
|
422
|
-
|
|
423
|
-
const peer1 = createMockPeerState(
|
|
424
|
-
{
|
|
425
|
-
id: "peer1",
|
|
426
|
-
role: "storage",
|
|
427
|
-
},
|
|
428
|
-
async () => {
|
|
429
|
-
return new Promise(() => {});
|
|
430
|
-
},
|
|
431
|
-
);
|
|
432
|
-
const peer2 = createMockPeerState(
|
|
433
|
-
{
|
|
434
|
-
id: "peer2",
|
|
435
|
-
role: "server",
|
|
436
|
-
},
|
|
437
|
-
async () => {
|
|
438
|
-
state.markAvailable(mockCoValue, "peer2");
|
|
439
|
-
},
|
|
440
|
-
);
|
|
441
|
-
|
|
442
|
-
peer1.closed = true;
|
|
443
|
-
|
|
444
|
-
const state = new CoValueState(mockCoValueId);
|
|
445
|
-
const loadPromise = state.loadFromPeers([peer1, peer2]);
|
|
446
|
-
|
|
447
|
-
for (let i = 0; i < CO_VALUE_LOADING_CONFIG.MAX_RETRIES; i++) {
|
|
448
|
-
await vi.runAllTimersAsync();
|
|
449
|
-
}
|
|
450
|
-
await loadPromise;
|
|
451
|
-
|
|
452
|
-
expect(peer1.pushOutgoingMessage).toHaveBeenCalledTimes(0);
|
|
453
|
-
expect(peer2.pushOutgoingMessage).toHaveBeenCalledTimes(1);
|
|
454
|
-
|
|
455
|
-
expect(state.highLevelState).toBe("available");
|
|
456
|
-
await expect(state.getCoValue()).resolves.toEqual({ id: mockCoValueId });
|
|
457
|
-
|
|
458
|
-
vi.useRealTimers();
|
|
459
|
-
});
|
|
460
|
-
|
|
461
|
-
test("should not be stuck in loading state when not getting a response", async () => {
|
|
462
|
-
vi.useFakeTimers();
|
|
463
|
-
|
|
464
|
-
const peer1 = createMockPeerState(
|
|
465
|
-
{
|
|
466
|
-
id: "peer1",
|
|
467
|
-
role: "server",
|
|
468
|
-
},
|
|
469
|
-
async () => {},
|
|
470
|
-
);
|
|
471
|
-
|
|
472
|
-
const state = new CoValueState(mockCoValueId);
|
|
473
|
-
const loadPromise = state.loadFromPeers([peer1]);
|
|
474
|
-
|
|
475
|
-
for (let i = 0; i < CO_VALUE_LOADING_CONFIG.MAX_RETRIES * 2; i++) {
|
|
476
|
-
await vi.runAllTimersAsync();
|
|
477
|
-
}
|
|
478
|
-
await loadPromise;
|
|
479
|
-
|
|
480
|
-
expect(peer1.pushOutgoingMessage).toHaveBeenCalledTimes(
|
|
481
|
-
CO_VALUE_LOADING_CONFIG.MAX_RETRIES,
|
|
482
|
-
);
|
|
483
|
-
|
|
484
|
-
expect(state.highLevelState).toBe("unavailable");
|
|
485
|
-
await expect(state.getCoValue()).resolves.toEqual("unavailable");
|
|
486
|
-
|
|
487
|
-
vi.useRealTimers();
|
|
488
|
-
});
|
|
489
|
-
});
|
|
490
|
-
|
|
491
|
-
function createMockPeerState(
|
|
492
|
-
peer: Partial<Peer>,
|
|
493
|
-
pushFn = () => Promise.resolve(),
|
|
494
|
-
) {
|
|
495
|
-
const peerState = new PeerState(
|
|
496
|
-
{
|
|
497
|
-
id: "peer",
|
|
498
|
-
role: "server",
|
|
499
|
-
outgoing: {
|
|
500
|
-
push: pushFn,
|
|
501
|
-
},
|
|
502
|
-
...peer,
|
|
503
|
-
} as Peer,
|
|
504
|
-
undefined,
|
|
505
|
-
);
|
|
506
|
-
|
|
507
|
-
vi.spyOn(peerState, "pushOutgoingMessage").mockImplementation(pushFn);
|
|
508
|
-
|
|
509
|
-
return peerState;
|
|
510
|
-
}
|
|
511
|
-
|
|
512
|
-
function createMockCoValueCore(mockCoValueId: string) {
|
|
513
|
-
// Setting the knownState as part of the prototype to simplify
|
|
514
|
-
// the equality checks
|
|
515
|
-
const mockCoValue = Object.create({
|
|
516
|
-
knownState: vi.fn().mockReturnValue({
|
|
517
|
-
id: mockCoValueId,
|
|
518
|
-
header: true,
|
|
519
|
-
sessions: {},
|
|
520
|
-
}),
|
|
521
|
-
});
|
|
522
|
-
|
|
523
|
-
mockCoValue.id = mockCoValueId;
|
|
524
|
-
return mockCoValue as unknown as CoValueCore;
|
|
525
|
-
}
|