@peers-app/peers-device 0.14.1 → 0.15.1

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