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.
Files changed (72) hide show
  1. package/.turbo/turbo-build.log +1 -1
  2. package/CHANGELOG.md +12 -0
  3. package/dist/CoValuesStore.d.ts +3 -1
  4. package/dist/CoValuesStore.d.ts.map +1 -1
  5. package/dist/CoValuesStore.js +7 -6
  6. package/dist/CoValuesStore.js.map +1 -1
  7. package/dist/PeerState.d.ts +0 -2
  8. package/dist/PeerState.d.ts.map +1 -1
  9. package/dist/PeerState.js +0 -1
  10. package/dist/PeerState.js.map +1 -1
  11. package/dist/SyncStateManager.js +2 -2
  12. package/dist/SyncStateManager.js.map +1 -1
  13. package/dist/coValueCore.js +2 -2
  14. package/dist/coValueCore.js.map +1 -1
  15. package/dist/coValueState.d.ts +21 -46
  16. package/dist/coValueState.d.ts.map +1 -1
  17. package/dist/coValueState.js +170 -246
  18. package/dist/coValueState.js.map +1 -1
  19. package/dist/coValues/group.js +2 -2
  20. package/dist/coValues/group.js.map +1 -1
  21. package/dist/exports.d.ts +2 -4
  22. package/dist/exports.d.ts.map +1 -1
  23. package/dist/exports.js +1 -2
  24. package/dist/exports.js.map +1 -1
  25. package/dist/localNode.d.ts.map +1 -1
  26. package/dist/localNode.js +20 -16
  27. package/dist/localNode.js.map +1 -1
  28. package/dist/sync.d.ts.map +1 -1
  29. package/dist/sync.js +32 -41
  30. package/dist/sync.js.map +1 -1
  31. package/dist/tests/coValueState.test.js +57 -104
  32. package/dist/tests/coValueState.test.js.map +1 -1
  33. package/dist/tests/group.test.js +1 -2
  34. package/dist/tests/group.test.js.map +1 -1
  35. package/dist/tests/messagesTestUtils.d.ts +4 -1
  36. package/dist/tests/messagesTestUtils.d.ts.map +1 -1
  37. package/dist/tests/messagesTestUtils.js +10 -0
  38. package/dist/tests/messagesTestUtils.js.map +1 -1
  39. package/dist/tests/sync.peerReconciliation.test.js +8 -8
  40. package/dist/tests/sync.peerReconciliation.test.js.map +1 -1
  41. package/dist/tests/sync.test.js +6 -4
  42. package/dist/tests/sync.test.js.map +1 -1
  43. package/package.json +1 -1
  44. package/src/CoValuesStore.ts +9 -6
  45. package/src/PeerState.ts +0 -2
  46. package/src/SyncStateManager.ts +2 -2
  47. package/src/coValueCore.ts +2 -2
  48. package/src/coValueState.ts +194 -316
  49. package/src/coValues/group.ts +2 -2
  50. package/src/exports.ts +0 -6
  51. package/src/localNode.ts +30 -21
  52. package/src/sync.ts +35 -43
  53. package/src/tests/coValueState.test.ts +55 -106
  54. package/src/tests/group.test.ts +2 -2
  55. package/src/tests/messagesTestUtils.ts +12 -1
  56. package/src/tests/sync.peerReconciliation.test.ts +8 -8
  57. package/src/tests/sync.test.ts +8 -23
  58. package/dist/storage/FileSystem.d.ts +0 -37
  59. package/dist/storage/FileSystem.d.ts.map +0 -1
  60. package/dist/storage/FileSystem.js +0 -48
  61. package/dist/storage/FileSystem.js.map +0 -1
  62. package/dist/storage/chunksAndKnownStates.d.ts +0 -7
  63. package/dist/storage/chunksAndKnownStates.d.ts.map +0 -1
  64. package/dist/storage/chunksAndKnownStates.js +0 -98
  65. package/dist/storage/chunksAndKnownStates.js.map +0 -1
  66. package/dist/storage/index.d.ts +0 -52
  67. package/dist/storage/index.d.ts.map +0 -1
  68. package/dist/storage/index.js +0 -335
  69. package/dist/storage/index.js.map +0 -1
  70. package/src/storage/FileSystem.ts +0 -113
  71. package/src/storage/chunksAndKnownStates.ts +0 -137
  72. 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.setAsAvailable(
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.state.type === "available") {
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.setAsAvailable(accountID, controlledAccount.core);
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.setAsAvailable(coValue.id, coValue);
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 (entry.state.type === "unknown" || entry.state.type === "unavailable") {
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.state.type === "available") {
313
- return entry.state.coValue.getCurrentContent() as T;
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.state.type !== "available") {
450
+ if (!entry.isAvailable()) {
443
451
  throw new Error(
444
- `${expectation ? expectation + ": " : ""}CoValue ${id} not yet loaded. Current state: ${entry.state.type}`,
452
+ `${expectation ? expectation + ": " : ""}CoValue ${id} not yet loaded. Current state: ${JSON.stringify(entry)}`,
445
453
  );
446
454
  }
447
- return entry.state.coValue;
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.state.type !== "available") {
649
+ if (!entry.isAvailable()) {
642
650
  coValuesToCopy.pop();
643
651
  continue;
644
652
  } else {
645
- const allDepsCopied = entry.state.coValue
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.state.coValue.header,
664
+ entry.core.header,
659
665
  newNode,
660
- new Map(entry.state.coValue.sessionLogs),
666
+ new Map(entry.core.sessionLogs),
661
667
  );
662
668
 
663
- newNode.coValuesStore.setAsAvailable(coValueID, newCoValue);
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 (peer.erroredCoValues.has(msg.id)) {
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.state.type === "available") {
255
- buildOrderedCoValueList(entry.state.coValue);
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
- switch (entry.state.type) {
264
- case "unavailable":
265
- // If the coValue is unavailable and we never tried this peer
266
- // we try to load it from the peer
267
- if (!peer.toldKnownState.has(entry.id)) {
268
- await entry.loadFromPeers([peer]).catch((e: unknown) => {
269
- logger.error("Error sending load", { err: e });
270
- });
271
- }
272
- break;
273
- case "available":
274
- const coValue = entry.state.coValue;
275
-
276
- // Build the list of coValues ordered by dependency
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 (entry.state.type === "unknown" || entry.state.type === "unavailable") {
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.state.type === "loading") {
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.state.type === "available") {
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
- if (entry.state.type !== "available") {
479
- const availableOnPeer = peer.optimisticKnownStates.get(msg.id)?.header;
478
+ const availableOnPeer = peer.optimisticKnownStates.get(msg.id)?.header;
480
479
 
481
- if (!availableOnPeer) {
482
- entry.dispatch({
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.state.type === "available") {
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.state.type !== "available") {
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.dispatch({
537
- type: "available",
538
- coValue,
539
- });
529
+ entry.markAvailable(coValue, peer.id);
540
530
  } else {
541
- coValue = entry.state.coValue;
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
- peer.erroredCoValues.set(msg.id, result.error);
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 (peer.erroredCoValues.has(coValue.id)) continue;
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.state.type === "available" || coValue.state.type === "loading",
720
+ coValue.highLevelState === "available" ||
721
+ coValue.highLevelState === "loading",
730
722
  );
731
723
 
732
724
  return Promise.all(