cojson 0.13.11 → 0.13.13
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 +12 -0
- package/dist/CoValuesStore.d.ts +3 -1
- package/dist/CoValuesStore.d.ts.map +1 -1
- package/dist/CoValuesStore.js +7 -6
- package/dist/CoValuesStore.js.map +1 -1
- package/dist/PeerState.d.ts +0 -2
- package/dist/PeerState.d.ts.map +1 -1
- package/dist/PeerState.js +0 -1
- package/dist/PeerState.js.map +1 -1
- package/dist/SyncStateManager.js +2 -2
- package/dist/SyncStateManager.js.map +1 -1
- package/dist/coValueCore.js +2 -2
- package/dist/coValueCore.js.map +1 -1
- package/dist/coValueState.d.ts +21 -46
- package/dist/coValueState.d.ts.map +1 -1
- package/dist/coValueState.js +170 -246
- package/dist/coValueState.js.map +1 -1
- package/dist/coValues/group.js +2 -2
- package/dist/coValues/group.js.map +1 -1
- package/dist/exports.d.ts +2 -4
- package/dist/exports.d.ts.map +1 -1
- package/dist/exports.js +1 -2
- package/dist/exports.js.map +1 -1
- package/dist/localNode.d.ts.map +1 -1
- package/dist/localNode.js +20 -16
- package/dist/localNode.js.map +1 -1
- package/dist/sync.d.ts.map +1 -1
- package/dist/sync.js +32 -41
- package/dist/sync.js.map +1 -1
- package/dist/tests/coValueState.test.js +57 -104
- package/dist/tests/coValueState.test.js.map +1 -1
- package/dist/tests/group.test.js +1 -2
- package/dist/tests/group.test.js.map +1 -1
- package/dist/tests/messagesTestUtils.d.ts +4 -1
- package/dist/tests/messagesTestUtils.d.ts.map +1 -1
- package/dist/tests/messagesTestUtils.js +10 -0
- package/dist/tests/messagesTestUtils.js.map +1 -1
- package/dist/tests/sync.peerReconciliation.test.js +8 -8
- package/dist/tests/sync.peerReconciliation.test.js.map +1 -1
- package/dist/tests/sync.test.js +6 -4
- package/dist/tests/sync.test.js.map +1 -1
- package/package.json +1 -1
- package/src/CoValuesStore.ts +9 -6
- package/src/PeerState.ts +0 -2
- package/src/SyncStateManager.ts +2 -2
- package/src/coValueCore.ts +2 -2
- package/src/coValueState.ts +194 -316
- package/src/coValues/group.ts +2 -2
- package/src/exports.ts +0 -6
- package/src/localNode.ts +30 -21
- package/src/sync.ts +35 -43
- package/src/tests/coValueState.test.ts +55 -106
- package/src/tests/group.test.ts +2 -2
- package/src/tests/messagesTestUtils.ts +12 -1
- package/src/tests/sync.peerReconciliation.test.ts +8 -8
- package/src/tests/sync.test.ts +8 -23
- package/dist/storage/FileSystem.d.ts +0 -37
- package/dist/storage/FileSystem.d.ts.map +0 -1
- package/dist/storage/FileSystem.js +0 -48
- package/dist/storage/FileSystem.js.map +0 -1
- package/dist/storage/chunksAndKnownStates.d.ts +0 -7
- package/dist/storage/chunksAndKnownStates.d.ts.map +0 -1
- package/dist/storage/chunksAndKnownStates.js +0 -98
- package/dist/storage/chunksAndKnownStates.js.map +0 -1
- package/dist/storage/index.d.ts +0 -52
- package/dist/storage/index.d.ts.map +0 -1
- package/dist/storage/index.js +0 -335
- package/dist/storage/index.js.map +0 -1
- package/src/storage/FileSystem.ts +0 -113
- package/src/storage/chunksAndKnownStates.ts +0 -137
- package/src/storage/index.ts +0 -531
package/src/localNode.ts
CHANGED
|
@@ -126,7 +126,7 @@ export class LocalNode {
|
|
|
126
126
|
);
|
|
127
127
|
|
|
128
128
|
nodeWithAccount.account = controlledAccount;
|
|
129
|
-
nodeWithAccount.coValuesStore.
|
|
129
|
+
nodeWithAccount.coValuesStore.internalMarkMagicallyAvailable(
|
|
130
130
|
controlledAccount.id,
|
|
131
131
|
controlledAccount.core,
|
|
132
132
|
);
|
|
@@ -139,10 +139,8 @@ export class LocalNode {
|
|
|
139
139
|
// we shouldn't need this, but it fixes account data not syncing for new accounts
|
|
140
140
|
function syncAllCoValuesAfterCreateAccount() {
|
|
141
141
|
for (const coValueEntry of nodeWithAccount.coValuesStore.getValues()) {
|
|
142
|
-
if (coValueEntry.
|
|
143
|
-
void nodeWithAccount.syncManager.syncCoValue(
|
|
144
|
-
coValueEntry.state.coValue,
|
|
145
|
-
);
|
|
142
|
+
if (coValueEntry.isAvailable()) {
|
|
143
|
+
void nodeWithAccount.syncManager.syncCoValue(coValueEntry.core);
|
|
146
144
|
}
|
|
147
145
|
}
|
|
148
146
|
}
|
|
@@ -208,7 +206,10 @@ export class LocalNode {
|
|
|
208
206
|
node.syncManager.local = node;
|
|
209
207
|
|
|
210
208
|
controlledAccount.core.node = node;
|
|
211
|
-
node.coValuesStore.
|
|
209
|
+
node.coValuesStore.internalMarkMagicallyAvailable(
|
|
210
|
+
accountID,
|
|
211
|
+
controlledAccount.core,
|
|
212
|
+
);
|
|
212
213
|
controlledAccount.core._cachedContent = undefined;
|
|
213
214
|
|
|
214
215
|
const profileID = account.get("profile");
|
|
@@ -245,7 +246,7 @@ export class LocalNode {
|
|
|
245
246
|
}
|
|
246
247
|
|
|
247
248
|
const coValue = new CoValueCore(header, this);
|
|
248
|
-
this.coValuesStore.
|
|
249
|
+
this.coValuesStore.internalMarkMagicallyAvailable(coValue.id, coValue);
|
|
249
250
|
|
|
250
251
|
void this.syncManager.syncCoValue(coValue);
|
|
251
252
|
|
|
@@ -265,10 +266,17 @@ export class LocalNode {
|
|
|
265
266
|
|
|
266
267
|
const entry = this.coValuesStore.get(id);
|
|
267
268
|
|
|
268
|
-
if (
|
|
269
|
+
if (
|
|
270
|
+
entry.highLevelState === "unknown" ||
|
|
271
|
+
entry.highLevelState === "unavailable"
|
|
272
|
+
) {
|
|
269
273
|
const peers =
|
|
270
274
|
this.syncManager.getServerAndStoragePeers(skipLoadingFromPeer);
|
|
271
275
|
|
|
276
|
+
if (peers.length === 0) {
|
|
277
|
+
return "unavailable";
|
|
278
|
+
}
|
|
279
|
+
|
|
272
280
|
await entry.loadFromPeers(peers).catch((e) => {
|
|
273
281
|
logger.error("Error loading from peers", {
|
|
274
282
|
id,
|
|
@@ -309,8 +317,8 @@ export class LocalNode {
|
|
|
309
317
|
getLoaded<T extends RawCoValue>(id: CoID<T>): T | undefined {
|
|
310
318
|
const entry = this.coValuesStore.get(id);
|
|
311
319
|
|
|
312
|
-
if (entry.
|
|
313
|
-
return entry.
|
|
320
|
+
if (entry.isAvailable()) {
|
|
321
|
+
return entry.core.getCurrentContent() as T;
|
|
314
322
|
}
|
|
315
323
|
|
|
316
324
|
return undefined;
|
|
@@ -439,12 +447,12 @@ export class LocalNode {
|
|
|
439
447
|
expectCoValueLoaded(id: RawCoID, expectation?: string): CoValueCore {
|
|
440
448
|
const entry = this.coValuesStore.get(id);
|
|
441
449
|
|
|
442
|
-
if (entry.
|
|
450
|
+
if (!entry.isAvailable()) {
|
|
443
451
|
throw new Error(
|
|
444
|
-
`${expectation ? expectation + ": " : ""}CoValue ${id} not yet loaded. Current state: ${entry
|
|
452
|
+
`${expectation ? expectation + ": " : ""}CoValue ${id} not yet loaded. Current state: ${JSON.stringify(entry)}`,
|
|
445
453
|
);
|
|
446
454
|
}
|
|
447
|
-
return entry.
|
|
455
|
+
return entry.core;
|
|
448
456
|
}
|
|
449
457
|
|
|
450
458
|
/** @internal */
|
|
@@ -638,15 +646,13 @@ export class LocalNode {
|
|
|
638
646
|
while (coValuesToCopy.length > 0) {
|
|
639
647
|
const [coValueID, entry] = coValuesToCopy[coValuesToCopy.length - 1]!;
|
|
640
648
|
|
|
641
|
-
if (entry.
|
|
649
|
+
if (!entry.isAvailable()) {
|
|
642
650
|
coValuesToCopy.pop();
|
|
643
651
|
continue;
|
|
644
652
|
} else {
|
|
645
|
-
const allDepsCopied = entry.
|
|
653
|
+
const allDepsCopied = entry.core
|
|
646
654
|
.getDependedOnCoValues()
|
|
647
|
-
.every(
|
|
648
|
-
(dep) => newNode.coValuesStore.get(dep).state.type === "available",
|
|
649
|
-
);
|
|
655
|
+
.every((dep) => newNode.coValuesStore.get(dep).isAvailable());
|
|
650
656
|
|
|
651
657
|
if (!allDepsCopied) {
|
|
652
658
|
// move to end of queue
|
|
@@ -655,12 +661,15 @@ export class LocalNode {
|
|
|
655
661
|
}
|
|
656
662
|
|
|
657
663
|
const newCoValue = new CoValueCore(
|
|
658
|
-
entry.
|
|
664
|
+
entry.core.header,
|
|
659
665
|
newNode,
|
|
660
|
-
new Map(entry.
|
|
666
|
+
new Map(entry.core.sessionLogs),
|
|
661
667
|
);
|
|
662
668
|
|
|
663
|
-
newNode.coValuesStore.
|
|
669
|
+
newNode.coValuesStore.internalMarkMagicallyAvailable(
|
|
670
|
+
coValueID,
|
|
671
|
+
newCoValue,
|
|
672
|
+
);
|
|
664
673
|
|
|
665
674
|
coValuesToCopy.pop();
|
|
666
675
|
}
|
package/src/sync.ts
CHANGED
|
@@ -163,7 +163,7 @@ export class SyncManager {
|
|
|
163
163
|
}
|
|
164
164
|
|
|
165
165
|
async handleSyncMessage(msg: SyncMessage, peer: PeerState) {
|
|
166
|
-
if (
|
|
166
|
+
if (this.local.coValuesStore.get(msg.id).isErroredInPeer(peer.id)) {
|
|
167
167
|
logger.warn(
|
|
168
168
|
`Skipping message ${msg.action} on errored coValue ${msg.id} from peer ${peer.id}`,
|
|
169
169
|
);
|
|
@@ -251,8 +251,8 @@ export class SyncManager {
|
|
|
251
251
|
for (const id of coValue.getDependedOnCoValues()) {
|
|
252
252
|
const entry = this.local.coValuesStore.get(id);
|
|
253
253
|
|
|
254
|
-
if (entry.
|
|
255
|
-
buildOrderedCoValueList(entry.
|
|
254
|
+
if (entry.isAvailable()) {
|
|
255
|
+
buildOrderedCoValueList(entry.core);
|
|
256
256
|
}
|
|
257
257
|
}
|
|
258
258
|
|
|
@@ -260,23 +260,20 @@ export class SyncManager {
|
|
|
260
260
|
};
|
|
261
261
|
|
|
262
262
|
for (const entry of this.local.coValuesStore.getValues()) {
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
// so we can send the load message in the correct order
|
|
278
|
-
buildOrderedCoValueList(coValue);
|
|
279
|
-
break;
|
|
263
|
+
if (!entry.isAvailable()) {
|
|
264
|
+
// If the coValue is unavailable and we never tried this peer
|
|
265
|
+
// we try to load it from the peer
|
|
266
|
+
if (!peer.toldKnownState.has(entry.id)) {
|
|
267
|
+
await entry.loadFromPeers([peer]).catch((e: unknown) => {
|
|
268
|
+
logger.error("Error sending load", { err: e });
|
|
269
|
+
});
|
|
270
|
+
}
|
|
271
|
+
} else {
|
|
272
|
+
const coValue = entry.core;
|
|
273
|
+
|
|
274
|
+
// Build the list of coValues ordered by dependency
|
|
275
|
+
// so we can send the load message in the correct order
|
|
276
|
+
buildOrderedCoValueList(coValue);
|
|
280
277
|
}
|
|
281
278
|
|
|
282
279
|
// Fill the missing known states with empty known states
|
|
@@ -399,7 +396,10 @@ export class SyncManager {
|
|
|
399
396
|
peer.setKnownState(msg.id, knownStateIn(msg));
|
|
400
397
|
const entry = this.local.coValuesStore.get(msg.id);
|
|
401
398
|
|
|
402
|
-
if (
|
|
399
|
+
if (
|
|
400
|
+
entry.highLevelState === "unknown" ||
|
|
401
|
+
entry.highLevelState === "unavailable"
|
|
402
|
+
) {
|
|
403
403
|
const eligiblePeers = this.getServerAndStoragePeers(peer.id);
|
|
404
404
|
|
|
405
405
|
if (eligiblePeers.length === 0) {
|
|
@@ -426,7 +426,7 @@ export class SyncManager {
|
|
|
426
426
|
}
|
|
427
427
|
}
|
|
428
428
|
|
|
429
|
-
if (entry.
|
|
429
|
+
if (entry.highLevelState === "loading") {
|
|
430
430
|
// We need to return from handleLoad immediately and wait for the CoValue to be loaded
|
|
431
431
|
// in a new task, otherwise we might block further incoming content messages that would
|
|
432
432
|
// resolve the CoValue as available. This can happen when we receive fresh
|
|
@@ -456,7 +456,7 @@ export class SyncManager {
|
|
|
456
456
|
err: e,
|
|
457
457
|
});
|
|
458
458
|
});
|
|
459
|
-
} else if (entry.
|
|
459
|
+
} else if (entry.isAvailable()) {
|
|
460
460
|
await this.sendNewContentIncludingDependencies(msg.id, peer);
|
|
461
461
|
} else {
|
|
462
462
|
this.trySendToPeer(peer, {
|
|
@@ -475,20 +475,13 @@ export class SyncManager {
|
|
|
475
475
|
|
|
476
476
|
// The header is a boolean value that tells us if the other peer do have information about the header.
|
|
477
477
|
// If it's false in this point it means that the coValue is unavailable on the other peer.
|
|
478
|
-
|
|
479
|
-
const availableOnPeer = peer.optimisticKnownStates.get(msg.id)?.header;
|
|
478
|
+
const availableOnPeer = peer.optimisticKnownStates.get(msg.id)?.header;
|
|
480
479
|
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
type: "not-found-in-peer",
|
|
484
|
-
peerId: peer.id,
|
|
485
|
-
});
|
|
486
|
-
}
|
|
487
|
-
|
|
488
|
-
return;
|
|
480
|
+
if (!availableOnPeer) {
|
|
481
|
+
entry.markNotFoundInPeer(peer.id);
|
|
489
482
|
}
|
|
490
483
|
|
|
491
|
-
if (entry.
|
|
484
|
+
if (entry.isAvailable()) {
|
|
492
485
|
await this.sendNewContentIncludingDependencies(msg.id, peer);
|
|
493
486
|
}
|
|
494
487
|
}
|
|
@@ -511,7 +504,7 @@ export class SyncManager {
|
|
|
511
504
|
|
|
512
505
|
let coValue: CoValueCore;
|
|
513
506
|
|
|
514
|
-
if (entry.
|
|
507
|
+
if (!entry.isAvailable()) {
|
|
515
508
|
if (!msg.header) {
|
|
516
509
|
this.trySendToPeer(peer, {
|
|
517
510
|
action: "known",
|
|
@@ -533,12 +526,9 @@ export class SyncManager {
|
|
|
533
526
|
|
|
534
527
|
coValue = new CoValueCore(msg.header, this.local);
|
|
535
528
|
|
|
536
|
-
entry.
|
|
537
|
-
type: "available",
|
|
538
|
-
coValue,
|
|
539
|
-
});
|
|
529
|
+
entry.markAvailable(coValue, peer.id);
|
|
540
530
|
} else {
|
|
541
|
-
coValue = entry.
|
|
531
|
+
coValue = entry.core;
|
|
542
532
|
}
|
|
543
533
|
|
|
544
534
|
let invalidStateAssumed = false;
|
|
@@ -581,7 +571,7 @@ export class SyncManager {
|
|
|
581
571
|
id: msg.id,
|
|
582
572
|
err: result.error,
|
|
583
573
|
});
|
|
584
|
-
|
|
574
|
+
entry.markErrored(peer.id, result.error);
|
|
585
575
|
continue;
|
|
586
576
|
}
|
|
587
577
|
|
|
@@ -671,7 +661,8 @@ export class SyncManager {
|
|
|
671
661
|
async actuallySyncCoValue(coValue: CoValueCore) {
|
|
672
662
|
for (const peer of this.peersInPriorityOrder()) {
|
|
673
663
|
if (peer.closed) continue;
|
|
674
|
-
if (
|
|
664
|
+
if (this.local.coValuesStore.get(coValue.id).isErroredInPeer(peer.id))
|
|
665
|
+
continue;
|
|
675
666
|
|
|
676
667
|
if (peer.optimisticKnownStates.has(coValue.id)) {
|
|
677
668
|
await this.sendNewContentIncludingDependencies(coValue.id, peer);
|
|
@@ -726,7 +717,8 @@ export class SyncManager {
|
|
|
726
717
|
const coValues = this.local.coValuesStore.getValues();
|
|
727
718
|
const validCoValues = Array.from(coValues).filter(
|
|
728
719
|
(coValue) =>
|
|
729
|
-
coValue.
|
|
720
|
+
coValue.highLevelState === "available" ||
|
|
721
|
+
coValue.highLevelState === "loading",
|
|
730
722
|
);
|
|
731
723
|
|
|
732
724
|
return Promise.all(
|