@peers-app/peers-device 0.15.0 → 0.15.2

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 (68) hide show
  1. package/dist/chunk-download-manager.d.ts +2 -2
  2. package/dist/chunk-download-manager.js +1 -1
  3. package/dist/chunk-download-manager.js.map +1 -1
  4. package/dist/chunk-download-manager.test.js +57 -57
  5. package/dist/chunk-download-manager.test.js.map +1 -1
  6. package/dist/chunk-download.types.d.ts +1 -1
  7. package/dist/connection-manager/connection-manager-priorities.d.ts +1 -1
  8. package/dist/connection-manager/connection-manager-priorities.js +10 -6
  9. package/dist/connection-manager/connection-manager-priorities.js.map +1 -1
  10. package/dist/connection-manager/connection-manager-priorities.test.js +192 -194
  11. package/dist/connection-manager/connection-manager-priorities.test.js.map +1 -1
  12. package/dist/connection-manager/connection-manager.d.ts +2 -2
  13. package/dist/connection-manager/connection-manager.js +71 -55
  14. package/dist/connection-manager/connection-manager.js.map +1 -1
  15. package/dist/connection-manager/connection-manager.test.js +165 -147
  16. package/dist/connection-manager/connection-manager.test.js.map +1 -1
  17. package/dist/connection-manager/connection-state.type.d.ts +1 -1
  18. package/dist/connection-manager/device-message-handler.types.d.ts +6 -6
  19. package/dist/connection-manager/device-messages.d.ts +4 -4
  20. package/dist/connection-manager/device-messages.js +56 -40
  21. package/dist/connection-manager/device-messages.js.map +1 -1
  22. package/dist/connection-manager/group-invite-messages.d.ts +2 -2
  23. package/dist/connection-manager/group-invite-messages.js +36 -47
  24. package/dist/connection-manager/group-invite-messages.js.map +1 -1
  25. package/dist/connection-manager/hops-map.js +4 -4
  26. package/dist/connection-manager/hops-map.js.map +1 -1
  27. package/dist/connection-manager/hops-map.test.js +3 -3
  28. package/dist/connection-manager/hops-map.test.js.map +1 -1
  29. package/dist/connection-manager/network-manager.d.ts +2 -2
  30. package/dist/connection-manager/network-manager.js +81 -75
  31. package/dist/connection-manager/network-manager.js.map +1 -1
  32. package/dist/index.d.ts +12 -12
  33. package/dist/json-diff.d.ts +2 -2
  34. package/dist/json-diff.js +30 -27
  35. package/dist/json-diff.js.map +1 -1
  36. package/dist/local.data-source.d.ts +1 -1
  37. package/dist/local.data-source.js +23 -23
  38. package/dist/local.data-source.js.map +1 -1
  39. package/dist/local.data-source.test.js +17 -17
  40. package/dist/local.data-source.test.js.map +1 -1
  41. package/dist/machine-stats.js +57 -51
  42. package/dist/machine-stats.js.map +1 -1
  43. package/dist/machine-stats.test.js +42 -42
  44. package/dist/machine-stats.test.js.map +1 -1
  45. package/dist/main.d.ts +2 -2
  46. package/dist/main.js +10 -8
  47. package/dist/main.js.map +1 -1
  48. package/dist/packages.tracked-data-source.d.ts +1 -1
  49. package/dist/packages.tracked-data-source.js.map +1 -1
  50. package/dist/persistent-vars.test.js +148 -148
  51. package/dist/persistent-vars.test.js.map +1 -1
  52. package/dist/pvars.tracked-data-source.d.ts +1 -1
  53. package/dist/pvars.tracked-data-source.js +12 -10
  54. package/dist/pvars.tracked-data-source.js.map +1 -1
  55. package/dist/sync-group.d.ts +2 -2
  56. package/dist/sync-group.js +110 -88
  57. package/dist/sync-group.js.map +1 -1
  58. package/dist/sync-group.test.js +157 -120
  59. package/dist/sync-group.test.js.map +1 -1
  60. package/dist/tracked-data-source.d.ts +1 -1
  61. package/dist/tracked-data-source.js +61 -62
  62. package/dist/tracked-data-source.js.map +1 -1
  63. package/dist/tracked-data-source.test.js +507 -299
  64. package/dist/tracked-data-source.test.js.map +1 -1
  65. package/dist/websocket-client.d.ts +1 -1
  66. package/dist/websocket-client.js +50 -41
  67. package/dist/websocket-client.js.map +1 -1
  68. package/package.json +3 -3
@@ -10,17 +10,20 @@ describe("peer-device", () => {
10
10
  const allPeers = [];
11
11
  afterEach(async () => {
12
12
  await (0, peers_sdk_1.sleep)(1);
13
- await Promise.all(allPeers.map(peer => peer.dispose()));
13
+ await Promise.all(allPeers.map((peer) => peer.dispose()));
14
14
  });
15
15
  afterAll(async () => {
16
- await Promise.all(allPeers.map(peer => peer.dispose()));
16
+ await Promise.all(allPeers.map((peer) => peer.dispose()));
17
17
  await (0, peers_sdk_1.sleep)(200);
18
18
  console.log("List changes count: ", sync_group_1.SyncGroup.listChangesCount);
19
19
  console.log("Apply changes count: ", sync_group_1.SyncGroup.applyChangesCount);
20
20
  console.log("Network info count: ", sync_group_1.SyncGroup.getNetworkInfoCount);
21
21
  console.log("Elections count: ", sync_group_1.SyncGroup.electPreferredConnectionsCount);
22
22
  console.log("Sync with remote device count: ", sync_group_1.SyncGroup.syncWithRemoteDeviceCount);
23
- console.log("Total count: ", sync_group_1.SyncGroup.listChangesCount + sync_group_1.SyncGroup.applyChangesCount + sync_group_1.SyncGroup.getNetworkInfoCount + sync_group_1.SyncGroup.electPreferredConnectionsCount);
23
+ console.log("Total count: ", sync_group_1.SyncGroup.listChangesCount +
24
+ sync_group_1.SyncGroup.applyChangesCount +
25
+ sync_group_1.SyncGroup.getNetworkInfoCount +
26
+ sync_group_1.SyncGroup.electPreferredConnectionsCount);
24
27
  console.log("Average sync time (ms): ", sync_group_1.SyncGroup.averageSyncTimeMs.avgTimeMs);
25
28
  });
26
29
  const notesSchema = peers_sdk_1.z.object({
@@ -34,15 +37,15 @@ describe("peer-device", () => {
34
37
  const notesTableName = "notes-test";
35
38
  const notesMetaData = {
36
39
  name: notesTableName,
37
- description: 'A table for notes',
38
- primaryKeyName: 'noteId',
40
+ description: "A table for notes",
41
+ primaryKeyName: "noteId",
39
42
  fields: (0, peers_sdk_1.schemaToFields)(notesSchema),
40
43
  };
41
44
  function getNotesTable(peer) {
42
45
  return peer.tableContainer.getTable(notesMetaData, notesSchema);
43
46
  }
44
47
  function buildPeer(userId = (0, peers_sdk_1.newid)(), deviceId = (0, peers_sdk_1.newid)()) {
45
- const db = new local_data_source_1.DBLocal(':memory:');
48
+ const db = new local_data_source_1.DBLocal(":memory:");
46
49
  const changeTrackingTable = new peers_sdk_1.ChangeTrackingTable({ db });
47
50
  // Create a mock UserContext and DataContext for testing
48
51
  const mockUserContext = {
@@ -56,14 +59,14 @@ describe("peer-device", () => {
56
59
  const trackedDS = new tracked_data_source_1.TrackedDataSource(sqlDS, changeTrackingTable);
57
60
  // trackedDS.preserveHistory = true;
58
61
  return trackedDS;
59
- }
62
+ },
60
63
  };
61
64
  const dataContext = new peers_sdk_1.DataContext(mockUserContext);
62
65
  const peer = new sync_group_1.SyncGroup(dataContext, changeTrackingTable);
63
66
  allPeers.push(peer);
64
67
  return peer;
65
68
  }
66
- function buildRemotePeer({ userId = (0, peers_sdk_1.newid)(), deviceId = (0, peers_sdk_1.newid)(), errorRate = 0, latencyMs = 0 } = {}) {
69
+ function buildRemotePeer({ userId = (0, peers_sdk_1.newid)(), deviceId = (0, peers_sdk_1.newid)(), errorRate = 0, latencyMs = 0, } = {}) {
67
70
  const peer = buildPeer(userId, deviceId);
68
71
  return {
69
72
  peer,
@@ -72,30 +75,30 @@ describe("peer-device", () => {
72
75
  userId: peer.userId,
73
76
  role: peer.role,
74
77
  listChanges: async (filter, opts) => {
75
- latencyMs && await (0, peers_sdk_1.sleep)(latencyMs);
78
+ latencyMs && (await (0, peers_sdk_1.sleep)(latencyMs));
76
79
  if (errorRate && Math.random() < errorRate) {
77
80
  throw new Error("Simulated error");
78
81
  }
79
82
  return peer.listChanges(filter, opts);
80
83
  },
81
84
  getNetworkInfo: async () => {
82
- latencyMs && await (0, peers_sdk_1.sleep)(latencyMs);
85
+ latencyMs && (await (0, peers_sdk_1.sleep)(latencyMs));
83
86
  if (errorRate && Math.random() < errorRate) {
84
87
  throw new Error("Simulated error");
85
88
  }
86
89
  return peer.getNetworkInfo();
87
90
  },
88
91
  notifyOfChanges: async (deviceId, timestampLastApplied) => {
89
- latencyMs && await (0, peers_sdk_1.sleep)(latencyMs);
92
+ latencyMs && (await (0, peers_sdk_1.sleep)(latencyMs));
90
93
  if (errorRate && Math.random() < errorRate) {
91
94
  throw new Error("Simulated error");
92
95
  }
93
96
  return peer.notifyOfChanges(deviceId, timestampLastApplied);
94
97
  },
95
98
  sendDeviceMessage(message) {
96
- throw new Error('not implemented');
99
+ throw new Error("not implemented");
97
100
  },
98
- }
101
+ },
99
102
  };
100
103
  }
101
104
  it("should have notes tables", async () => {
@@ -137,24 +140,26 @@ describe("peer-device", () => {
137
140
  recordId: noteId,
138
141
  createdAt: now - 5000, // 5 seconds before change3
139
142
  appliedAt: now - 5000,
140
- op: 'set',
141
- path: '/',
143
+ op: "set",
144
+ path: "/",
142
145
  value: noteUpdate2,
143
146
  };
144
147
  await peer.applyChanges([change2]);
145
148
  let note = await peerNotes.get(noteId);
146
149
  expect(note).toEqual(noteUpdate2);
147
150
  const noteUpdate1 = { noteId: noteId, title: "note updated first" };
148
- await peer.applyChanges([{
151
+ await peer.applyChanges([
152
+ {
149
153
  changeId: (0, peers_sdk_1.newid)(),
150
154
  tableName: notesTableName,
151
155
  recordId: noteId,
152
156
  createdAt: now - 6000,
153
157
  appliedAt: now - 6000,
154
- op: 'set',
155
- path: '/',
158
+ op: "set",
159
+ path: "/",
156
160
  value: noteUpdate1,
157
- }]);
161
+ },
162
+ ]);
158
163
  note = await peerNotes.get(noteId);
159
164
  expect(note).toEqual(noteUpdate2);
160
165
  // Create changes with different timestamps (newer to older)
@@ -164,8 +169,8 @@ describe("peer-device", () => {
164
169
  recordId: noteId,
165
170
  createdAt: now,
166
171
  appliedAt: now,
167
- op: 'delete',
168
- path: '/',
172
+ op: "delete",
173
+ path: "/",
169
174
  value: null,
170
175
  };
171
176
  await peer.applyChanges([change3]);
@@ -177,9 +182,9 @@ describe("peer-device", () => {
177
182
  recordId: noteId,
178
183
  createdAt: now - 10000, // 10 seconds before change3
179
184
  appliedAt: now - 10000,
180
- op: 'set',
181
- path: '/',
182
- value: { noteId: noteId, title: "Note inserted" }
185
+ op: "set",
186
+ path: "/",
187
+ value: { noteId: noteId, title: "Note inserted" },
183
188
  };
184
189
  await peer.applyChanges([change1]);
185
190
  note = await peerNotes.get(noteId);
@@ -230,7 +235,7 @@ describe("peer-device", () => {
230
235
  expect(peer1Note2).toBeDefined();
231
236
  expect(peer1Note2?.title).toBe("Note from Peer2");
232
237
  });
233
- // this is unreliable because it's based on the machine it runs on.
238
+ // this is unreliable because it's based on the machine it runs on.
234
239
  // just use it for verifying performance if changes are made to syncing algorithm
235
240
  it.skip("should only sync changes that were written after the last sync", async () => {
236
241
  // Create two peers
@@ -301,10 +306,7 @@ describe("peer-device", () => {
301
306
  async function assertSyncMs(msLt, msGt = 1) {
302
307
  // time the sync
303
308
  const start = Date.now();
304
- await Promise.all([
305
- peer1.syncWithRemoteDevice(peer2),
306
- peer2.syncWithRemoteDevice(peer1)
307
- ]);
309
+ await Promise.all([peer1.syncWithRemoteDevice(peer2), peer2.syncWithRemoteDevice(peer1)]);
308
310
  const end = Date.now();
309
311
  const syncTime = end - start;
310
312
  // console.log(`Sync time: ${syncTime}ms`);
@@ -345,10 +347,7 @@ describe("peer-device", () => {
345
347
  async function assertSync() {
346
348
  // time the sync
347
349
  const start = Date.now();
348
- await Promise.all([
349
- peer1.syncWithRemoteDevice(peer2),
350
- peer2.syncWithRemoteDevice(peer1)
351
- ]);
350
+ await Promise.all([peer1.syncWithRemoteDevice(peer2), peer2.syncWithRemoteDevice(peer1)]);
352
351
  const end = Date.now();
353
352
  const syncTime = end - start;
354
353
  // console.log(`Sync time: ${syncTime}ms`);
@@ -387,10 +386,10 @@ describe("peer-device", () => {
387
386
  const notes1 = await peer1Notes.list();
388
387
  const notes2 = await peer2Notes.list();
389
388
  const diffs = [];
390
- const ids = (0, lodash_1.uniq)([...notes1.map(n => n.noteId), ...notes2.map(n => n.noteId)]);
389
+ const ids = (0, lodash_1.uniq)([...notes1.map((n) => n.noteId), ...notes2.map((n) => n.noteId)]);
391
390
  for (const id of ids) {
392
- const note1 = notes1.find(n => n.noteId === id);
393
- const note2 = notes2.find(n => n.noteId === id);
391
+ const note1 = notes1.find((n) => n.noteId === id);
392
+ const note2 = notes2.find((n) => n.noteId === id);
394
393
  if ((0, lodash_1.isEqual)(note1, note2))
395
394
  continue;
396
395
  diffs.push({ id, note1, note2 });
@@ -462,17 +461,11 @@ describe("peer-device", () => {
462
461
  await (0, peers_sdk_1.sleep)(1000);
463
462
  // start syncing
464
463
  while (!finished) {
465
- await Promise.all([
466
- peer2.syncWithRemoteDevice(peer1),
467
- peer3.syncWithRemoteDevice(peer2),
468
- ]);
464
+ await Promise.all([peer2.syncWithRemoteDevice(peer1), peer3.syncWithRemoteDevice(peer2)]);
469
465
  await (0, peers_sdk_1.sleep)(10);
470
466
  }
471
467
  // do final sync
472
- await Promise.all([
473
- peer2.syncWithRemoteDevice(peer1),
474
- peer3.syncWithRemoteDevice(peer1),
475
- ]);
468
+ await Promise.all([peer2.syncWithRemoteDevice(peer1), peer3.syncWithRemoteDevice(peer1)]);
476
469
  await (0, peers_sdk_1.sleep)(100);
477
470
  const peer1FinalNotes = await peer1Notes.list();
478
471
  const peer2FinalNotes = await peer2Notes.list();
@@ -583,8 +576,8 @@ describe("peer-device", () => {
583
576
  });
584
577
  const tasksMetaData = {
585
578
  name: "tasks-test",
586
- description: 'A table for tasks',
587
- primaryKeyName: 'taskId',
579
+ description: "A table for tasks",
580
+ primaryKeyName: "taskId",
588
581
  fields: (0, peers_sdk_1.schemaToFields)(tasksSchema),
589
582
  };
590
583
  // Get notes tables
@@ -594,10 +587,38 @@ describe("peer-device", () => {
594
587
  const peer2Tasks = peer2.tableContainer.getTable(tasksMetaData);
595
588
  // create notes
596
589
  for (let i = 0; i < 10; i++) {
597
- await peer1Notes.save({ noteId: (0, peers_sdk_1.newid)(), title: `Note ${i}`, completed: false, number: i, string: `String ${i}`, date: new Date() });
598
- await peer2Notes.save({ noteId: (0, peers_sdk_1.newid)(), title: `Note ${i}`, completed: false, number: i, string: `String ${i}`, date: new Date() });
599
- await peer1Tasks.save({ taskId: (0, peers_sdk_1.newid)(), title: `Task ${i}`, completed: false, number: i, string: `String ${i}`, date: new Date() });
600
- await peer2Tasks.save({ taskId: (0, peers_sdk_1.newid)(), title: `Task ${i}`, completed: false, number: i, string: `String ${i}`, date: new Date() });
590
+ await peer1Notes.save({
591
+ noteId: (0, peers_sdk_1.newid)(),
592
+ title: `Note ${i}`,
593
+ completed: false,
594
+ number: i,
595
+ string: `String ${i}`,
596
+ date: new Date(),
597
+ });
598
+ await peer2Notes.save({
599
+ noteId: (0, peers_sdk_1.newid)(),
600
+ title: `Note ${i}`,
601
+ completed: false,
602
+ number: i,
603
+ string: `String ${i}`,
604
+ date: new Date(),
605
+ });
606
+ await peer1Tasks.save({
607
+ taskId: (0, peers_sdk_1.newid)(),
608
+ title: `Task ${i}`,
609
+ completed: false,
610
+ number: i,
611
+ string: `String ${i}`,
612
+ date: new Date(),
613
+ });
614
+ await peer2Tasks.save({
615
+ taskId: (0, peers_sdk_1.newid)(),
616
+ title: `Task ${i}`,
617
+ completed: false,
618
+ number: i,
619
+ string: `String ${i}`,
620
+ date: new Date(),
621
+ });
601
622
  }
602
623
  await (0, peers_sdk_1.sleep)(1000);
603
624
  let peer1NotesList = await peer1Notes.list();
@@ -683,7 +704,7 @@ describe("peer-device", () => {
683
704
  getNetworkInfoCount: 2, // network info on elections (use same network info for sync)
684
705
  applyChangesCount: 0, // no changes to apply
685
706
  });
686
- // expect them to be synced with each other
707
+ // expect them to be synced with each other
687
708
  const peer1NetworkInfo = await peer1.peer.getNetworkInfo();
688
709
  const peer1Conns = peer1NetworkInfo.connections;
689
710
  expect(peer1Conns.length).toBe(1);
@@ -729,10 +750,7 @@ describe("peer-device", () => {
729
750
  const notes1 = await peer1Notes.list();
730
751
  const notes2 = await peer2Notes.list();
731
752
  expect(notes1).toEqual(notes2);
732
- await Promise.all([
733
- peer1.peer.dispose(),
734
- peer2.peer.dispose(),
735
- ]);
753
+ await Promise.all([peer1.peer.dispose(), peer2.peer.dispose()]);
736
754
  });
737
755
  it("should keep synced three connected peers that are all connected to each other", async () => {
738
756
  // Create peers
@@ -750,7 +768,7 @@ describe("peer-device", () => {
750
768
  await getNotesTable(peer).save({ noteId: (0, peers_sdk_1.newid)(), title: `Note ${i}` });
751
769
  }
752
770
  }
753
- // connect all peers
771
+ // connect all peers
754
772
  for (const peer of peers) {
755
773
  for (const otherPeer of peers) {
756
774
  if (peer !== otherPeer) {
@@ -925,9 +943,9 @@ describe("peer-device", () => {
925
943
  }
926
944
  }
927
945
  for (let i = 0; i < 10; i++) {
928
- const stillSyncing = peer1.getConnections().some(c => !c.timestampLastApplied) ||
929
- peer2.getConnections().some(c => !c.timestampLastApplied) ||
930
- peer3.getConnections().some(c => !c.timestampLastApplied);
946
+ const stillSyncing = peer1.getConnections().some((c) => !c.timestampLastApplied) ||
947
+ peer2.getConnections().some((c) => !c.timestampLastApplied) ||
948
+ peer3.getConnections().some((c) => !c.timestampLastApplied);
931
949
  await (0, peers_sdk_1.sleep)(100);
932
950
  if (!stillSyncing)
933
951
  break;
@@ -1006,10 +1024,10 @@ describe("peer-device", () => {
1006
1024
  }
1007
1025
  }
1008
1026
  for (let i = 0; i < 10; i++) {
1009
- const stillSyncing = peer1.getConnections().some(c => !c.timestampLastApplied) ||
1010
- peer2.getConnections().some(c => !c.timestampLastApplied) ||
1011
- peer3.getConnections().some(c => !c.timestampLastApplied) ||
1012
- peer4.getConnections().some(c => !c.timestampLastApplied);
1027
+ const stillSyncing = peer1.getConnections().some((c) => !c.timestampLastApplied) ||
1028
+ peer2.getConnections().some((c) => !c.timestampLastApplied) ||
1029
+ peer3.getConnections().some((c) => !c.timestampLastApplied) ||
1030
+ peer4.getConnections().some((c) => !c.timestampLastApplied);
1013
1031
  await (0, peers_sdk_1.sleep)(100);
1014
1032
  if (!stillSyncing)
1015
1033
  break;
@@ -1037,7 +1055,7 @@ describe("peer-device", () => {
1037
1055
  });
1038
1056
  // unreliable for CI/CD so skipping. Use for local dev only
1039
1057
  it("after syncing with a peers, should skip forward to that peer's timestampAppliedLast for all it's connections", async () => {
1040
- // NOTE: I confirmed via execution time that this is working.
1058
+ // NOTE: I confirmed via execution time that this is working.
1041
1059
  // Speedup is dependent on amount of data to sync and page size of sync.
1042
1060
  // It is significant for large data sets, but not for small ones.
1043
1061
  // election overhead will be minimized over time for very active networks.
@@ -1085,7 +1103,7 @@ describe("peer-device", () => {
1085
1103
  const remotePeers = (0, lodash_1.range)(peerCnt).map(() => {
1086
1104
  return buildRemotePeer({ errorRate, latencyMs });
1087
1105
  });
1088
- const peers = remotePeers.map(p => p.peer);
1106
+ const peers = remotePeers.map((p) => p.peer);
1089
1107
  for (const peer of peers) {
1090
1108
  getNotesTable(peer);
1091
1109
  }
@@ -1094,7 +1112,7 @@ describe("peer-device", () => {
1094
1112
  for (const peer2 of peers) {
1095
1113
  if (peer1 === peer2)
1096
1114
  continue;
1097
- const remotePeer = remotePeers.find(p => p.peer === peer2)?.remotePeer;
1115
+ const remotePeer = remotePeers.find((p) => p.peer === peer2)?.remotePeer;
1098
1116
  if (!remotePeer)
1099
1117
  throw new Error("Remote peer not found");
1100
1118
  await peer1.addConnection(remotePeer, { resyncInterval: 10_000 });
@@ -1134,13 +1152,16 @@ describe("peer-device", () => {
1134
1152
  console.log("Apply changes count: ", sync_group_1.SyncGroup.applyChangesCount);
1135
1153
  console.log("Network info count: ", sync_group_1.SyncGroup.getNetworkInfoCount);
1136
1154
  console.log("Elections count: ", sync_group_1.SyncGroup.electPreferredConnectionsCount);
1137
- console.log("Total calls: ", sync_group_1.SyncGroup.listChangesCount + sync_group_1.SyncGroup.applyChangesCount + sync_group_1.SyncGroup.getNetworkInfoCount + sync_group_1.SyncGroup.electPreferredConnectionsCount);
1138
- await Promise.all(peers.map(peer => peer.dispose()));
1155
+ console.log("Total calls: ", sync_group_1.SyncGroup.listChangesCount +
1156
+ sync_group_1.SyncGroup.applyChangesCount +
1157
+ sync_group_1.SyncGroup.getNetworkInfoCount +
1158
+ sync_group_1.SyncGroup.electPreferredConnectionsCount);
1159
+ await Promise.all(peers.map((peer) => peer.dispose()));
1139
1160
  });
1140
1161
  it.skip([
1141
1162
  `should not slow down as data accumulates many changes`,
1142
- `(this is a long running test that is left skipped unless explicitly checking for performance problems with syncing)`
1143
- ].join('\n '), async () => {
1163
+ `(this is a long running test that is left skipped unless explicitly checking for performance problems with syncing)`,
1164
+ ].join("\n "), async () => {
1144
1165
  // Create peers
1145
1166
  const peer1 = buildPeer();
1146
1167
  const peer2 = buildPeer();
@@ -1164,7 +1185,7 @@ describe("peer-device", () => {
1164
1185
  peer3.syncWithRemoteDevice(peer2),
1165
1186
  ]);
1166
1187
  // create many inserts, updates, and deletes in all of them
1167
- let allNotes = await peer1Notes.list();
1188
+ const allNotes = await peer1Notes.list();
1168
1189
  for (const changeBatch of (0, lodash_1.range)(100)) {
1169
1190
  const startTime = Date.now();
1170
1191
  for (const table of [peer1Notes, peer2Notes, peer3Notes]) {
@@ -1179,14 +1200,17 @@ describe("peer-device", () => {
1179
1200
  try {
1180
1201
  if (rand < 0.05) {
1181
1202
  await table.delete(note);
1182
- allNotes.splice(allNotes.findIndex(n => n.noteId === note.noteId), 1);
1203
+ allNotes.splice(allNotes.findIndex((n) => n.noteId === note.noteId), 1);
1183
1204
  }
1184
1205
  else if (rand < 0.95) {
1185
1206
  note.title = `Updated ${Math.random().toString().substring(1, 2)} - ${changeBatch}`;
1186
1207
  await table.save(note);
1187
1208
  }
1188
1209
  else {
1189
- const newNote = await table.save({ noteId: (0, peers_sdk_1.newid)(), title: `new note - ${changeBatch}` });
1210
+ const newNote = await table.save({
1211
+ noteId: (0, peers_sdk_1.newid)(),
1212
+ title: `new note - ${changeBatch}`,
1213
+ });
1190
1214
  allNotes.push(newNote);
1191
1215
  }
1192
1216
  }
@@ -1239,10 +1263,7 @@ describe("peer-device", () => {
1239
1263
  const peerNotesTable = getNotesTable(peer);
1240
1264
  const peerNotes = await peerNotesTable.list();
1241
1265
  expect(peerNotes).toEqual(myNotes);
1242
- await Promise.all([
1243
- me.dispose(),
1244
- peer.dispose(),
1245
- ]);
1266
+ await Promise.all([me.dispose(), peer.dispose()]);
1246
1267
  });
1247
1268
  it.skip("should should prioritize devices by lowest error * latency", async () => {
1248
1269
  const peerCnt = 4;
@@ -1251,7 +1272,7 @@ describe("peer-device", () => {
1251
1272
  const latencyMs = 100 * (i + 1);
1252
1273
  return buildRemotePeer({ errorRate, latencyMs });
1253
1274
  });
1254
- const peers = remotePeers.map(p => p.peer);
1275
+ const peers = remotePeers.map((p) => p.peer);
1255
1276
  // ensures the table exists and is being tracked
1256
1277
  for (const peer of peers) {
1257
1278
  getNotesTable(peer);
@@ -1260,7 +1281,7 @@ describe("peer-device", () => {
1260
1281
  for (const peer2 of peers) {
1261
1282
  if (peer1 === peer2)
1262
1283
  continue;
1263
- const remotePeer = remotePeers.find(p => p.peer === peer2)?.remotePeer;
1284
+ const remotePeer = remotePeers.find((p) => p.peer === peer2)?.remotePeer;
1264
1285
  if (!remotePeer)
1265
1286
  throw new Error("Remote peer not found");
1266
1287
  await peer1.addConnection(remotePeer, { resyncInterval: 1000 });
@@ -1314,11 +1335,15 @@ describe("peer-device", () => {
1314
1335
  const peer3DeviceId = peers[2].deviceId;
1315
1336
  const peer4DeviceId = peers[3].deviceId;
1316
1337
  const peer1 = peers[0];
1317
- expect(peer1.getConnections().map(c => c.deviceId)).toEqual([peer2DeviceId, peer3DeviceId, peer4DeviceId]);
1338
+ expect(peer1.getConnections().map((c) => c.deviceId)).toEqual([
1339
+ peer2DeviceId,
1340
+ peer3DeviceId,
1341
+ peer4DeviceId,
1342
+ ]);
1318
1343
  // TODO this has been moved to the connection manager
1319
- // peer1.removeLeastPreferredConnection();
1344
+ // peer1.removeLeastPreferredConnection();
1320
1345
  // expect(peer1.getConnections().map(c => c.deviceId)).toEqual([peer2DeviceId, peer3DeviceId]);
1321
- await Promise.all(peers.map(peer => peer.dispose()));
1346
+ await Promise.all(peers.map((peer) => peer.dispose()));
1322
1347
  });
1323
1348
  it.skip("should prune connections after 30 and changes should fully sync", async () => {
1324
1349
  const peerCnt = 50;
@@ -1327,7 +1352,7 @@ describe("peer-device", () => {
1327
1352
  const latencyMs = 1;
1328
1353
  return buildRemotePeer({ errorRate, latencyMs });
1329
1354
  });
1330
- const peers = remotePeers.map(p => p.peer);
1355
+ const peers = remotePeers.map((p) => p.peer);
1331
1356
  for (const peer of peers) {
1332
1357
  getNotesTable(peer);
1333
1358
  }
@@ -1337,12 +1362,12 @@ describe("peer-device", () => {
1337
1362
  for (const peer2 of peers) {
1338
1363
  if (peer1 === peer2)
1339
1364
  continue;
1340
- const remotePeer = remotePeers.find(p => p.peer === peer2)?.remotePeer;
1365
+ const remotePeer = remotePeers.find((p) => p.peer === peer2)?.remotePeer;
1341
1366
  if (!remotePeer)
1342
1367
  throw new Error("Remote peer not found");
1343
1368
  connCnt++;
1344
1369
  await peer1.addConnection(remotePeer, {
1345
- // resyncInterval: 10_000,
1370
+ // resyncInterval: 10_000,
1346
1371
  async onClose() {
1347
1372
  peer2.removeConnection(peer1.deviceId);
1348
1373
  peer1.removeConnection(peer2.deviceId);
@@ -1357,14 +1382,20 @@ describe("peer-device", () => {
1357
1382
  const peers1NI = [];
1358
1383
  for (const peer of peers) {
1359
1384
  const networkInfo = await peer.getNetworkInfo();
1360
- peers1NI.push({ deviceId: peer.deviceId, preferredDeviceIds: networkInfo.preferredDeviceIds.length });
1385
+ peers1NI.push({
1386
+ deviceId: peer.deviceId,
1387
+ preferredDeviceIds: networkInfo.preferredDeviceIds.length,
1388
+ });
1361
1389
  }
1362
- await Promise.all(peers.map(peer => peer.electPreferredConnections()));
1390
+ await Promise.all(peers.map((peer) => peer.electPreferredConnections()));
1363
1391
  // await sleep(2000);
1364
1392
  const peers2NI = [];
1365
1393
  for (const peer of peers) {
1366
1394
  const networkInfo = await peer.getNetworkInfo();
1367
- peers2NI.push({ deviceId: peer.deviceId, preferredDeviceIds: networkInfo.preferredDeviceIds.length });
1395
+ peers2NI.push({
1396
+ deviceId: peer.deviceId,
1397
+ preferredDeviceIds: networkInfo.preferredDeviceIds.length,
1398
+ });
1368
1399
  }
1369
1400
  stable = (0, lodash_1.isEqual)(peers1NI, peers2NI);
1370
1401
  console.log({ peers1NI, peers2NI });
@@ -1392,7 +1423,7 @@ describe("peer-device", () => {
1392
1423
  expect(peerNotes).toEqual(myNotes);
1393
1424
  expect(peer.getConnections().length).toBeLessThanOrEqual(peers_sdk_1.PeerDeviceConsts.MAX_CONNECTIONS);
1394
1425
  }
1395
- await Promise.all(peers.map(peer => peer.dispose()));
1426
+ await Promise.all(peers.map((peer) => peer.dispose()));
1396
1427
  });
1397
1428
  it.skip("should prune connections after 30 is reached but still sync the full network", async () => {
1398
1429
  const peerCnt = 50;
@@ -1401,7 +1432,7 @@ describe("peer-device", () => {
1401
1432
  const latencyMs = 1;
1402
1433
  return buildRemotePeer({ errorRate, latencyMs });
1403
1434
  });
1404
- const peers = remotePeers.map(p => p.peer);
1435
+ const peers = remotePeers.map((p) => p.peer);
1405
1436
  for (const peer of peers) {
1406
1437
  getNotesTable(peer);
1407
1438
  }
@@ -1411,12 +1442,13 @@ describe("peer-device", () => {
1411
1442
  for (const peer2 of peers) {
1412
1443
  if (peer1 === peer2)
1413
1444
  continue;
1414
- const remotePeer = remotePeers.find(p => p.peer === peer2)?.remotePeer;
1445
+ const remotePeer = remotePeers.find((p) => p.peer === peer2)?.remotePeer;
1415
1446
  if (!remotePeer)
1416
1447
  throw new Error("Remote peer not found");
1417
1448
  connCnt++;
1418
1449
  await peer1.addConnection(remotePeer, {
1419
- resyncInterval: 4_000, async onClose() {
1450
+ resyncInterval: 4_000,
1451
+ async onClose() {
1420
1452
  peer2.removeConnection(peer1.deviceId);
1421
1453
  peer1.removeConnection(peer2.deviceId);
1422
1454
  },
@@ -1451,7 +1483,10 @@ describe("peer-device", () => {
1451
1483
  expect(peerNotes).toEqual(myNotes);
1452
1484
  expect(peer.getConnections().length).toBeLessThanOrEqual(peers_sdk_1.PeerDeviceConsts.MAX_CONNECTIONS);
1453
1485
  }
1454
- const totalNetworkOps = sync_group_1.SyncGroup.listChangesCount + sync_group_1.SyncGroup.applyChangesCount + sync_group_1.SyncGroup.getNetworkInfoCount + sync_group_1.SyncGroup.electPreferredConnectionsCount;
1486
+ const totalNetworkOps = sync_group_1.SyncGroup.listChangesCount +
1487
+ sync_group_1.SyncGroup.applyChangesCount +
1488
+ sync_group_1.SyncGroup.getNetworkInfoCount +
1489
+ sync_group_1.SyncGroup.electPreferredConnectionsCount;
1455
1490
  console.log("Total count: ", totalNetworkOps);
1456
1491
  console.log("Total ops per peer: ", Math.round(totalNetworkOps / peerCnt));
1457
1492
  let stable = false;
@@ -1461,7 +1496,7 @@ describe("peer-device", () => {
1461
1496
  for (const peer of peers) {
1462
1497
  let preferredDeviceIds = (await peer.getNetworkInfo()).preferredDeviceIds;
1463
1498
  const connections = peer.getConnections();
1464
- preferredDeviceIds = preferredDeviceIds.filter(deviceId => connections.find(c => c.deviceId === deviceId));
1499
+ preferredDeviceIds = preferredDeviceIds.filter((deviceId) => connections.find((c) => c.deviceId === deviceId));
1465
1500
  expect(preferredDeviceIds.length).toBeLessThanOrEqual(peers_sdk_1.PeerDeviceConsts.MAX_CONNECTIONS);
1466
1501
  preferredDeviceIds.forEach((deviceId) => {
1467
1502
  deviceIdPriority1[deviceId] = (deviceIdPriority1[deviceId] || 0) + 1;
@@ -1483,7 +1518,7 @@ describe("peer-device", () => {
1483
1518
  for (const peer of peers) {
1484
1519
  let preferredDeviceIds = (await peer.getNetworkInfo()).preferredDeviceIds;
1485
1520
  const connections = peer.getConnections();
1486
- preferredDeviceIds = preferredDeviceIds.filter(deviceId => connections.find(c => c.deviceId === deviceId));
1521
+ preferredDeviceIds = preferredDeviceIds.filter((deviceId) => connections.find((c) => c.deviceId === deviceId));
1487
1522
  expect(preferredDeviceIds.length).toBeLessThanOrEqual(peers_sdk_1.PeerDeviceConsts.MAX_CONNECTIONS);
1488
1523
  preferredDeviceIds.forEach((deviceId) => {
1489
1524
  deviceIdPriority2[deviceId] = (deviceIdPriority2[deviceId] || 0) + 1;
@@ -1503,15 +1538,17 @@ describe("peer-device", () => {
1503
1538
  console.log("Device ID priority2: ", deviceIdPriority2);
1504
1539
  if ((0, lodash_1.isEqual)(deviceIdPriority1, deviceIdPriority2)) {
1505
1540
  stable = true;
1506
- const highestPriority = (0, lodash_1.sortBy)(Object.entries(deviceIdPriority1), ([k, v]) => v).map(([k, v]) => k).reverse();
1507
- const peer = peers.find(p => p.deviceId === highestPriority[0]);
1541
+ const highestPriority = (0, lodash_1.sortBy)(Object.entries(deviceIdPriority1), ([k, v]) => v)
1542
+ .map(([k, v]) => k)
1543
+ .reverse();
1544
+ const peer = peers.find((p) => p.deviceId === highestPriority[0]);
1508
1545
  if (!peer)
1509
1546
  throw new Error("Peer not found");
1510
1547
  const networkInfo = await peer.getNetworkInfo();
1511
1548
  console.log(networkInfo);
1512
1549
  }
1513
1550
  }
1514
- await Promise.all(peers.map(peer => peer.dispose()));
1551
+ await Promise.all(peers.map((peer) => peer.dispose()));
1515
1552
  });
1516
1553
  it.skip("very large networks - should prune connections after 30 but maintain a fully connected network", async () => {
1517
1554
  const peerCnt = 110;
@@ -1520,7 +1557,7 @@ describe("peer-device", () => {
1520
1557
  const latencyMs = 1;
1521
1558
  return buildRemotePeer({ errorRate, latencyMs });
1522
1559
  });
1523
- const peers = remotePeers.map(p => p.peer);
1560
+ const peers = remotePeers.map((p) => p.peer);
1524
1561
  for (const peer of peers) {
1525
1562
  getNotesTable(peer);
1526
1563
  }
@@ -1530,12 +1567,12 @@ describe("peer-device", () => {
1530
1567
  for (const peer2 of peers) {
1531
1568
  if (peer1 === peer2)
1532
1569
  continue;
1533
- const remotePeer = remotePeers.find(p => p.peer === peer2)?.remotePeer;
1570
+ const remotePeer = remotePeers.find((p) => p.peer === peer2)?.remotePeer;
1534
1571
  if (!remotePeer)
1535
1572
  throw new Error("Remote peer not found");
1536
1573
  connCnt++;
1537
1574
  await peer1.addConnection(remotePeer, {
1538
- // resyncInterval: 4_000,
1575
+ // resyncInterval: 4_000,
1539
1576
  async onClose() {
1540
1577
  peer2.removeConnection(peer1.deviceId);
1541
1578
  peer1.removeConnection(peer2.deviceId);
@@ -1555,24 +1592,21 @@ describe("peer-device", () => {
1555
1592
  for (const peer of peers) {
1556
1593
  let preferredDeviceIds = (await peer.getNetworkInfo()).preferredDeviceIds;
1557
1594
  const connections = peer.getConnections();
1558
- preferredDeviceIds = preferredDeviceIds.filter(deviceId => connections.find(c => c.deviceId === deviceId));
1595
+ preferredDeviceIds = preferredDeviceIds.filter((deviceId) => connections.find((c) => c.deviceId === deviceId));
1559
1596
  expect(preferredDeviceIds.length).toBeLessThanOrEqual(peers_sdk_1.PeerDeviceConsts.MAX_CONNECTIONS);
1560
1597
  preferredDeviceIds.forEach((deviceId) => {
1561
1598
  deviceIdPriority1[deviceId] = (deviceIdPriority1[deviceId] || 0) + 1;
1562
1599
  });
1563
1600
  }
1564
1601
  for (const peer of peers) {
1565
- await Promise.race([
1566
- (0, peers_sdk_1.sleep)(20),
1567
- peer.electPreferredConnections(),
1568
- ]);
1602
+ await Promise.race([(0, peers_sdk_1.sleep)(20), peer.electPreferredConnections()]);
1569
1603
  }
1570
1604
  await (0, peers_sdk_1.sleep)(2000);
1571
1605
  const deviceIdPriority2 = {};
1572
1606
  for (const peer of peers) {
1573
1607
  let preferredDeviceIds = (await peer.getNetworkInfo()).preferredDeviceIds;
1574
1608
  const connections = peer.getConnections();
1575
- preferredDeviceIds = preferredDeviceIds.filter(deviceId => connections.find(c => c.deviceId === deviceId));
1609
+ preferredDeviceIds = preferredDeviceIds.filter((deviceId) => connections.find((c) => c.deviceId === deviceId));
1576
1610
  expect(preferredDeviceIds.length).toBeLessThanOrEqual(peers_sdk_1.PeerDeviceConsts.MAX_CONNECTIONS);
1577
1611
  preferredDeviceIds.forEach((deviceId) => {
1578
1612
  deviceIdPriority2[deviceId] = (deviceIdPriority2[deviceId] || 0) + 1;
@@ -1596,7 +1630,7 @@ describe("peer-device", () => {
1596
1630
  console.log("Total number of priority connections: ", Object.values(deviceIdPriority1).reduce((a, b) => a + b, 0));
1597
1631
  // walk the network but only through priority connections
1598
1632
  const connectedDevices = new Set();
1599
- let connectedPeers = [peers[0]];
1633
+ const connectedPeers = [peers[0]];
1600
1634
  while (connectedPeers.length) {
1601
1635
  const peer = connectedPeers.pop();
1602
1636
  if (!peer)
@@ -1605,7 +1639,7 @@ describe("peer-device", () => {
1605
1639
  const priorityDeviceIds = peer.priorityDeviceIds.priorityDeviceIds;
1606
1640
  for (const deviceId of priorityDeviceIds) {
1607
1641
  if (!connectedDevices.has(deviceId)) {
1608
- const peer = peers.find(p => p.deviceId === deviceId);
1642
+ const peer = peers.find((p) => p.deviceId === deviceId);
1609
1643
  if (!peer)
1610
1644
  throw new Error("Peer not found");
1611
1645
  connectedPeers.push(peer);
@@ -1627,12 +1661,15 @@ describe("peer-device", () => {
1627
1661
  // }
1628
1662
  if ((0, lodash_1.isEqual)(deviceIdPriority1, deviceIdPriority2)) {
1629
1663
  stable = true;
1630
- console.log("highest priority devices: ", (0, lodash_1.sortBy)(Object.entries(deviceIdPriority1), ([k, v]) => v).map(([k, v]) => [k, v]).reverse().slice(0, 20));
1664
+ console.log("highest priority devices: ", (0, lodash_1.sortBy)(Object.entries(deviceIdPriority1), ([k, v]) => v)
1665
+ .map(([k, v]) => [k, v])
1666
+ .reverse()
1667
+ .slice(0, 20));
1631
1668
  expect(connectedDevices.size).toEqual(peerCnt);
1632
1669
  // expect(preferredDeviceIds.size).toEqual(peerCnt);
1633
1670
  }
1634
1671
  }
1635
- await Promise.all(peers.map(peer => peer.dispose()));
1672
+ await Promise.all(peers.map((peer) => peer.dispose()));
1636
1673
  });
1637
1674
  // For some reason this test fails when run with the rest but works when run alone
1638
1675
  it.skip("should handle a change has data that doesn't match the schema", async () => {
@@ -1650,8 +1687,8 @@ describe("peer-device", () => {
1650
1687
  recordId: noteId,
1651
1688
  createdAt: now,
1652
1689
  appliedAt: now,
1653
- op: 'set',
1654
- path: '/',
1690
+ op: "set",
1691
+ path: "/",
1655
1692
  // @ts-expect-error setting `title: string` to a number to simulate bad data
1656
1693
  value: { noteId, title: 1 },
1657
1694
  });
@@ -1682,8 +1719,8 @@ describe("peer-device", () => {
1682
1719
  recordId,
1683
1720
  createdAt: ts,
1684
1721
  appliedAt: ts,
1685
- op: 'set',
1686
- path: '/',
1722
+ op: "set",
1723
+ path: "/",
1687
1724
  value: { noteId: recordId, title: "note inserted" },
1688
1725
  },
1689
1726
  {
@@ -1693,8 +1730,8 @@ describe("peer-device", () => {
1693
1730
  createdAt: ts + 1,
1694
1731
  appliedAt: ts + 1,
1695
1732
  // @ts-expect-error invalid op
1696
- op: 'junk',
1697
- path: '/string',
1733
+ op: "junk",
1734
+ path: "/string",
1698
1735
  value: "junk updated",
1699
1736
  },
1700
1737
  {
@@ -1703,10 +1740,10 @@ describe("peer-device", () => {
1703
1740
  recordId,
1704
1741
  createdAt: ts + 2,
1705
1742
  appliedAt: ts + 2,
1706
- op: 'set',
1707
- path: '/title',
1743
+ op: "set",
1744
+ path: "/title",
1708
1745
  value: "note updated",
1709
- }
1746
+ },
1710
1747
  ]);
1711
1748
  const notes = await peer1Notes.list();
1712
1749
  expect(notes).toEqual([{ noteId: recordId, title: "note updated" }]);