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
package/src/permissions.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { CoID } from "./coValue.js";
|
|
2
|
-
import { CoValueCore
|
|
2
|
+
import { CoValueCore } from "./coValueCore/coValueCore.js";
|
|
3
|
+
import { Transaction } from "./coValueCore/verifiedState.js";
|
|
3
4
|
import { RawAccount, RawAccountID, RawProfile } from "./coValues/account.js";
|
|
4
5
|
import { MapOpPayload } from "./coValues/coMap.js";
|
|
5
6
|
import {
|
|
@@ -64,19 +65,23 @@ export function determineValidTransactions(
|
|
|
64
65
|
coValue: CoValueCore,
|
|
65
66
|
knownTransactions?: CoValueKnownState["sessions"],
|
|
66
67
|
): { txID: TransactionID; tx: Transaction }[] {
|
|
67
|
-
if (coValue.
|
|
68
|
-
|
|
68
|
+
if (!coValue.isAvailable()) {
|
|
69
|
+
throw new Error("determineValidTransactions CoValue is not available");
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
if (coValue.verified.header.ruleset.type === "group") {
|
|
73
|
+
const initialAdmin = coValue.verified.header.ruleset.initialAdmin;
|
|
69
74
|
if (!initialAdmin) {
|
|
70
75
|
throw new Error("Group must have initialAdmin");
|
|
71
76
|
}
|
|
72
77
|
|
|
73
78
|
return determineValidTransactionsForGroup(coValue, initialAdmin)
|
|
74
79
|
.validTransactions;
|
|
75
|
-
} else if (coValue.header.ruleset.type === "ownedByGroup") {
|
|
80
|
+
} else if (coValue.verified.header.ruleset.type === "ownedByGroup") {
|
|
76
81
|
const groupContent = expectGroup(
|
|
77
82
|
coValue.node
|
|
78
83
|
.expectCoValueLoaded(
|
|
79
|
-
coValue.header.ruleset.group,
|
|
84
|
+
coValue.verified.header.ruleset.group,
|
|
80
85
|
"Determining valid transaction in owned object but its group wasn't loaded",
|
|
81
86
|
)
|
|
82
87
|
.getCurrentContent(),
|
|
@@ -88,7 +93,7 @@ export function determineValidTransactions(
|
|
|
88
93
|
|
|
89
94
|
const validTransactions: ValidTransactionsResult[] = [];
|
|
90
95
|
|
|
91
|
-
for (const [sessionID, sessionLog] of coValue.
|
|
96
|
+
for (const [sessionID, sessionLog] of coValue.verified.sessions.entries()) {
|
|
92
97
|
const transactor = accountOrAgentIDfromSessionID(sessionID);
|
|
93
98
|
const knownTransactionsForSession = knownTransactions?.[sessionID] ?? -1;
|
|
94
99
|
|
|
@@ -123,10 +128,10 @@ export function determineValidTransactions(
|
|
|
123
128
|
}
|
|
124
129
|
|
|
125
130
|
return validTransactions;
|
|
126
|
-
} else if (coValue.header.ruleset.type === "unsafeAllowAll") {
|
|
131
|
+
} else if (coValue.verified.header.ruleset.type === "unsafeAllowAll") {
|
|
127
132
|
const validTransactions: ValidTransactionsResult[] = [];
|
|
128
133
|
|
|
129
|
-
for (const [sessionID, sessionLog] of coValue.
|
|
134
|
+
for (const [sessionID, sessionLog] of coValue.verified.sessions.entries()) {
|
|
130
135
|
const knownTransactionsForSession = knownTransactions?.[sessionID] ?? -1;
|
|
131
136
|
|
|
132
137
|
sessionLog.transactions.forEach((tx, txIndex) => {
|
|
@@ -141,7 +146,7 @@ export function determineValidTransactions(
|
|
|
141
146
|
} else {
|
|
142
147
|
throw new Error(
|
|
143
148
|
"Unknown ruleset type " +
|
|
144
|
-
(coValue.header.ruleset as { type: string }).type,
|
|
149
|
+
(coValue.verified.header.ruleset as { type: string }).type,
|
|
145
150
|
);
|
|
146
151
|
}
|
|
147
152
|
}
|
|
@@ -167,7 +172,7 @@ function resolveMemberStateFromParentReference(
|
|
|
167
172
|
"Expected parent group to be loaded",
|
|
168
173
|
);
|
|
169
174
|
|
|
170
|
-
if (parentGroup.header.ruleset.type !== "group") {
|
|
175
|
+
if (parentGroup.verified.header.ruleset.type !== "group") {
|
|
171
176
|
return;
|
|
172
177
|
}
|
|
173
178
|
|
|
@@ -176,7 +181,7 @@ function resolveMemberStateFromParentReference(
|
|
|
176
181
|
return;
|
|
177
182
|
}
|
|
178
183
|
|
|
179
|
-
const initialAdmin = parentGroup.header.ruleset.initialAdmin;
|
|
184
|
+
const initialAdmin = parentGroup.verified.header.ruleset.initialAdmin;
|
|
180
185
|
|
|
181
186
|
if (!initialAdmin) {
|
|
182
187
|
throw new Error("Group must have initialAdmin");
|
|
@@ -214,7 +219,8 @@ function determineValidTransactionsForGroup(
|
|
|
214
219
|
tx: Transaction;
|
|
215
220
|
}[] = [];
|
|
216
221
|
|
|
217
|
-
for (const [sessionID, sessionLog] of coValue.
|
|
222
|
+
for (const [sessionID, sessionLog] of coValue.verified?.sessions.entries() ??
|
|
223
|
+
[]) {
|
|
218
224
|
sessionLog.transactions.forEach((tx, txIndex) => {
|
|
219
225
|
allTransactionsSorted.push({ sessionID, txIndex, tx });
|
|
220
226
|
});
|
package/src/priority.ts
CHANGED
package/src/sync.ts
CHANGED
|
@@ -1,9 +1,11 @@
|
|
|
1
1
|
import { Histogram, ValueType, metrics } from "@opentelemetry/api";
|
|
2
2
|
import { PeerState } from "./PeerState.js";
|
|
3
3
|
import { SyncStateManager } from "./SyncStateManager.js";
|
|
4
|
-
import {
|
|
5
|
-
|
|
6
|
-
|
|
4
|
+
import {
|
|
5
|
+
AvailableCoValueCore,
|
|
6
|
+
CoValueCore,
|
|
7
|
+
} from "./coValueCore/coValueCore.js";
|
|
8
|
+
import { CoValueHeader, Transaction } from "./coValueCore/verifiedState.js";
|
|
7
9
|
import { Signature } from "./crypto/crypto.js";
|
|
8
10
|
import { RawCoID, SessionID } from "./ids.js";
|
|
9
11
|
import { LocalNode } from "./localNode.js";
|
|
@@ -158,7 +160,7 @@ export class SyncManager {
|
|
|
158
160
|
}
|
|
159
161
|
|
|
160
162
|
handleSyncMessage(msg: SyncMessage, peer: PeerState) {
|
|
161
|
-
if (this.local.
|
|
163
|
+
if (this.local.getCoValue(msg.id).isErroredInPeer(peer.id)) {
|
|
162
164
|
logger.warn(
|
|
163
165
|
`Skipping message ${msg.action} on errored coValue ${msg.id} from peer ${peer.id}`,
|
|
164
166
|
);
|
|
@@ -197,13 +199,17 @@ export class SyncManager {
|
|
|
197
199
|
}
|
|
198
200
|
|
|
199
201
|
sendNewContentIncludingDependencies(id: RawCoID, peer: PeerState) {
|
|
200
|
-
const coValue = this.local.
|
|
202
|
+
const coValue = this.local.getCoValue(id);
|
|
203
|
+
|
|
204
|
+
if (!coValue.isAvailable()) {
|
|
205
|
+
return;
|
|
206
|
+
}
|
|
201
207
|
|
|
202
208
|
coValue
|
|
203
209
|
.getDependedOnCoValues()
|
|
204
210
|
.map((id) => this.sendNewContentIncludingDependencies(id, peer));
|
|
205
211
|
|
|
206
|
-
const newContentPieces = coValue.newContentSince(
|
|
212
|
+
const newContentPieces = coValue.verified.newContentSince(
|
|
207
213
|
peer.optimisticKnownStates.get(id),
|
|
208
214
|
);
|
|
209
215
|
|
|
@@ -212,16 +218,15 @@ export class SyncManager {
|
|
|
212
218
|
this.trySendToPeer(peer, piece);
|
|
213
219
|
}
|
|
214
220
|
|
|
215
|
-
peer.toldKnownState.add(id);
|
|
216
221
|
peer.combineOptimisticWith(id, coValue.knownState());
|
|
217
222
|
} else if (!peer.toldKnownState.has(id)) {
|
|
218
223
|
this.trySendToPeer(peer, {
|
|
219
224
|
action: "known",
|
|
220
225
|
...coValue.knownState(),
|
|
221
226
|
});
|
|
222
|
-
|
|
223
|
-
peer.toldKnownState.add(id);
|
|
224
227
|
}
|
|
228
|
+
|
|
229
|
+
peer.trackToldKnownState(id);
|
|
225
230
|
}
|
|
226
231
|
|
|
227
232
|
startPeerReconciliation(peer: PeerState) {
|
|
@@ -237,40 +242,38 @@ export class SyncManager {
|
|
|
237
242
|
gathered.add(coValue.id);
|
|
238
243
|
|
|
239
244
|
for (const id of coValue.getDependedOnCoValues()) {
|
|
240
|
-
const
|
|
245
|
+
const coValue = this.local.getCoValue(id);
|
|
241
246
|
|
|
242
|
-
if (
|
|
243
|
-
buildOrderedCoValueList(
|
|
247
|
+
if (coValue.isAvailable()) {
|
|
248
|
+
buildOrderedCoValueList(coValue);
|
|
244
249
|
}
|
|
245
250
|
}
|
|
246
251
|
|
|
247
252
|
coValuesOrderedByDependency.push(coValue);
|
|
248
253
|
};
|
|
249
254
|
|
|
250
|
-
for (const
|
|
251
|
-
if (!
|
|
255
|
+
for (const coValue of this.local.allCoValues()) {
|
|
256
|
+
if (!coValue.isAvailable()) {
|
|
252
257
|
// If the coValue is unavailable and we never tried this peer
|
|
253
258
|
// we try to load it from the peer
|
|
254
|
-
if (!peer.
|
|
255
|
-
peer.
|
|
259
|
+
if (!peer.loadRequestSent.has(coValue.id)) {
|
|
260
|
+
peer.trackLoadRequestSent(coValue.id);
|
|
256
261
|
this.trySendToPeer(peer, {
|
|
257
262
|
action: "load",
|
|
258
263
|
header: false,
|
|
259
|
-
id:
|
|
264
|
+
id: coValue.id,
|
|
260
265
|
sessions: {},
|
|
261
266
|
});
|
|
262
267
|
}
|
|
263
268
|
} else {
|
|
264
|
-
const coValue = entry.core;
|
|
265
|
-
|
|
266
269
|
// Build the list of coValues ordered by dependency
|
|
267
270
|
// so we can send the load message in the correct order
|
|
268
271
|
buildOrderedCoValueList(coValue);
|
|
269
272
|
}
|
|
270
273
|
|
|
271
274
|
// Fill the missing known states with empty known states
|
|
272
|
-
if (!peer.optimisticKnownStates.has(
|
|
273
|
-
peer.setOptimisticKnownState(
|
|
275
|
+
if (!peer.optimisticKnownStates.has(coValue.id)) {
|
|
276
|
+
peer.setOptimisticKnownState(coValue.id, "empty");
|
|
274
277
|
}
|
|
275
278
|
}
|
|
276
279
|
|
|
@@ -281,7 +284,7 @@ export class SyncManager {
|
|
|
281
284
|
* - Start the sync process in case we or the other peer
|
|
282
285
|
* lacks some transactions
|
|
283
286
|
*/
|
|
284
|
-
peer.
|
|
287
|
+
peer.trackLoadRequestSent(coValue.id);
|
|
285
288
|
this.trySendToPeer(peer, {
|
|
286
289
|
action: "load",
|
|
287
290
|
...coValue.knownState(),
|
|
@@ -368,11 +371,11 @@ export class SyncManager {
|
|
|
368
371
|
*
|
|
369
372
|
*/
|
|
370
373
|
peer.setKnownState(msg.id, knownStateIn(msg));
|
|
371
|
-
const
|
|
374
|
+
const coValue = this.local.getCoValue(msg.id);
|
|
372
375
|
|
|
373
376
|
if (
|
|
374
|
-
|
|
375
|
-
|
|
377
|
+
coValue.loadingState === "unknown" ||
|
|
378
|
+
coValue.loadingState === "unavailable"
|
|
376
379
|
) {
|
|
377
380
|
const eligiblePeers = this.getServerAndStoragePeers(peer.id);
|
|
378
381
|
|
|
@@ -380,8 +383,7 @@ export class SyncManager {
|
|
|
380
383
|
// We don't have any eligible peers to load the coValue from
|
|
381
384
|
// so we send a known state back to the sender to let it know
|
|
382
385
|
// that the coValue is unavailable
|
|
383
|
-
peer.
|
|
384
|
-
|
|
386
|
+
peer.trackToldKnownState(msg.id);
|
|
385
387
|
this.trySendToPeer(peer, {
|
|
386
388
|
action: "known",
|
|
387
389
|
id: msg.id,
|
|
@@ -398,17 +400,16 @@ export class SyncManager {
|
|
|
398
400
|
}
|
|
399
401
|
}
|
|
400
402
|
|
|
401
|
-
if (
|
|
403
|
+
if (coValue.loadingState === "loading") {
|
|
402
404
|
// We need to return from handleLoad immediately and wait for the CoValue to be loaded
|
|
403
405
|
// in a new task, otherwise we might block further incoming content messages that would
|
|
404
406
|
// resolve the CoValue as available. This can happen when we receive fresh
|
|
405
407
|
// content from a client, but we are a server with our own upstream server(s)
|
|
406
|
-
|
|
407
|
-
.
|
|
408
|
+
coValue
|
|
409
|
+
.waitForAvailableOrUnavailable()
|
|
408
410
|
.then(async (value) => {
|
|
409
|
-
if (value
|
|
410
|
-
peer.
|
|
411
|
-
|
|
411
|
+
if (!value.isAvailable()) {
|
|
412
|
+
peer.trackToldKnownState(msg.id);
|
|
412
413
|
this.trySendToPeer(peer, {
|
|
413
414
|
action: "known",
|
|
414
415
|
id: msg.id,
|
|
@@ -426,9 +427,10 @@ export class SyncManager {
|
|
|
426
427
|
err: e,
|
|
427
428
|
});
|
|
428
429
|
});
|
|
429
|
-
} else if (
|
|
430
|
+
} else if (coValue.isAvailable()) {
|
|
430
431
|
this.sendNewContentIncludingDependencies(msg.id, peer);
|
|
431
432
|
} else {
|
|
433
|
+
peer.trackToldKnownState(msg.id);
|
|
432
434
|
this.trySendToPeer(peer, {
|
|
433
435
|
action: "known",
|
|
434
436
|
id: msg.id,
|
|
@@ -439,7 +441,7 @@ export class SyncManager {
|
|
|
439
441
|
}
|
|
440
442
|
|
|
441
443
|
handleKnownState(msg: KnownStateMessage, peer: PeerState) {
|
|
442
|
-
const
|
|
444
|
+
const coValue = this.local.getCoValue(msg.id);
|
|
443
445
|
|
|
444
446
|
peer.combineWith(msg.id, knownStateIn(msg));
|
|
445
447
|
|
|
@@ -448,10 +450,10 @@ export class SyncManager {
|
|
|
448
450
|
const availableOnPeer = peer.optimisticKnownStates.get(msg.id)?.header;
|
|
449
451
|
|
|
450
452
|
if (!availableOnPeer) {
|
|
451
|
-
|
|
453
|
+
coValue.markNotFoundInPeer(peer.id);
|
|
452
454
|
}
|
|
453
455
|
|
|
454
|
-
if (
|
|
456
|
+
if (coValue.isAvailable()) {
|
|
455
457
|
this.sendNewContentIncludingDependencies(msg.id, peer);
|
|
456
458
|
}
|
|
457
459
|
}
|
|
@@ -470,11 +472,9 @@ export class SyncManager {
|
|
|
470
472
|
}
|
|
471
473
|
|
|
472
474
|
handleNewContent(msg: NewContentMessage, peer: PeerState) {
|
|
473
|
-
const
|
|
474
|
-
|
|
475
|
-
let coValue: CoValueCore;
|
|
475
|
+
const coValue = this.local.getCoValue(msg.id);
|
|
476
476
|
|
|
477
|
-
if (!
|
|
477
|
+
if (!coValue.isAvailable()) {
|
|
478
478
|
if (!msg.header) {
|
|
479
479
|
this.trySendToPeer(peer, {
|
|
480
480
|
action: "known",
|
|
@@ -487,12 +487,11 @@ export class SyncManager {
|
|
|
487
487
|
}
|
|
488
488
|
|
|
489
489
|
peer.updateHeader(msg.id, true);
|
|
490
|
+
coValue.markAvailable(msg.header, peer.id);
|
|
491
|
+
}
|
|
490
492
|
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
entry.markAvailable(coValue, peer.id);
|
|
494
|
-
} else {
|
|
495
|
-
coValue = entry.core;
|
|
493
|
+
if (!coValue.isAvailable()) {
|
|
494
|
+
throw new Error("Unreachable: CoValue should be available in every case");
|
|
496
495
|
}
|
|
497
496
|
|
|
498
497
|
let invalidStateAssumed = false;
|
|
@@ -502,7 +501,7 @@ export class SyncManager {
|
|
|
502
501
|
SessionNewContent,
|
|
503
502
|
][]) {
|
|
504
503
|
const ourKnownTxIdx =
|
|
505
|
-
coValue.
|
|
504
|
+
coValue.verified.sessions.get(sessionID)?.transactions.length;
|
|
506
505
|
const theirFirstNewTxIdx = newContentForSession.after;
|
|
507
506
|
|
|
508
507
|
if ((ourKnownTxIdx || 0) < theirFirstNewTxIdx) {
|
|
@@ -526,16 +525,17 @@ export class SyncManager {
|
|
|
526
525
|
newTransactions,
|
|
527
526
|
undefined,
|
|
528
527
|
newContentForSession.lastSignature,
|
|
528
|
+
"immediate", // TODO: can we change this to deferred?
|
|
529
529
|
);
|
|
530
530
|
|
|
531
531
|
if (result.isErr()) {
|
|
532
|
-
|
|
532
|
+
console.error("Failed to add transactions", {
|
|
533
533
|
peerId: peer.id,
|
|
534
534
|
peerRole: peer.role,
|
|
535
535
|
id: msg.id,
|
|
536
536
|
err: result.error,
|
|
537
537
|
});
|
|
538
|
-
|
|
538
|
+
coValue.markErrored(peer.id, result.error);
|
|
539
539
|
continue;
|
|
540
540
|
}
|
|
541
541
|
|
|
@@ -555,7 +555,7 @@ export class SyncManager {
|
|
|
555
555
|
isCorrection: true,
|
|
556
556
|
...coValue.knownState(),
|
|
557
557
|
});
|
|
558
|
-
peer.
|
|
558
|
+
peer.trackToldKnownState(msg.id);
|
|
559
559
|
} else {
|
|
560
560
|
/**
|
|
561
561
|
* We are sending a known state message to the peer to acknowledge the
|
|
@@ -568,15 +568,50 @@ export class SyncManager {
|
|
|
568
568
|
action: "known",
|
|
569
569
|
...coValue.knownState(),
|
|
570
570
|
});
|
|
571
|
-
peer.
|
|
571
|
+
peer.trackToldKnownState(msg.id);
|
|
572
572
|
}
|
|
573
573
|
|
|
574
|
-
|
|
575
|
-
|
|
576
|
-
|
|
577
|
-
|
|
578
|
-
|
|
579
|
-
|
|
574
|
+
const sourcePeer = peer;
|
|
575
|
+
const syncedPeers = [];
|
|
576
|
+
|
|
577
|
+
for (const peer of this.peersInPriorityOrder()) {
|
|
578
|
+
/**
|
|
579
|
+
* We sync the content against the source peer if it is a client or server peers
|
|
580
|
+
* to upload any content that is available on the current node and not on the source peer.
|
|
581
|
+
*
|
|
582
|
+
* We don't need to do this with storage peers because we don't get updates from those peers,
|
|
583
|
+
* only load and store content.
|
|
584
|
+
*/
|
|
585
|
+
if (peer.id === sourcePeer.id && sourcePeer.role === "storage") continue;
|
|
586
|
+
if (peer.closed) continue;
|
|
587
|
+
if (coValue.isErroredInPeer(peer.id)) continue;
|
|
588
|
+
|
|
589
|
+
// We directly forward the new content to peers that have an active subscription
|
|
590
|
+
if (peer.optimisticKnownStates.has(coValue.id)) {
|
|
591
|
+
this.sendNewContentIncludingDependencies(coValue.id, peer);
|
|
592
|
+
syncedPeers.push(peer);
|
|
593
|
+
} else if (
|
|
594
|
+
peer.isServerOrStoragePeer() &&
|
|
595
|
+
!peer.loadRequestSent.has(coValue.id)
|
|
596
|
+
) {
|
|
597
|
+
const state = coValue.getStateForPeer(peer.id)?.type;
|
|
598
|
+
|
|
599
|
+
// Check if there is a inflight load operation and we
|
|
600
|
+
// are waiting for other peers to send the load request
|
|
601
|
+
if (state === "unknown" || state === undefined) {
|
|
602
|
+
this.trySendToPeer(peer, {
|
|
603
|
+
action: "load",
|
|
604
|
+
...coValue.knownState(),
|
|
605
|
+
});
|
|
606
|
+
peer.trackLoadRequestSent(coValue.id);
|
|
607
|
+
syncedPeers.push(peer);
|
|
608
|
+
}
|
|
609
|
+
}
|
|
610
|
+
}
|
|
611
|
+
|
|
612
|
+
for (const peer of syncedPeers) {
|
|
613
|
+
this.syncState.triggerUpdate(peer.id, coValue.id);
|
|
614
|
+
}
|
|
580
615
|
}
|
|
581
616
|
|
|
582
617
|
handleCorrection(msg: KnownStateMessage, peer: PeerState) {
|
|
@@ -609,11 +644,9 @@ export class SyncManager {
|
|
|
609
644
|
}
|
|
610
645
|
|
|
611
646
|
async syncCoValue(coValue: CoValueCore) {
|
|
612
|
-
const entry = this.local.coValuesStore.get(coValue.id);
|
|
613
|
-
|
|
614
647
|
for (const peer of this.peersInPriorityOrder()) {
|
|
615
648
|
if (peer.closed) continue;
|
|
616
|
-
if (
|
|
649
|
+
if (coValue.isErroredInPeer(peer.id)) continue;
|
|
617
650
|
|
|
618
651
|
// Only subscribed CoValues are synced to clients
|
|
619
652
|
if (
|
|
@@ -669,11 +702,11 @@ export class SyncManager {
|
|
|
669
702
|
}
|
|
670
703
|
|
|
671
704
|
async waitForAllCoValuesSync(timeout = 60_000) {
|
|
672
|
-
const coValues = this.local.
|
|
705
|
+
const coValues = this.local.allCoValues();
|
|
673
706
|
const validCoValues = Array.from(coValues).filter(
|
|
674
707
|
(coValue) =>
|
|
675
|
-
coValue.
|
|
676
|
-
coValue.
|
|
708
|
+
coValue.loadingState === "available" ||
|
|
709
|
+
coValue.loadingState === "loading",
|
|
677
710
|
);
|
|
678
711
|
|
|
679
712
|
return Promise.all(
|