cojson 0.18.18 → 0.18.20
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/GarbageCollector.d.ts +2 -1
- package/dist/GarbageCollector.d.ts.map +1 -1
- package/dist/GarbageCollector.js +3 -2
- package/dist/GarbageCollector.js.map +1 -1
- package/dist/coValueCore/coValueCore.d.ts +28 -25
- package/dist/coValueCore/coValueCore.d.ts.map +1 -1
- package/dist/coValueCore/coValueCore.js +128 -90
- package/dist/coValueCore/coValueCore.js.map +1 -1
- package/dist/coValueCore/utils.d.ts +6 -0
- package/dist/coValueCore/utils.d.ts.map +1 -1
- package/dist/coValueCore/utils.js +53 -25
- package/dist/coValueCore/utils.js.map +1 -1
- package/dist/localNode.d.ts +5 -4
- package/dist/localNode.d.ts.map +1 -1
- package/dist/localNode.js +31 -37
- package/dist/localNode.js.map +1 -1
- package/dist/sync.d.ts.map +1 -1
- package/dist/sync.js +56 -69
- package/dist/sync.js.map +1 -1
- package/dist/tests/GarbageCollector.test.js +14 -0
- package/dist/tests/GarbageCollector.test.js.map +1 -1
- package/dist/tests/SyncStateManager.test.js +1 -1
- package/dist/tests/coValueCore.dependencies.test.d.ts +2 -0
- package/dist/tests/coValueCore.dependencies.test.d.ts.map +1 -0
- package/dist/tests/coValueCore.dependencies.test.js +55 -0
- package/dist/tests/coValueCore.dependencies.test.js.map +1 -0
- package/dist/tests/coValueCore.test.js +2 -2
- package/dist/tests/coValueCore.test.js.map +1 -1
- package/dist/tests/coValueCoreLoadingState.test.js +43 -62
- package/dist/tests/coValueCoreLoadingState.test.js.map +1 -1
- package/dist/tests/permissions.test.js +117 -117
- package/dist/tests/permissions.test.js.map +1 -1
- package/dist/tests/sync.load.test.js +238 -9
- package/dist/tests/sync.load.test.js.map +1 -1
- package/dist/tests/sync.peerReconciliation.test.js +7 -6
- package/dist/tests/sync.peerReconciliation.test.js.map +1 -1
- package/dist/tests/testUtils.d.ts.map +1 -1
- package/dist/tests/testUtils.js +2 -1
- package/dist/tests/testUtils.js.map +1 -1
- package/package.json +2 -2
- package/src/GarbageCollector.ts +5 -2
- package/src/coValueCore/coValueCore.ts +172 -118
- package/src/coValueCore/utils.ts +85 -31
- package/src/localNode.ts +43 -48
- package/src/sync.ts +63 -89
- package/src/tests/GarbageCollector.test.ts +20 -0
- package/src/tests/SyncStateManager.test.ts +1 -1
- package/src/tests/coValueCore.dependencies.test.ts +90 -0
- package/src/tests/coValueCore.test.ts +2 -2
- package/src/tests/coValueCoreLoadingState.test.ts +50 -66
- package/src/tests/permissions.test.ts +120 -123
- package/src/tests/sync.load.test.ts +308 -9
- package/src/tests/sync.peerReconciliation.test.ts +7 -6
- package/src/tests/testUtils.ts +5 -3
|
@@ -1,8 +1,7 @@
|
|
|
1
1
|
import { afterEach, beforeEach, describe, expect, test, vi } from "vitest";
|
|
2
2
|
import { PeerState } from "../PeerState";
|
|
3
3
|
import { CoValueCore, idforHeader } from "../coValueCore/coValueCore";
|
|
4
|
-
import { createTestMetricReader, tearDownTestMetricReader } from "./testUtils";
|
|
5
|
-
import { WasmCrypto } from "../crypto/WasmCrypto";
|
|
4
|
+
import { createTestMetricReader, createTestNode, tearDownTestMetricReader, } from "./testUtils";
|
|
6
5
|
let metricReader;
|
|
7
6
|
beforeEach(() => {
|
|
8
7
|
metricReader = createTestMetricReader();
|
|
@@ -10,55 +9,55 @@ beforeEach(() => {
|
|
|
10
9
|
afterEach(() => {
|
|
11
10
|
tearDownTestMetricReader();
|
|
12
11
|
});
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
const
|
|
12
|
+
function setup() {
|
|
13
|
+
const node = createTestNode();
|
|
14
|
+
const header = {
|
|
15
|
+
type: "comap",
|
|
16
|
+
ruleset: { type: "ownedByGroup", group: "co_ztest123" },
|
|
17
|
+
meta: null,
|
|
18
|
+
...node.crypto.createdNowUnique(),
|
|
19
|
+
};
|
|
20
|
+
const id = idforHeader(header, node.crypto);
|
|
21
|
+
const state = CoValueCore.fromID(id, node);
|
|
22
|
+
return { node, state, id, header };
|
|
23
|
+
}
|
|
23
24
|
describe("CoValueCore loading state", () => {
|
|
24
|
-
const mockCoValueId = testCoValueId;
|
|
25
25
|
test("should create unknown state", async () => {
|
|
26
|
-
const state =
|
|
27
|
-
expect(state.id).toBe(
|
|
26
|
+
const { state, id } = setup();
|
|
27
|
+
expect(state.id).toBe(id);
|
|
28
28
|
expect(state.loadingState).toBe("unknown");
|
|
29
29
|
expect(await metricReader.getMetricValue("jazz.covalues.loaded", {
|
|
30
30
|
state: "unknown",
|
|
31
31
|
})).toBe(1);
|
|
32
32
|
});
|
|
33
33
|
test("should create loading state", async () => {
|
|
34
|
-
const state =
|
|
34
|
+
const { state, id } = setup();
|
|
35
35
|
state.loadFromPeers([
|
|
36
36
|
createMockPeerState({ id: "peer1", role: "server" }),
|
|
37
37
|
createMockPeerState({ id: "peer2", role: "server" }),
|
|
38
38
|
]);
|
|
39
|
-
expect(state.id).toBe(
|
|
39
|
+
expect(state.id).toBe(id);
|
|
40
40
|
expect(state.loadingState).toBe("loading");
|
|
41
41
|
expect(await metricReader.getMetricValue("jazz.covalues.loaded", {
|
|
42
42
|
state: "loading",
|
|
43
43
|
})).toBe(1);
|
|
44
44
|
});
|
|
45
45
|
test("should create available state", async () => {
|
|
46
|
-
const
|
|
47
|
-
const
|
|
48
|
-
state.
|
|
49
|
-
|
|
46
|
+
const { state, id, header } = setup();
|
|
47
|
+
const previousState = state.loadingState;
|
|
48
|
+
state.provideHeader(header);
|
|
49
|
+
state.markFoundInPeer("peer1", previousState);
|
|
50
|
+
expect(state.id).toBe(id);
|
|
50
51
|
expect(state.loadingState).toBe("available");
|
|
51
|
-
expect(state.verified).toBe(mockVerified);
|
|
52
52
|
await expect(state.waitForAvailableOrUnavailable()).resolves.toMatchObject({
|
|
53
|
-
verified:
|
|
53
|
+
verified: expect.any(Object),
|
|
54
54
|
});
|
|
55
55
|
expect(await metricReader.getMetricValue("jazz.covalues.loaded", {
|
|
56
56
|
state: "available",
|
|
57
57
|
})).toBe(1);
|
|
58
58
|
});
|
|
59
59
|
test("should handle found action", async () => {
|
|
60
|
-
const
|
|
61
|
-
const state = CoValueCore.fromID(mockCoValueId, mockNode);
|
|
60
|
+
const { state, header } = setup();
|
|
62
61
|
state.loadFromPeers([
|
|
63
62
|
createMockPeerState({ id: "peer1", role: "server" }),
|
|
64
63
|
createMockPeerState({ id: "peer2", role: "server" }),
|
|
@@ -70,12 +69,10 @@ describe("CoValueCore loading state", () => {
|
|
|
70
69
|
state: "loading",
|
|
71
70
|
})).toBe(1);
|
|
72
71
|
const stateValuePromise = state.waitForAvailableOrUnavailable();
|
|
73
|
-
state.
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
await
|
|
77
|
-
verified: mockVerified,
|
|
78
|
-
});
|
|
72
|
+
const previousState = state.loadingState;
|
|
73
|
+
state.provideHeader(header);
|
|
74
|
+
state.markFoundInPeer("peer1", previousState);
|
|
75
|
+
await stateValuePromise;
|
|
79
76
|
expect(await metricReader.getMetricValue("jazz.covalues.loaded", {
|
|
80
77
|
state: "available",
|
|
81
78
|
})).toBe(1);
|
|
@@ -84,6 +81,7 @@ describe("CoValueCore loading state", () => {
|
|
|
84
81
|
})).toBe(0);
|
|
85
82
|
});
|
|
86
83
|
test("should skip errored coValues when loading from peers", async () => {
|
|
84
|
+
const { state } = setup();
|
|
87
85
|
vi.useFakeTimers();
|
|
88
86
|
const peer1 = createMockPeerState({
|
|
89
87
|
id: "peer1",
|
|
@@ -98,7 +96,6 @@ describe("CoValueCore loading state", () => {
|
|
|
98
96
|
state.markNotFoundInPeer("peer2");
|
|
99
97
|
});
|
|
100
98
|
const mockPeers = [peer1, peer2];
|
|
101
|
-
const state = CoValueCore.fromID(mockCoValueId, mockNode);
|
|
102
99
|
const loadPromise = state.loadFromPeers(mockPeers);
|
|
103
100
|
await vi.runAllTimersAsync();
|
|
104
101
|
await loadPromise;
|
|
@@ -111,6 +108,7 @@ describe("CoValueCore loading state", () => {
|
|
|
111
108
|
vi.useRealTimers();
|
|
112
109
|
});
|
|
113
110
|
test("should have a coValue as value property when becomes available after that have been marked as unavailable", async () => {
|
|
111
|
+
const { state, header } = setup();
|
|
114
112
|
vi.useFakeTimers();
|
|
115
113
|
const peer1 = createMockPeerState({
|
|
116
114
|
id: "peer1",
|
|
@@ -119,10 +117,11 @@ describe("CoValueCore loading state", () => {
|
|
|
119
117
|
state.markNotFoundInPeer("peer1");
|
|
120
118
|
});
|
|
121
119
|
const mockPeers = [peer1];
|
|
122
|
-
const state = CoValueCore.fromID(mockCoValueId, mockNode);
|
|
123
120
|
const loadPromise = state.loadFromPeers(mockPeers);
|
|
124
121
|
await vi.runAllTimersAsync();
|
|
125
|
-
state.
|
|
122
|
+
const previousState = state.loadingState;
|
|
123
|
+
state.provideHeader(header);
|
|
124
|
+
state.markFoundInPeer("peer1", previousState);
|
|
126
125
|
await loadPromise;
|
|
127
126
|
expect(peer1.pushOutgoingMessage).toHaveBeenCalledTimes(1);
|
|
128
127
|
expect(state.loadingState).toBe("available");
|
|
@@ -133,12 +132,14 @@ describe("CoValueCore loading state", () => {
|
|
|
133
132
|
});
|
|
134
133
|
test("should start sending the known state to peers when available", async () => {
|
|
135
134
|
vi.useFakeTimers();
|
|
136
|
-
const
|
|
135
|
+
const { state, header } = setup();
|
|
137
136
|
const peer1 = createMockPeerState({
|
|
138
137
|
id: "peer1",
|
|
139
138
|
role: "server",
|
|
140
139
|
}, async () => {
|
|
141
|
-
state.
|
|
140
|
+
const previousState = state.loadingState;
|
|
141
|
+
state.provideHeader(header);
|
|
142
|
+
state.markFoundInPeer("peer1", previousState);
|
|
142
143
|
});
|
|
143
144
|
const peer2 = createMockPeerState({
|
|
144
145
|
id: "peer2",
|
|
@@ -146,7 +147,6 @@ describe("CoValueCore loading state", () => {
|
|
|
146
147
|
}, async () => {
|
|
147
148
|
state.markNotFoundInPeer("peer2");
|
|
148
149
|
});
|
|
149
|
-
const state = CoValueCore.fromID(mockCoValueId, mockNode);
|
|
150
150
|
const loadPromise = state.loadFromPeers([peer1, peer2]);
|
|
151
151
|
await vi.runAllTimersAsync();
|
|
152
152
|
await loadPromise;
|
|
@@ -154,17 +154,14 @@ describe("CoValueCore loading state", () => {
|
|
|
154
154
|
expect(peer2.pushOutgoingMessage).toHaveBeenCalledTimes(1);
|
|
155
155
|
expect(peer2.pushOutgoingMessage).toHaveBeenCalledWith({
|
|
156
156
|
action: "load",
|
|
157
|
-
...
|
|
157
|
+
...state.knownState(),
|
|
158
158
|
});
|
|
159
159
|
expect(state.loadingState).toBe("available");
|
|
160
|
-
await expect(state.waitForAvailableOrUnavailable()).resolves.toMatchObject({
|
|
161
|
-
verified: mockVerified,
|
|
162
|
-
});
|
|
163
160
|
vi.useRealTimers();
|
|
164
161
|
});
|
|
165
162
|
test("should skip closed peers", async () => {
|
|
166
163
|
vi.useFakeTimers();
|
|
167
|
-
const
|
|
164
|
+
const { state, header } = setup();
|
|
168
165
|
const peer1 = createMockPeerState({
|
|
169
166
|
id: "peer1",
|
|
170
167
|
role: "server",
|
|
@@ -175,19 +172,17 @@ describe("CoValueCore loading state", () => {
|
|
|
175
172
|
id: "peer2",
|
|
176
173
|
role: "server",
|
|
177
174
|
}, async () => {
|
|
178
|
-
state.
|
|
175
|
+
const previousState = state.loadingState;
|
|
176
|
+
state.provideHeader(header);
|
|
177
|
+
state.markFoundInPeer("peer2", previousState);
|
|
179
178
|
});
|
|
180
179
|
peer1.closed = true;
|
|
181
|
-
const state = CoValueCore.fromID(mockCoValueId, mockNode);
|
|
182
180
|
const loadPromise = state.loadFromPeers([peer1, peer2]);
|
|
183
181
|
await vi.runAllTimersAsync();
|
|
184
182
|
await loadPromise;
|
|
185
183
|
expect(peer1.pushOutgoingMessage).toHaveBeenCalledTimes(0);
|
|
186
184
|
expect(peer2.pushOutgoingMessage).toHaveBeenCalledTimes(1);
|
|
187
185
|
expect(state.loadingState).toBe("available");
|
|
188
|
-
await expect(state.waitForAvailableOrUnavailable()).resolves.toMatchObject({
|
|
189
|
-
verified: mockVerified,
|
|
190
|
-
});
|
|
191
186
|
vi.useRealTimers();
|
|
192
187
|
});
|
|
193
188
|
test("should not be stuck in loading state when not getting a response", async () => {
|
|
@@ -196,7 +191,7 @@ describe("CoValueCore loading state", () => {
|
|
|
196
191
|
id: "peer1",
|
|
197
192
|
role: "server",
|
|
198
193
|
}, async () => { });
|
|
199
|
-
const state =
|
|
194
|
+
const { state } = setup();
|
|
200
195
|
const loadPromise = state.loadFromPeers([peer1]);
|
|
201
196
|
await vi.runAllTimersAsync();
|
|
202
197
|
await loadPromise;
|
|
@@ -220,18 +215,4 @@ function createMockPeerState(peer, pushFn = () => Promise.resolve()) {
|
|
|
220
215
|
vi.spyOn(peerState, "pushOutgoingMessage").mockImplementation(pushFn);
|
|
221
216
|
return peerState;
|
|
222
217
|
}
|
|
223
|
-
function createMockCoValueVerified(mockCoValueId) {
|
|
224
|
-
// Setting the knownState as part of the prototype to simplify
|
|
225
|
-
// the equality checks
|
|
226
|
-
const mockCoValueVerified = Object.create({
|
|
227
|
-
id: mockCoValueId,
|
|
228
|
-
knownState: vi.fn().mockReturnValue({
|
|
229
|
-
id: mockCoValueId,
|
|
230
|
-
header: true,
|
|
231
|
-
sessions: {},
|
|
232
|
-
}),
|
|
233
|
-
clone: vi.fn().mockReturnThis(),
|
|
234
|
-
});
|
|
235
|
-
return mockCoValueVerified;
|
|
236
|
-
}
|
|
237
218
|
//# sourceMappingURL=coValueCoreLoadingState.test.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"coValueCoreLoadingState.test.js","sourceRoot":"","sources":["../../src/tests/coValueCoreLoadingState.test.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,UAAU,EAAE,QAAQ,EAAE,MAAM,EAAE,IAAI,EAAE,EAAE,EAAE,MAAM,QAAQ,CAAC;AAC3E,OAAO,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AACzC,OAAO,EAAE,WAAW,EAAE,WAAW,EAAE,MAAM,4BAA4B,CAAC;AAKtE,OAAO,
|
|
1
|
+
{"version":3,"file":"coValueCoreLoadingState.test.js","sourceRoot":"","sources":["../../src/tests/coValueCoreLoadingState.test.ts"],"names":[],"mappings":"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"}
|