cojson 0.8.5 → 0.8.12

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 (49) hide show
  1. package/CHANGELOG.md +12 -0
  2. package/dist/native/PeerKnownStates.js +63 -0
  3. package/dist/native/PeerKnownStates.js.map +1 -0
  4. package/dist/native/PeerState.js +5 -1
  5. package/dist/native/PeerState.js.map +1 -1
  6. package/dist/native/coValueState.js +74 -0
  7. package/dist/native/coValueState.js.map +1 -0
  8. package/dist/native/exports.js +39 -0
  9. package/dist/native/exports.js.map +1 -0
  10. package/dist/native/index.native.js +2 -39
  11. package/dist/native/index.native.js.map +1 -1
  12. package/dist/native/localNode.js +29 -51
  13. package/dist/native/localNode.js.map +1 -1
  14. package/dist/native/storage/index.js +2 -2
  15. package/dist/native/storage/index.js.map +1 -1
  16. package/dist/native/sync.js +89 -109
  17. package/dist/native/sync.js.map +1 -1
  18. package/dist/web/PeerKnownStates.js +63 -0
  19. package/dist/web/PeerKnownStates.js.map +1 -0
  20. package/dist/web/PeerState.js +5 -1
  21. package/dist/web/PeerState.js.map +1 -1
  22. package/dist/web/coValueState.js +74 -0
  23. package/dist/web/coValueState.js.map +1 -0
  24. package/dist/web/exports.js +39 -0
  25. package/dist/web/exports.js.map +1 -0
  26. package/dist/web/index.web.js +2 -39
  27. package/dist/web/index.web.js.map +1 -1
  28. package/dist/web/localNode.js +29 -51
  29. package/dist/web/localNode.js.map +1 -1
  30. package/dist/web/storage/index.js +2 -2
  31. package/dist/web/storage/index.js.map +1 -1
  32. package/dist/web/sync.js +89 -109
  33. package/dist/web/sync.js.map +1 -1
  34. package/package.json +1 -1
  35. package/src/PeerKnownStates.ts +108 -0
  36. package/src/PeerState.ts +8 -2
  37. package/src/coValueState.ts +107 -0
  38. package/src/exports.ts +149 -0
  39. package/src/index.native.ts +2 -152
  40. package/src/index.web.ts +2 -152
  41. package/src/localNode.ts +43 -90
  42. package/src/storage/index.ts +2 -2
  43. package/src/sync.ts +95 -148
  44. package/src/tests/PeerKnownStates.test.ts +100 -0
  45. package/src/tests/PeerState.test.ts +0 -11
  46. package/src/tests/sync.test.ts +2 -2
  47. package/.turbo/turbo-build.log +0 -16
  48. package/.turbo/turbo-lint.log +0 -4
  49. package/.turbo/turbo-test.log +0 -1001
package/src/sync.ts CHANGED
@@ -1,7 +1,8 @@
1
1
  import { Signature } from "./crypto/crypto.js";
2
2
  import { CoValueHeader, Transaction } from "./coValueCore.js";
3
3
  import { CoValueCore } from "./coValueCore.js";
4
- import { LocalNode, newLoadingState } from "./localNode.js";
4
+ import { LocalNode } from "./localNode.js";
5
+ import { CoValueState } from "./coValueState.js";
5
6
  import { RawCoID, SessionID } from "./ids.js";
6
7
  import { PeerState } from "./PeerState.js";
7
8
  import { CoValuePriority } from "./priority.js";
@@ -74,7 +75,7 @@ export interface Peer {
74
75
  id: PeerID;
75
76
  incoming: IncomingSyncStream;
76
77
  outgoing: OutgoingSyncQueue;
77
- role: "peer" | "server" | "client";
78
+ role: "peer" | "server" | "client" | "storage";
78
79
  priority?: number;
79
80
  crashOnClose: boolean;
80
81
  }
@@ -128,11 +129,12 @@ export class SyncManager {
128
129
 
129
130
  async loadFromPeers(id: RawCoID, forPeer?: PeerID) {
130
131
  const eligiblePeers = this.peersInPriorityOrder().filter(
131
- (peer) => peer.id !== forPeer && peer.role === "server",
132
+ (peer) => peer.id !== forPeer && peer.isServerOrStoragePeer(),
132
133
  );
133
134
 
135
+ const coValueEntry = this.local.coValues[id];
136
+
134
137
  for (const peer of eligiblePeers) {
135
- // console.log("loading", id, "from", peer.id);
136
138
  await peer.pushOutgoingMessage({
137
139
  action: "load",
138
140
  id: id,
@@ -140,44 +142,9 @@ export class SyncManager {
140
142
  sessions: {},
141
143
  });
142
144
 
143
- const coValueEntry = this.local.coValues[id];
144
- if (coValueEntry?.state !== "loading") {
145
- continue;
145
+ if (coValueEntry?.state.type === "unknown") {
146
+ await coValueEntry.state.waitForPeer(peer.id);
146
147
  }
147
- const firstStateEntry = coValueEntry.firstPeerState[peer.id];
148
- if (firstStateEntry?.type !== "waiting") {
149
- throw new Error("Expected firstPeerState to be waiting " + id);
150
- }
151
- await new Promise<void>((resolve) => {
152
- // const timeout = setTimeout(() => {
153
- // if (this.local.coValues[id]?.state === "loading") {
154
- // console.warn(
155
- // "Timeout waiting for peer to load",
156
- // id,
157
- // "from",
158
- // peer.id,
159
- // "and it hasn't loaded from other peers yet"
160
- // );
161
- // }
162
- // resolve();
163
- // }, 1000);
164
- firstStateEntry.done
165
- .then(() => {
166
- // clearTimeout(timeout);
167
- resolve();
168
- })
169
- .catch((e) => {
170
- // clearTimeout(timeout);
171
- console.error(
172
- "Error waiting for peer to load",
173
- id,
174
- "from",
175
- peer.id,
176
- e,
177
- );
178
- resolve();
179
- });
180
- });
181
148
  }
182
149
  }
183
150
 
@@ -213,7 +180,7 @@ export class SyncManager {
213
180
  throw new Error("Expected coValue entry on subscribe");
214
181
  }
215
182
 
216
- if (entry.state === "loading") {
183
+ if (entry.state.type === "unknown") {
217
184
  this.trySendToPeer(peer, {
218
185
  action: "load",
219
186
  id,
@@ -225,7 +192,7 @@ export class SyncManager {
225
192
  return;
226
193
  }
227
194
 
228
- const coValue = entry.coValue;
195
+ const coValue = entry.state.coValue;
229
196
 
230
197
  for (const id of coValue.getDependedOnCoValues()) {
231
198
  await this.subscribeToIncludingDependencies(id, peer);
@@ -274,10 +241,7 @@ export class SyncManager {
274
241
  }
275
242
  }
276
243
 
277
- async sendNewContentIncludingDependencies(
278
- id: RawCoID,
279
- peer: PeerState,
280
- ) {
244
+ async sendNewContentIncludingDependencies(id: RawCoID, peer: PeerState) {
281
245
  const coValue = this.local.expectCoValueLoaded(id);
282
246
 
283
247
  await Promise.all(
@@ -289,12 +253,12 @@ export class SyncManager {
289
253
  );
290
254
 
291
255
  const newContentPieces = coValue.newContentSince(
292
- peer.optimisticKnownStates[id],
256
+ peer.optimisticKnownStates.get(id),
293
257
  );
294
258
 
295
259
  if (newContentPieces) {
296
260
  const optimisticKnownStateBefore =
297
- peer.optimisticKnownStates[id] || emptyKnownState(id);
261
+ peer.optimisticKnownStates.get(id) || emptyKnownState(id);
298
262
 
299
263
  const sendPieces = async () => {
300
264
  let lastYield = performance.now();
@@ -321,14 +285,19 @@ export class SyncManager {
321
285
 
322
286
  sendPieces().catch((e) => {
323
287
  console.error("Error sending new content piece, retrying", e);
324
- peer.optimisticKnownStates[id] = optimisticKnownStateBefore;
288
+ peer.optimisticKnownStates.dispatch({
289
+ type: "SET",
290
+ id,
291
+ value: optimisticKnownStateBefore ?? emptyKnownState(id),
292
+ });
325
293
  return this.sendNewContentIncludingDependencies(id, peer);
326
294
  });
327
295
 
328
- peer.optimisticKnownStates[id] = combinedKnownStates(
329
- optimisticKnownStateBefore,
330
- coValue.knownState(),
331
- );
296
+ peer.optimisticKnownStates.dispatch({
297
+ type: "COMBINE_WITH",
298
+ id,
299
+ value: coValue.knownState(),
300
+ });
332
301
  }
333
302
  }
334
303
 
@@ -336,7 +305,7 @@ export class SyncManager {
336
305
  const peerState = new PeerState(peer);
337
306
  this.peers[peer.id] = peerState;
338
307
 
339
- if (peer.role === "server") {
308
+ if (peerState.isServerOrStoragePeer()) {
340
309
  const initialSync = async () => {
341
310
  for (const id of Object.keys(
342
311
  this.local.coValues,
@@ -344,11 +313,10 @@ export class SyncManager {
344
313
  // console.log("subscribing to after peer added", id, peer.id)
345
314
  await this.subscribeToIncludingDependencies(id, peerState);
346
315
 
347
- peerState.optimisticKnownStates[id] = {
348
- id: id,
349
- header: false,
350
- sessions: {},
351
- };
316
+ peerState.optimisticKnownStates.dispatch({
317
+ type: "SET_AS_EMPTY",
318
+ id,
319
+ });
352
320
  }
353
321
  };
354
322
  void initialSync();
@@ -412,7 +380,11 @@ export class SyncManager {
412
380
  }
413
381
 
414
382
  async handleLoad(msg: LoadMessage, peer: PeerState) {
415
- peer.optimisticKnownStates[msg.id] = knownStateIn(msg);
383
+ peer.optimisticKnownStates.dispatch({
384
+ type: "SET",
385
+ id: msg.id,
386
+ value: knownStateIn(msg),
387
+ });
416
388
  let entry = this.local.coValues[msg.id];
417
389
 
418
390
  if (!entry) {
@@ -421,11 +393,11 @@ export class SyncManager {
421
393
  // special case: we should be able to solve this much more neatly
422
394
  // with an explicit state machine in the future
423
395
  const eligiblePeers = this.peersInPriorityOrder().filter(
424
- (other) => other.id !== peer.id && other.role === "server",
396
+ (other) => other.id !== peer.id && other.isServerOrStoragePeer(),
425
397
  );
426
398
  if (eligiblePeers.length === 0) {
427
399
  if (msg.header || Object.keys(msg.sessions).length > 0) {
428
- this.local.coValues[msg.id] = newLoadingState(
400
+ this.local.coValues[msg.id] = CoValueState.Unknown(
429
401
  new Set([peer.id]),
430
402
  );
431
403
  this.trySendToPeer(peer, {
@@ -452,17 +424,21 @@ export class SyncManager {
452
424
  entry = this.local.coValues[msg.id]!;
453
425
  }
454
426
 
455
- if (entry.state === "loading") {
427
+ if (entry.state.type === "unknown") {
456
428
  // console.debug(
457
429
  // "Waiting for loaded",
458
430
  // msg.id,
459
431
  // "after message from",
460
432
  // peer.id,
461
433
  // );
462
- const loaded = await entry.done;
463
- // console.log("Loaded", msg.id, loaded);
434
+ const loaded = await entry.state.ready;
435
+
464
436
  if (loaded === "unavailable") {
465
- peer.optimisticKnownStates[msg.id] = knownStateIn(msg);
437
+ peer.optimisticKnownStates.dispatch({
438
+ type: "SET",
439
+ id: msg.id,
440
+ value: knownStateIn(msg),
441
+ });
466
442
  peer.toldKnownState.add(msg.id);
467
443
 
468
444
  this.trySendToPeer(peer, {
@@ -485,10 +461,11 @@ export class SyncManager {
485
461
  async handleKnownState(msg: KnownStateMessage, peer: PeerState) {
486
462
  let entry = this.local.coValues[msg.id];
487
463
 
488
- peer.optimisticKnownStates[msg.id] = combinedKnownStates(
489
- peer.optimisticKnownStates[msg.id] || emptyKnownState(msg.id),
490
- knownStateIn(msg),
491
- );
464
+ peer.optimisticKnownStates.dispatch({
465
+ type: "COMBINE_WITH",
466
+ id: msg.id,
467
+ value: knownStateIn(msg),
468
+ });
492
469
 
493
470
  if (!entry) {
494
471
  if (msg.asDependencyOf) {
@@ -514,31 +491,17 @@ export class SyncManager {
514
491
  }
515
492
  }
516
493
 
517
- if (entry.state === "loading") {
518
- const availableOnPeer = peer.optimisticKnownStates[msg.id]?.header;
519
- const firstPeerStateEntry = entry.firstPeerState[peer.id];
520
- if (firstPeerStateEntry?.type === "waiting") {
521
- firstPeerStateEntry.resolve();
522
- }
523
- entry.firstPeerState[peer.id] = availableOnPeer
524
- ? { type: "available" }
525
- : { type: "unavailable" };
526
- // console.log(
527
- // "Marking",
528
- // msg.id,
529
- // "as",
530
- // entry.firstPeerState[peer.id]?.type,
531
- // "from",
532
- // peer.id
533
- // );
534
- if (
535
- Object.values(entry.firstPeerState).every(
536
- (s) => s.type === "unavailable",
537
- )
538
- ) {
539
- entry.resolve("unavailable");
494
+ if (entry.state.type === "unknown") {
495
+ const availableOnPeer = peer.optimisticKnownStates.get(msg.id)?.header;
496
+
497
+ if (!availableOnPeer) {
498
+ entry.dispatch({
499
+ type: "not-found",
500
+ peerId: peer.id,
501
+ });
540
502
  }
541
- return [];
503
+
504
+ return;
542
505
  }
543
506
 
544
507
  await this.tellUntoldKnownStateIncludingDependencies(msg.id, peer);
@@ -546,7 +509,7 @@ export class SyncManager {
546
509
  }
547
510
 
548
511
  async handleNewContent(msg: NewContentMessage, peer: PeerState) {
549
- let entry = this.local.coValues[msg.id];
512
+ const entry = this.local.coValues[msg.id];
550
513
 
551
514
  if (!entry) {
552
515
  console.error(
@@ -555,46 +518,31 @@ export class SyncManager {
555
518
  return;
556
519
  }
557
520
 
558
- let resolveAfterDone: ((coValue: CoValueCore) => void) | undefined;
559
-
560
- const peerOptimisticKnownState = peer.optimisticKnownStates[msg.id];
561
-
562
- if (!peerOptimisticKnownState) {
563
- console.error(
564
- "Expected optimisticKnownState to be set for coValue we receive new content for",
565
- );
566
- return;
567
- }
521
+ let coValue: CoValueCore;
568
522
 
569
- if (entry.state === "loading") {
523
+ if (entry.state.type === "unknown") {
570
524
  if (!msg.header) {
571
525
  console.error("Expected header to be sent in first message");
572
526
  return;
573
527
  }
574
528
 
575
- const firstPeerStateEntry = entry.firstPeerState[peer.id];
576
- if (firstPeerStateEntry?.type === "waiting") {
577
- firstPeerStateEntry.resolve();
578
- entry.firstPeerState[peer.id] = { type: "available" };
579
- }
580
-
581
- peerOptimisticKnownState.header = true;
582
-
583
- const coValue = new CoValueCore(msg.header, this.local);
529
+ peer.optimisticKnownStates.dispatch({
530
+ type: "UPDATE_HEADER",
531
+ id: msg.id,
532
+ header: true,
533
+ });
584
534
 
585
- resolveAfterDone = entry.resolve;
535
+ coValue = new CoValueCore(msg.header, this.local);
586
536
 
587
- entry = {
588
- state: "loaded",
589
- coValue: coValue,
590
- onProgress: entry.onProgress,
591
- };
592
-
593
- this.local.coValues[msg.id] = entry;
537
+ entry.dispatch({
538
+ type: "found",
539
+ coValue,
540
+ peerId: peer.id,
541
+ });
542
+ } else {
543
+ coValue = entry.state.coValue;
594
544
  }
595
545
 
596
- const coValue = entry.coValue;
597
-
598
546
  let invalidStateAssumed = false;
599
547
 
600
548
  for (const [sessionID, newContentForSession] of Object.entries(
@@ -648,15 +596,13 @@ export class SyncManager {
648
596
  );
649
597
  }
650
598
 
651
- const theirTotalnTxs = Object.values(
652
- peer.optimisticKnownStates[msg.id]?.sessions || {},
653
- ).reduce((sum, nTxs) => sum + nTxs, 0);
654
- const ourTotalnTxs = [...coValue.sessionLogs.values()].reduce(
655
- (sum, session) => sum + session.transactions.length,
656
- 0,
657
- );
658
-
659
- entry.onProgress?.(ourTotalnTxs / theirTotalnTxs);
599
+ // const theirTotalnTxs = Object.values(
600
+ // peer.optimisticKnownStates[msg.id]?.sessions || {},
601
+ // ).reduce((sum, nTxs) => sum + nTxs, 0);
602
+ // const ourTotalnTxs = [...coValue.sessionLogs.values()].reduce(
603
+ // (sum, session) => sum + session.transactions.length,
604
+ // 0,
605
+ // );
660
606
 
661
607
  if (result.isErr()) {
662
608
  console.error(
@@ -673,15 +619,14 @@ export class SyncManager {
673
619
  continue;
674
620
  }
675
621
 
676
- peerOptimisticKnownState.sessions[sessionID] = Math.max(
677
- peerOptimisticKnownState.sessions[sessionID] || 0,
678
- newContentForSession.after +
622
+ peer.optimisticKnownStates.dispatch({
623
+ type: "UPDATE_SESSION_COUNTER",
624
+ id: msg.id,
625
+ sessionId: sessionID,
626
+ value:
627
+ newContentForSession.after +
679
628
  newContentForSession.newTransactions.length,
680
- );
681
- }
682
-
683
- if (resolveAfterDone) {
684
- resolveAfterDone(coValue);
629
+ });
685
630
  }
686
631
 
687
632
  await this.syncCoValue(coValue);
@@ -698,7 +643,11 @@ export class SyncManager {
698
643
  }
699
644
 
700
645
  async handleCorrection(msg: KnownStateMessage, peer: PeerState) {
701
- peer.optimisticKnownStates[msg.id] = msg;
646
+ peer.optimisticKnownStates.dispatch({
647
+ type: "SET",
648
+ id: msg.id,
649
+ value: knownStateIn(msg),
650
+ });
702
651
 
703
652
  return this.sendNewContentIncludingDependencies(msg.id, peer);
704
653
  }
@@ -740,9 +689,7 @@ export class SyncManager {
740
689
  // });
741
690
  // blockingSince = performance.now();
742
691
  // }
743
- const optimisticKnownState = peer.optimisticKnownStates[coValue.id];
744
-
745
- if (optimisticKnownState) {
692
+ if (peer.optimisticKnownStates.has(coValue.id)) {
746
693
  await this.tellUntoldKnownStateIncludingDependencies(
747
694
  coValue.id,
748
695
  peer,
@@ -751,7 +698,7 @@ export class SyncManager {
751
698
  coValue.id,
752
699
  peer,
753
700
  );
754
- } else if (peer.role === "server") {
701
+ } else if (peer.isServerOrStoragePeer()) {
755
702
  await this.subscribeToIncludingDependencies(coValue.id, peer);
756
703
  await this.sendNewContentIncludingDependencies(
757
704
  coValue.id,
@@ -0,0 +1,100 @@
1
+ import { PeerKnownStates } from '../PeerKnownStates.js';
2
+ import { CoValueKnownState, emptyKnownState } from '../sync.js';
3
+ import { RawCoID, SessionID } from '../ids.js';
4
+ import { vi, describe, test, expect } from 'vitest';
5
+
6
+
7
+ describe('PeerKnownStates', () => {
8
+ test('should set and get a known state', () => {
9
+ const peerKnownStates = new PeerKnownStates();
10
+ const id = 'test-id' as RawCoID;
11
+ const knownState: CoValueKnownState = emptyKnownState(id);
12
+
13
+ peerKnownStates.dispatch({ type: 'SET', id, value: knownState });
14
+
15
+ expect(peerKnownStates.get(id)).toEqual(knownState);
16
+ expect(peerKnownStates.has(id)).toBe(true);
17
+ });
18
+
19
+ test('should update header', () => {
20
+ const peerKnownStates = new PeerKnownStates();
21
+ const id = 'test-id' as RawCoID;
22
+
23
+ peerKnownStates.dispatch({ type: 'UPDATE_HEADER', id, header: true });
24
+
25
+ const result = peerKnownStates.get(id);
26
+ expect(result?.header).toBe(true);
27
+ });
28
+
29
+ test('should update session counter', () => {
30
+ const peerKnownStates = new PeerKnownStates();
31
+ const id = 'test-id' as RawCoID;
32
+ const sessionId = 'session-1' as SessionID;
33
+
34
+ peerKnownStates.dispatch({ type: 'UPDATE_SESSION_COUNTER', id, sessionId, value: 5 });
35
+
36
+ const result = peerKnownStates.get(id);
37
+ expect(result?.sessions[sessionId]).toBe(5);
38
+ });
39
+
40
+ test('should combine with existing state', () => {
41
+ const peerKnownStates = new PeerKnownStates();
42
+ const id = 'test-id' as RawCoID;
43
+ const session1 = 'session-1' as SessionID;
44
+ const session2 = 'session-2' as SessionID;
45
+ const initialState: CoValueKnownState = {
46
+ ...emptyKnownState(id),
47
+ sessions: { [session1]: 5 },
48
+ };
49
+ const combineState: CoValueKnownState = {
50
+ ...emptyKnownState(id),
51
+ sessions: { [session2]: 10 },
52
+ };
53
+
54
+ peerKnownStates.dispatch({ type: 'SET', id, value: initialState });
55
+ peerKnownStates.dispatch({ type: 'COMBINE_WITH', id, value: combineState });
56
+
57
+ const result = peerKnownStates.get(id);
58
+ expect(result?.sessions).toEqual({ [session1]: 5, [session2]: 10 });
59
+ });
60
+
61
+ test('should set as empty', () => {
62
+ const peerKnownStates = new PeerKnownStates();
63
+ const id = 'test-id' as RawCoID;
64
+ const sessionId = 'session-1' as SessionID;
65
+ const initialState: CoValueKnownState = {
66
+ ...emptyKnownState(id),
67
+ sessions: { [sessionId]: 5 },
68
+ };
69
+
70
+ peerKnownStates.dispatch({ type: 'SET', id, value: initialState });
71
+ peerKnownStates.dispatch({ type: 'SET_AS_EMPTY', id });
72
+
73
+ const result = peerKnownStates.get(id);
74
+ expect(result).toEqual(emptyKnownState(id));
75
+ });
76
+
77
+ test('should trigger listeners on dispatch', () => {
78
+ const peerKnownStates = new PeerKnownStates();
79
+ const id = 'test-id' as RawCoID;
80
+ const listener = vi.fn();
81
+
82
+ peerKnownStates.subscribe(listener);
83
+ peerKnownStates.dispatch({ type: 'SET_AS_EMPTY', id });
84
+
85
+ expect(listener).toHaveBeenCalledWith(id, emptyKnownState(id));
86
+ });
87
+
88
+ test('should unsubscribe listener', () => {
89
+ const peerKnownStates = new PeerKnownStates();
90
+ const id = 'test-id' as RawCoID;
91
+ const listener = vi.fn();
92
+
93
+ const unsubscribe = peerKnownStates.subscribe(listener);
94
+ unsubscribe();
95
+
96
+ peerKnownStates.dispatch({ type: 'SET_AS_EMPTY', id });
97
+
98
+ expect(listener).not.toHaveBeenCalled();
99
+ });
100
+ });
@@ -20,17 +20,6 @@ function setup() {
20
20
  }
21
21
 
22
22
  describe("PeerState", () => {
23
- test("should initialize with correct properties", () => {
24
- const { peerState } = setup();
25
- expect(peerState.id).toBe("test-peer");
26
- expect(peerState.role).toBe("peer");
27
- expect(peerState.priority).toBe(1);
28
- expect(peerState.crashOnClose).toBe(false);
29
- expect(peerState.closed).toBe(false);
30
- expect(peerState.optimisticKnownStates).toEqual({});
31
- expect(peerState.toldKnownState).toEqual(new Set());
32
- });
33
-
34
23
  test("should push outgoing message to peer", async () => {
35
24
  const { mockPeer, peerState } = setup();
36
25
  const message: SyncMessage = { action: "load", id: "co_ztest-id", header: false, sessions: {} };
@@ -761,7 +761,7 @@ test.skip("When replaying creation and transactions of a coValue as new content,
761
761
  expect(groupTellKnownStateMsg).toMatchObject(groupStateEx(group));
762
762
 
763
763
  expect(
764
- node2.syncManager.peers["test1"]!.optimisticKnownStates[group.core.id],
764
+ node2.syncManager.peers["test1"]!.optimisticKnownStates.has(group.core.id),
765
765
  ).toBeDefined();
766
766
 
767
767
  // await inTx1.push(adminTellKnownStateMsg);
@@ -1086,7 +1086,7 @@ test("If we start loading a coValue before connecting to a peer that has it, it
1086
1086
 
1087
1087
  const mapOnNode2Promise = node2.loadCoValueCore(map.core.id);
1088
1088
 
1089
- expect(node2.coValues[map.core.id]?.state).toEqual("loading");
1089
+ expect(node2.coValues[map.core.id]?.state.type).toEqual("unknown");
1090
1090
 
1091
1091
  node2.syncManager.addPeer(node1asPeer);
1092
1092
 
@@ -1,16 +0,0 @@
1
-
2
- > cojson@0.8.3 build /Users/anselm/jazz/jazz/packages/cojson
3
- > npm run lint && rm -rf ./dist && pnpm run build:native && pnpm run build:web
4
-
5
-
6
- > cojson@0.8.3 lint
7
- > eslint . --ext ts,tsx
8
-
9
-
10
- > cojson@0.8.3 build:native /Users/anselm/jazz/jazz/packages/cojson
11
- > tsc --sourceMap --outDir dist/native -p tsconfig.native.json
12
-
13
-
14
- > cojson@0.8.3 build:web /Users/anselm/jazz/jazz/packages/cojson
15
- > tsc --sourceMap --outDir dist/web -p tsconfig.web.json
16
-
@@ -1,4 +0,0 @@
1
-
2
- > cojson@0.7.35-guest-auth.5 lint /Users/anselm/jazz/jazz/packages/cojson
3
- > eslint . --ext ts,tsx
4
-