@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.
- package/dist/chunk-download-manager.d.ts +2 -2
- package/dist/chunk-download-manager.js +1 -1
- package/dist/chunk-download-manager.js.map +1 -1
- package/dist/chunk-download-manager.test.js +57 -57
- package/dist/chunk-download-manager.test.js.map +1 -1
- package/dist/chunk-download.types.d.ts +1 -1
- package/dist/connection-manager/connection-manager-priorities.d.ts +1 -1
- package/dist/connection-manager/connection-manager-priorities.js +10 -6
- package/dist/connection-manager/connection-manager-priorities.js.map +1 -1
- package/dist/connection-manager/connection-manager-priorities.test.js +192 -194
- package/dist/connection-manager/connection-manager-priorities.test.js.map +1 -1
- package/dist/connection-manager/connection-manager.d.ts +2 -2
- package/dist/connection-manager/connection-manager.js +71 -55
- package/dist/connection-manager/connection-manager.js.map +1 -1
- package/dist/connection-manager/connection-manager.test.js +165 -147
- package/dist/connection-manager/connection-manager.test.js.map +1 -1
- package/dist/connection-manager/connection-state.type.d.ts +1 -1
- package/dist/connection-manager/device-message-handler.types.d.ts +6 -6
- package/dist/connection-manager/device-messages.d.ts +4 -4
- package/dist/connection-manager/device-messages.js +56 -40
- package/dist/connection-manager/device-messages.js.map +1 -1
- package/dist/connection-manager/group-invite-messages.d.ts +2 -2
- package/dist/connection-manager/group-invite-messages.js +36 -47
- package/dist/connection-manager/group-invite-messages.js.map +1 -1
- package/dist/connection-manager/hops-map.js +4 -4
- package/dist/connection-manager/hops-map.js.map +1 -1
- package/dist/connection-manager/hops-map.test.js +3 -3
- package/dist/connection-manager/hops-map.test.js.map +1 -1
- package/dist/connection-manager/network-manager.d.ts +2 -2
- package/dist/connection-manager/network-manager.js +81 -75
- package/dist/connection-manager/network-manager.js.map +1 -1
- package/dist/index.d.ts +12 -12
- package/dist/json-diff.d.ts +2 -2
- package/dist/json-diff.js +30 -27
- package/dist/json-diff.js.map +1 -1
- package/dist/local.data-source.d.ts +1 -1
- package/dist/local.data-source.js +23 -23
- package/dist/local.data-source.js.map +1 -1
- package/dist/local.data-source.test.js +17 -17
- package/dist/local.data-source.test.js.map +1 -1
- package/dist/machine-stats.js +57 -51
- package/dist/machine-stats.js.map +1 -1
- package/dist/machine-stats.test.js +42 -42
- package/dist/machine-stats.test.js.map +1 -1
- package/dist/main.d.ts +2 -2
- package/dist/main.js +10 -8
- package/dist/main.js.map +1 -1
- package/dist/packages.tracked-data-source.d.ts +1 -1
- package/dist/packages.tracked-data-source.js.map +1 -1
- package/dist/persistent-vars.test.js +148 -148
- package/dist/persistent-vars.test.js.map +1 -1
- package/dist/pvars.tracked-data-source.d.ts +1 -1
- package/dist/pvars.tracked-data-source.js +12 -10
- package/dist/pvars.tracked-data-source.js.map +1 -1
- package/dist/sync-group.d.ts +2 -2
- package/dist/sync-group.js +110 -88
- package/dist/sync-group.js.map +1 -1
- package/dist/sync-group.test.js +157 -120
- package/dist/sync-group.test.js.map +1 -1
- package/dist/tracked-data-source.d.ts +1 -1
- package/dist/tracked-data-source.js +61 -62
- package/dist/tracked-data-source.js.map +1 -1
- package/dist/tracked-data-source.test.js +507 -299
- package/dist/tracked-data-source.test.js.map +1 -1
- package/dist/websocket-client.d.ts +1 -1
- package/dist/websocket-client.js +50 -41
- package/dist/websocket-client.js.map +1 -1
- package/package.json +3 -3
|
@@ -75,11 +75,15 @@ async function connectDeviceManagers(connMan1, connMan2) {
|
|
|
75
75
|
const connMan1Device = new peers_sdk_1.Device(connMan1.userContext.userId, connMan1.userContext.deviceId(), keys1);
|
|
76
76
|
const connMan2Device = new peers_sdk_1.Device(connMan2.userContext.userId, connMan2.userContext.deviceId(), keys2);
|
|
77
77
|
// Connection for connMan1 - represents the remote connMan2
|
|
78
|
-
const connMan1Connection = new peers_sdk_1.Connection(connMan1Socket, connMan1Device, [
|
|
78
|
+
const connMan1Connection = new peers_sdk_1.Connection(connMan1Socket, connMan1Device, [
|
|
79
|
+
"http://localhost:3000",
|
|
80
|
+
]);
|
|
79
81
|
// Connection for connMan2 - represents the remote connMan1
|
|
80
|
-
const connMan2Connection = new peers_sdk_1.Connection(connMan2Socket, connMan2Device, [
|
|
82
|
+
const connMan2Connection = new peers_sdk_1.Connection(connMan2Socket, connMan2Device, [
|
|
83
|
+
"http://localhost:3000",
|
|
84
|
+
]);
|
|
81
85
|
// Perform handshake from connMan1 to connMan2
|
|
82
|
-
await connMan1Connection.doHandshake(
|
|
86
|
+
await connMan1Connection.doHandshake("http://localhost:3000");
|
|
83
87
|
connMan1Connection.secureLocal = true;
|
|
84
88
|
connMan1Connection.secureRemote = true;
|
|
85
89
|
connMan2Connection.secureLocal = true;
|
|
@@ -96,7 +100,7 @@ async function connectionManagerFactory(userId = (0, peers_sdk_1.newid)(), devic
|
|
|
96
100
|
const groupDbs = {};
|
|
97
101
|
function getDb(dataContextId) {
|
|
98
102
|
const dbKey = `${deviceId}_${dataContextId}`;
|
|
99
|
-
const db = groupDbs[dbKey] || new local_data_source_1.DBLocal(
|
|
103
|
+
const db = groupDbs[dbKey] || new local_data_source_1.DBLocal(":memory:");
|
|
100
104
|
groupDbs[dataContextId] = db;
|
|
101
105
|
return db;
|
|
102
106
|
}
|
|
@@ -121,7 +125,9 @@ async function connectionManagerFactory(userId = (0, peers_sdk_1.newid)(), devic
|
|
|
121
125
|
const userContext = new peers_sdk_1.UserContext(userId, dataSourceFactory, true);
|
|
122
126
|
await userContext.loadingPromise; // Wait for initialization to complete
|
|
123
127
|
userContext.deviceId(deviceId); // Now set the deviceId after DB load
|
|
124
|
-
const connMan = new connection_manager_1.ConnectionManager(userContext, changeTrackingTableFactory, localDevice, groupId => {
|
|
128
|
+
const connMan = new connection_manager_1.ConnectionManager(userContext, changeTrackingTableFactory, localDevice, (groupId) => {
|
|
129
|
+
throw new Error("group keys not supported");
|
|
130
|
+
});
|
|
125
131
|
return connMan;
|
|
126
132
|
}
|
|
127
133
|
describe("connection-manager", () => {
|
|
@@ -132,7 +138,7 @@ describe("connection-manager", () => {
|
|
|
132
138
|
});
|
|
133
139
|
describe("sendDeviceMessage", () => {
|
|
134
140
|
// Shared network topology for tests
|
|
135
|
-
const userId =
|
|
141
|
+
const userId = "00mhiuq9q3ik7moqqjt00000u";
|
|
136
142
|
let connMan1;
|
|
137
143
|
let connMan2;
|
|
138
144
|
let connMan2b;
|
|
@@ -145,13 +151,13 @@ describe("connection-manager", () => {
|
|
|
145
151
|
// connMan1 <-> connMan2 <-> connMan3
|
|
146
152
|
// | |
|
|
147
153
|
// +<- connMan2b <-+
|
|
148
|
-
connMan1 = await connectionManagerFactory(userId,
|
|
149
|
-
connMan2 = await connectionManagerFactory(userId,
|
|
150
|
-
connMan2b = await connectionManagerFactory(userId,
|
|
151
|
-
connMan2c = await connectionManagerFactory(userId,
|
|
152
|
-
connMan3 = await connectionManagerFactory(userId,
|
|
153
|
-
connMan3b = await connectionManagerFactory(userId,
|
|
154
|
-
connMan4 = await connectionManagerFactory(userId,
|
|
154
|
+
connMan1 = await connectionManagerFactory(userId, "00mhiuq9q3ik7moqqjt000010");
|
|
155
|
+
connMan2 = await connectionManagerFactory(userId, "00mhiuq9q3ik7moqqjt000020");
|
|
156
|
+
connMan2b = await connectionManagerFactory(userId, "00mhiuq9q3ik7moqqjt00002b");
|
|
157
|
+
connMan2c = await connectionManagerFactory(userId, "00mhiuq9q3ik7moqqjt00002c");
|
|
158
|
+
connMan3 = await connectionManagerFactory(userId, "00mhiuq9q3ik7moqqjt000030");
|
|
159
|
+
connMan3b = await connectionManagerFactory(userId, "00mhiuq9q3ik7moqqjt00003b");
|
|
160
|
+
connMan4 = await connectionManagerFactory(userId, "00mhiuq9q3ik7moqqjt000040");
|
|
155
161
|
await Promise.all([
|
|
156
162
|
connectDeviceManagers(connMan1, connMan2),
|
|
157
163
|
connectDeviceManagers(connMan1, connMan2b),
|
|
@@ -210,7 +216,7 @@ describe("connection-manager", () => {
|
|
|
210
216
|
dataContextId: (0, peers_sdk_1.newid)(),
|
|
211
217
|
ttl: 3,
|
|
212
218
|
payload: null,
|
|
213
|
-
hops: []
|
|
219
|
+
hops: [],
|
|
214
220
|
};
|
|
215
221
|
// This should not hang - should resolve immediately with TTL0 when there are no connections
|
|
216
222
|
const response = await connMan.sendDeviceMessage(message);
|
|
@@ -228,12 +234,12 @@ describe("connection-manager", () => {
|
|
|
228
234
|
dataContextId: nonExistentGroupId, // But this group doesn't exist
|
|
229
235
|
ttl: 3,
|
|
230
236
|
payload: null,
|
|
231
|
-
hops: []
|
|
237
|
+
hops: [],
|
|
232
238
|
};
|
|
233
239
|
const response = await connMan.sendDeviceMessage(message);
|
|
234
240
|
expect(response.isError).toBe(true);
|
|
235
241
|
expect(response.statusCode).toBe(400);
|
|
236
|
-
expect(response.statusMessage).toBe(
|
|
242
|
+
expect(response.statusMessage).toBe(`Device does not support specified dataContext: ${nonExistentGroupId}`);
|
|
237
243
|
await connMan.dispose();
|
|
238
244
|
});
|
|
239
245
|
it("should return TTL0 when TTL becomes 1 and no direct connection exists", async () => {
|
|
@@ -245,7 +251,7 @@ describe("connection-manager", () => {
|
|
|
245
251
|
dataContextId: (0, peers_sdk_1.newid)(),
|
|
246
252
|
ttl: 2, // Will decrement to 1
|
|
247
253
|
payload: null,
|
|
248
|
-
hops: []
|
|
254
|
+
hops: [],
|
|
249
255
|
};
|
|
250
256
|
const response = await connMan.sendDeviceMessage(message);
|
|
251
257
|
// Should return TTL0 because after decrement ttl=1 and there's no direct connection
|
|
@@ -264,7 +270,7 @@ describe("connection-manager", () => {
|
|
|
264
270
|
dataContextId: user1Id, // Use userId as the dataContext (personal group)
|
|
265
271
|
ttl: 3,
|
|
266
272
|
payload: null,
|
|
267
|
-
hops: []
|
|
273
|
+
hops: [],
|
|
268
274
|
};
|
|
269
275
|
// Send message - it should be processed by the groupDevice
|
|
270
276
|
const response = await connMan1.sendDeviceMessage(message);
|
|
@@ -277,7 +283,7 @@ describe("connection-manager", () => {
|
|
|
277
283
|
it("should return error for oversized message payload", async () => {
|
|
278
284
|
const connMan = await connectionManagerFactory();
|
|
279
285
|
// Create a payload larger than 64KB
|
|
280
|
-
const largePayload = new Array(64 * 100).fill(0).map(c => Math.random());
|
|
286
|
+
const largePayload = new Array(64 * 100).fill(0).map((c) => Math.random());
|
|
281
287
|
const message = {
|
|
282
288
|
deviceMessageId: (0, peers_sdk_1.newid)(),
|
|
283
289
|
fromDeviceId: (0, peers_sdk_1.newid)(),
|
|
@@ -295,8 +301,8 @@ describe("connection-manager", () => {
|
|
|
295
301
|
await connMan.dispose();
|
|
296
302
|
});
|
|
297
303
|
it("should forward message directly to connected device", async () => {
|
|
298
|
-
const connMan2SendSpy = jest.spyOn(connMan2,
|
|
299
|
-
const connMan3SendSpy = jest.spyOn(connMan3,
|
|
304
|
+
const connMan2SendSpy = jest.spyOn(connMan2, "sendDeviceMessage");
|
|
305
|
+
const connMan3SendSpy = jest.spyOn(connMan3, "sendDeviceMessage");
|
|
300
306
|
const message = {
|
|
301
307
|
deviceMessageId: (0, peers_sdk_1.newid)(),
|
|
302
308
|
fromDeviceId: connMan1.userContext.deviceId(),
|
|
@@ -319,7 +325,7 @@ describe("connection-manager", () => {
|
|
|
319
325
|
connMan3SendSpy.mockRestore();
|
|
320
326
|
});
|
|
321
327
|
it("should forward message through indirect connections", async () => {
|
|
322
|
-
const connMan2bSendSpy = jest.spyOn(connMan2b,
|
|
328
|
+
const connMan2bSendSpy = jest.spyOn(connMan2b, "sendDeviceMessage");
|
|
323
329
|
const message = {
|
|
324
330
|
deviceMessageId: (0, peers_sdk_1.newid)(),
|
|
325
331
|
fromDeviceId: connMan1.userContext.deviceId(),
|
|
@@ -327,13 +333,13 @@ describe("connection-manager", () => {
|
|
|
327
333
|
dataContextId: userId, // both devices are same user so both will have this dataContext
|
|
328
334
|
ttl: 3,
|
|
329
335
|
payload: { test: "data", customField: "value123" },
|
|
330
|
-
hops: []
|
|
336
|
+
hops: [],
|
|
331
337
|
};
|
|
332
338
|
// Send message from connMan1 - it should be forwarded through the network to connMan3
|
|
333
339
|
const response = await connMan1.sendDeviceMessage(message);
|
|
334
340
|
// The message should have been forwarded successfully and return "No handler for message"
|
|
335
341
|
expect(response).toBeDefined();
|
|
336
|
-
expect(typeof response).toEqual(
|
|
342
|
+
expect(typeof response).toEqual("object");
|
|
337
343
|
expect(response.statusCode).toBe(404);
|
|
338
344
|
expect(response.statusMessage).toBe("No handler for message");
|
|
339
345
|
// Verify message was only sent through connMan2 (not 2b) since that had the indirect connection
|
|
@@ -346,15 +352,15 @@ describe("connection-manager", () => {
|
|
|
346
352
|
const hub3 = [];
|
|
347
353
|
const hub4 = [];
|
|
348
354
|
const mocks = new Map();
|
|
349
|
-
for (
|
|
350
|
-
const hubNum = (i + 1).toString().padStart(2,
|
|
355
|
+
for (const [i, hub] of [hub1, hub2, hub3, hub4].entries()) {
|
|
356
|
+
const hubNum = (i + 1).toString().padStart(2, "0");
|
|
351
357
|
for (let j = 0; j < 4; j++) {
|
|
352
|
-
const deviceNum = (j + 1).toString().padStart(2,
|
|
358
|
+
const deviceNum = (j + 1).toString().padStart(2, "0");
|
|
353
359
|
const deviceId = `000000000hub${hubNum}000device${deviceNum}`;
|
|
354
360
|
const connMan = await connectionManagerFactory(userId, deviceId);
|
|
355
361
|
// NOTE: Limit to 2 to force ConnectionManager to try to limit calls
|
|
356
362
|
connMan.MAX_CONNECTIONS_TO_FORWARD_MESSAGES_TO = 2;
|
|
357
|
-
mocks.set(connMan, jest.spyOn(connMan,
|
|
363
|
+
mocks.set(connMan, jest.spyOn(connMan, "sendDeviceMessage"));
|
|
358
364
|
if (j > 0) {
|
|
359
365
|
await connectDeviceManagers(hub[0], connMan);
|
|
360
366
|
}
|
|
@@ -366,10 +372,10 @@ describe("connection-manager", () => {
|
|
|
366
372
|
await connectDeviceManagers(hub2[0], hub3[0]);
|
|
367
373
|
await connectDeviceManagers(hub1[0], hub4[0]); // another hub off hub1 with no path to hub3
|
|
368
374
|
await Promise.all([
|
|
369
|
-
...hub1.map(d => d.refreshAllNetworkInfo()),
|
|
370
|
-
...hub2.map(d => d.refreshAllNetworkInfo()),
|
|
371
|
-
...hub3.map(d => d.refreshAllNetworkInfo()),
|
|
372
|
-
...hub4.map(d => d.refreshAllNetworkInfo()),
|
|
375
|
+
...hub1.map((d) => d.refreshAllNetworkInfo()),
|
|
376
|
+
...hub2.map((d) => d.refreshAllNetworkInfo()),
|
|
377
|
+
...hub3.map((d) => d.refreshAllNetworkInfo()),
|
|
378
|
+
...hub4.map((d) => d.refreshAllNetworkInfo()),
|
|
373
379
|
]);
|
|
374
380
|
// send message from hub1[-1] to hub3[-1]
|
|
375
381
|
const sourceConnMan = hub1[hub1.length - 1];
|
|
@@ -380,8 +386,8 @@ describe("connection-manager", () => {
|
|
|
380
386
|
toDeviceId: targetConnMan.userContext.deviceId(),
|
|
381
387
|
dataContextId: userId,
|
|
382
388
|
ttl: 5,
|
|
383
|
-
payload: [
|
|
384
|
-
hops: []
|
|
389
|
+
payload: ["getNetworkInfo"],
|
|
390
|
+
hops: [],
|
|
385
391
|
};
|
|
386
392
|
const response = await sourceConnMan.sendDeviceMessage(message);
|
|
387
393
|
expect(response).toBeDefined();
|
|
@@ -393,8 +399,15 @@ describe("connection-manager", () => {
|
|
|
393
399
|
hub3[0].userContext.deviceId(),
|
|
394
400
|
hub3[hub3.length - 1].userContext.deviceId(),
|
|
395
401
|
]);
|
|
396
|
-
const expectCalled = [
|
|
397
|
-
|
|
402
|
+
const expectCalled = [
|
|
403
|
+
hub1[hub1.length - 1],
|
|
404
|
+
hub1[0],
|
|
405
|
+
hub4[0],
|
|
406
|
+
hub2[0],
|
|
407
|
+
hub3[0],
|
|
408
|
+
hub3[hub3.length - 1],
|
|
409
|
+
];
|
|
410
|
+
for (const connMan of [...hub1, ...hub2, ...hub3, ...hub4]) {
|
|
398
411
|
const mock = mocks.get(connMan);
|
|
399
412
|
const numCalls = mock.mock.calls.length;
|
|
400
413
|
const deviceId = connMan.userContext.deviceId();
|
|
@@ -410,10 +423,10 @@ describe("connection-manager", () => {
|
|
|
410
423
|
}
|
|
411
424
|
}
|
|
412
425
|
// Clean up
|
|
413
|
-
for (
|
|
426
|
+
for (const connMan of [...hub1, ...hub2, ...hub3, ...hub4]) {
|
|
414
427
|
await connMan.dispose();
|
|
415
428
|
}
|
|
416
|
-
for (
|
|
429
|
+
for (const mock of mocks.values()) {
|
|
417
430
|
mock.mockRestore();
|
|
418
431
|
}
|
|
419
432
|
});
|
|
@@ -422,13 +435,13 @@ describe("connection-manager", () => {
|
|
|
422
435
|
const hub2 = [];
|
|
423
436
|
const hub3 = [];
|
|
424
437
|
const mocks = new Map();
|
|
425
|
-
for (
|
|
426
|
-
const hubNum = (i + 1).toString().padStart(2,
|
|
438
|
+
for (const [i, hub] of [hub1, hub2, hub3].entries()) {
|
|
439
|
+
const hubNum = (i + 1).toString().padStart(2, "0");
|
|
427
440
|
for (let j = 0; j < 10; j++) {
|
|
428
|
-
const deviceNum = (j + 1).toString().padStart(2,
|
|
441
|
+
const deviceNum = (j + 1).toString().padStart(2, "0");
|
|
429
442
|
const deviceId = `000000000hub${hubNum}000device${deviceNum}`;
|
|
430
443
|
const connMan = await connectionManagerFactory(userId, deviceId);
|
|
431
|
-
mocks.set(connMan, jest.spyOn(connMan,
|
|
444
|
+
mocks.set(connMan, jest.spyOn(connMan, "sendDeviceMessage"));
|
|
432
445
|
if (j > 0) {
|
|
433
446
|
await connectDeviceManagers(hub[0], connMan);
|
|
434
447
|
}
|
|
@@ -440,9 +453,9 @@ describe("connection-manager", () => {
|
|
|
440
453
|
await connectDeviceManagers(hub1[0], hub2[0]);
|
|
441
454
|
await connectDeviceManagers(hub2[0], hub3[0]);
|
|
442
455
|
await Promise.all([
|
|
443
|
-
...hub1.map(d => d.refreshAllNetworkInfo()),
|
|
444
|
-
...hub2.map(d => d.refreshAllNetworkInfo()),
|
|
445
|
-
...hub3.map(d => d.refreshAllNetworkInfo()),
|
|
456
|
+
...hub1.map((d) => d.refreshAllNetworkInfo()),
|
|
457
|
+
...hub2.map((d) => d.refreshAllNetworkInfo()),
|
|
458
|
+
...hub3.map((d) => d.refreshAllNetworkInfo()),
|
|
446
459
|
]);
|
|
447
460
|
// send message from hub1[-1] to hub3[-1]
|
|
448
461
|
const sourceConnMan = hub1[hub1.length - 1];
|
|
@@ -453,23 +466,29 @@ describe("connection-manager", () => {
|
|
|
453
466
|
toDeviceId: targetConnMan.userContext.deviceId(),
|
|
454
467
|
dataContextId: userId,
|
|
455
468
|
ttl: 5,
|
|
456
|
-
payload: [
|
|
457
|
-
hops: []
|
|
469
|
+
payload: ["getNetworkInfo"],
|
|
470
|
+
hops: [],
|
|
458
471
|
};
|
|
459
472
|
const response = await sourceConnMan.sendDeviceMessage(message);
|
|
460
473
|
expect(response).toBeDefined();
|
|
461
474
|
expect(response.statusCode).toBe(200);
|
|
462
475
|
expect(response.hops).toEqual([
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
476
|
+
"000000000hub01000device10",
|
|
477
|
+
"000000000hub01000device01",
|
|
478
|
+
"000000000hub02000device01",
|
|
479
|
+
"000000000hub03000device01",
|
|
480
|
+
"000000000hub03000device10",
|
|
468
481
|
]);
|
|
469
482
|
// NOTE the blind calls only happen in the first hub. By hub2, the path is known since it's only two hops away
|
|
470
483
|
// ALSO NOTE: because of the trimming of leaf nodes, only hub1[0] is called even though MAX is 6
|
|
471
|
-
const expectCalled = [
|
|
472
|
-
|
|
484
|
+
const expectCalled = [
|
|
485
|
+
hub1[hub1.length - 1],
|
|
486
|
+
hub1[0],
|
|
487
|
+
hub2[0],
|
|
488
|
+
hub3[0],
|
|
489
|
+
hub3[hub3.length - 1],
|
|
490
|
+
];
|
|
491
|
+
for (const connMan of [...hub1, ...hub2, ...hub3]) {
|
|
473
492
|
const mock = mocks.get(connMan);
|
|
474
493
|
const numCalls = mock.mock.calls.length;
|
|
475
494
|
const deviceId = connMan.userContext.deviceId();
|
|
@@ -485,10 +504,10 @@ describe("connection-manager", () => {
|
|
|
485
504
|
}
|
|
486
505
|
}
|
|
487
506
|
// Clean up
|
|
488
|
-
for (
|
|
507
|
+
for (const connMan of [...hub1, ...hub2, ...hub3]) {
|
|
489
508
|
await connMan.dispose();
|
|
490
509
|
}
|
|
491
|
-
for (
|
|
510
|
+
for (const mock of mocks.values()) {
|
|
492
511
|
mock.mockRestore();
|
|
493
512
|
}
|
|
494
513
|
});
|
|
@@ -501,14 +520,14 @@ describe("connection-manager", () => {
|
|
|
501
520
|
const hub4 = [];
|
|
502
521
|
const mocks = new Map();
|
|
503
522
|
// Create 4 hubs with 4 devices each
|
|
504
|
-
for (
|
|
505
|
-
const hubNum = (i + 1).toString().padStart(2,
|
|
523
|
+
for (const [i, hub] of [hub1, hub2, hub3, hub4].entries()) {
|
|
524
|
+
const hubNum = (i + 1).toString().padStart(2, "0");
|
|
506
525
|
for (let j = 0; j < 7; j++) {
|
|
507
|
-
const deviceNum = (j + 1).toString().padStart(2,
|
|
526
|
+
const deviceNum = (j + 1).toString().padStart(2, "0");
|
|
508
527
|
const deviceId = `000000000hub${hubNum}000device${deviceNum}`;
|
|
509
528
|
const connMan = await connectionManagerFactory(userId, deviceId);
|
|
510
529
|
connMan.MAX_CONNECTIONS_TO_FORWARD_MESSAGES_TO = 4;
|
|
511
|
-
mocks.set(connMan, jest.spyOn(connMan,
|
|
530
|
+
mocks.set(connMan, jest.spyOn(connMan, "sendDeviceMessage"));
|
|
512
531
|
hub.push(connMan);
|
|
513
532
|
}
|
|
514
533
|
}
|
|
@@ -540,10 +559,10 @@ describe("connection-manager", () => {
|
|
|
540
559
|
// random side path from 1 to 4 to 3
|
|
541
560
|
await connectDeviceManagers(hub4[0], hub3[0]);
|
|
542
561
|
await Promise.all([
|
|
543
|
-
...hub1.map(d => d.refreshAllNetworkInfo()),
|
|
544
|
-
...hub2.map(d => d.refreshAllNetworkInfo()),
|
|
545
|
-
...hub3.map(d => d.refreshAllNetworkInfo()),
|
|
546
|
-
...hub4.map(d => d.refreshAllNetworkInfo()),
|
|
562
|
+
...hub1.map((d) => d.refreshAllNetworkInfo()),
|
|
563
|
+
...hub2.map((d) => d.refreshAllNetworkInfo()),
|
|
564
|
+
...hub3.map((d) => d.refreshAllNetworkInfo()),
|
|
565
|
+
...hub4.map((d) => d.refreshAllNetworkInfo()),
|
|
547
566
|
]);
|
|
548
567
|
// Send message from a leaf device in hub1 to a leaf device in hub3
|
|
549
568
|
const sourceConnMan = hub1[hub1.length - 1]; // Leaf device in hub1
|
|
@@ -554,14 +573,14 @@ describe("connection-manager", () => {
|
|
|
554
573
|
toDeviceId: targetConnMan.userContext.deviceId(),
|
|
555
574
|
dataContextId: userId,
|
|
556
575
|
ttl: 5,
|
|
557
|
-
payload: [
|
|
576
|
+
payload: ["getNetworkInfo"],
|
|
558
577
|
hops: [],
|
|
559
578
|
};
|
|
560
579
|
const response = await sourceConnMan.sendDeviceMessage(message);
|
|
561
580
|
// count number of times each connMan was called
|
|
562
581
|
let totalCalls = 0;
|
|
563
|
-
|
|
564
|
-
for (
|
|
582
|
+
const callStrs = [];
|
|
583
|
+
for (const connMan of [...hub1, ...hub2, ...hub3, ...hub4]) {
|
|
565
584
|
const mock = mocks.get(connMan);
|
|
566
585
|
const numCalls = mock.mock.calls.length;
|
|
567
586
|
if (!numCalls)
|
|
@@ -594,10 +613,10 @@ describe("connection-manager", () => {
|
|
|
594
613
|
]);
|
|
595
614
|
expect(totalCalls).toBe(21);
|
|
596
615
|
// Clean up
|
|
597
|
-
for (
|
|
616
|
+
for (const connMan of [...hub1, ...hub2, ...hub3, ...hub4]) {
|
|
598
617
|
await connMan.dispose();
|
|
599
618
|
}
|
|
600
|
-
for (
|
|
619
|
+
for (const mock of mocks.values()) {
|
|
601
620
|
mock.mockRestore();
|
|
602
621
|
}
|
|
603
622
|
});
|
|
@@ -608,14 +627,14 @@ describe("connection-manager", () => {
|
|
|
608
627
|
const hub2 = [];
|
|
609
628
|
const mocks = new Map();
|
|
610
629
|
// Create 2 hubs with 7 devices each
|
|
611
|
-
for (
|
|
612
|
-
const hubNum = (i + 1).toString().padStart(2,
|
|
630
|
+
for (const [i, hub] of [hub1, hub2].entries()) {
|
|
631
|
+
const hubNum = (i + 1).toString().padStart(2, "0");
|
|
613
632
|
for (let j = 0; j < 7; j++) {
|
|
614
|
-
const deviceNum = (j + 1).toString().padStart(2,
|
|
633
|
+
const deviceNum = (j + 1).toString().padStart(2, "0");
|
|
615
634
|
const deviceId = `000000000hub${hubNum}000device${deviceNum}`;
|
|
616
635
|
const connMan = await connectionManagerFactory(userId, deviceId);
|
|
617
636
|
connMan.MAX_CONNECTIONS_TO_FORWARD_MESSAGES_TO = 4;
|
|
618
|
-
mocks.set(connMan, jest.spyOn(connMan,
|
|
637
|
+
mocks.set(connMan, jest.spyOn(connMan, "sendDeviceMessage"));
|
|
619
638
|
hub.push(connMan);
|
|
620
639
|
}
|
|
621
640
|
}
|
|
@@ -635,8 +654,8 @@ describe("connection-manager", () => {
|
|
|
635
654
|
}
|
|
636
655
|
}
|
|
637
656
|
await Promise.all([
|
|
638
|
-
...hub1.map(d => d.refreshAllNetworkInfo()),
|
|
639
|
-
...hub2.map(d => d.refreshAllNetworkInfo()),
|
|
657
|
+
...hub1.map((d) => d.refreshAllNetworkInfo()),
|
|
658
|
+
...hub2.map((d) => d.refreshAllNetworkInfo()),
|
|
640
659
|
]);
|
|
641
660
|
// Send message from a leaf device in hub1 to a leaf device in hub2
|
|
642
661
|
const sourceConnMan = hub1[hub1.length - 1]; // Leaf device in hub1
|
|
@@ -647,14 +666,14 @@ describe("connection-manager", () => {
|
|
|
647
666
|
toDeviceId: targetConnMan.userContext.deviceId(),
|
|
648
667
|
dataContextId: userId,
|
|
649
668
|
ttl: 5,
|
|
650
|
-
payload: [
|
|
651
|
-
hops: []
|
|
669
|
+
payload: ["getNetworkInfo"],
|
|
670
|
+
hops: [],
|
|
652
671
|
};
|
|
653
672
|
const response = await sourceConnMan.sendDeviceMessage(message);
|
|
654
673
|
// count number of times each connMan was called
|
|
655
674
|
let totalCalls = 0;
|
|
656
|
-
|
|
657
|
-
for (
|
|
675
|
+
const callStrs = [];
|
|
676
|
+
for (const connMan of [...hub1, ...hub2]) {
|
|
658
677
|
const mock = mocks.get(connMan);
|
|
659
678
|
const numCalls = mock.mock.calls.length;
|
|
660
679
|
if (!numCalls)
|
|
@@ -674,21 +693,21 @@ describe("connection-manager", () => {
|
|
|
674
693
|
]);
|
|
675
694
|
console.log(callStrs.sort());
|
|
676
695
|
expect(callStrs.sort()).toEqual([
|
|
677
|
-
|
|
678
|
-
|
|
679
|
-
|
|
680
|
-
|
|
681
|
-
|
|
682
|
-
|
|
683
|
-
|
|
684
|
-
|
|
696
|
+
"Device 000000000hub01000device01 was called 1 times",
|
|
697
|
+
"Device 000000000hub01000device02 was called 1 times",
|
|
698
|
+
"Device 000000000hub01000device03 was called 1 times",
|
|
699
|
+
"Device 000000000hub01000device04 was called 1 times",
|
|
700
|
+
"Device 000000000hub01000device07 was called 1 times",
|
|
701
|
+
"Device 000000000hub02000device01 was called 4 times",
|
|
702
|
+
"Device 000000000hub02000device02 was called 4 times",
|
|
703
|
+
"Device 000000000hub02000device07 was called 1 times",
|
|
685
704
|
]);
|
|
686
705
|
expect(totalCalls).toBe(14);
|
|
687
706
|
// Clean up
|
|
688
|
-
for (
|
|
707
|
+
for (const connMan of [...hub1, ...hub2]) {
|
|
689
708
|
await connMan.dispose();
|
|
690
709
|
}
|
|
691
|
-
for (
|
|
710
|
+
for (const mock of mocks.values()) {
|
|
692
711
|
mock.mockRestore();
|
|
693
712
|
}
|
|
694
713
|
});
|
|
@@ -706,8 +725,8 @@ describe("connection-manager", () => {
|
|
|
706
725
|
toDeviceId: connMan3.userContext.deviceId(),
|
|
707
726
|
dataContextId: userId,
|
|
708
727
|
ttl: 5,
|
|
709
|
-
payload: [
|
|
710
|
-
hops: []
|
|
728
|
+
payload: ["ping", Date.now()],
|
|
729
|
+
hops: [],
|
|
711
730
|
};
|
|
712
731
|
await connMan1.sendDeviceMessage(message);
|
|
713
732
|
// connMan2 should have recorded the hop path
|
|
@@ -751,8 +770,8 @@ describe("connection-manager", () => {
|
|
|
751
770
|
toDeviceId: iso1.userContext.deviceId(),
|
|
752
771
|
dataContextId: isolatedUserId,
|
|
753
772
|
ttl: 5,
|
|
754
|
-
payload: [
|
|
755
|
-
hops: []
|
|
773
|
+
payload: ["ping", 1],
|
|
774
|
+
hops: [],
|
|
756
775
|
};
|
|
757
776
|
await iso4.sendDeviceMessage(firstMessage);
|
|
758
777
|
// Now iso2 should know about the path iso3 -> iso4 from the message hops
|
|
@@ -763,15 +782,15 @@ describe("connection-manager", () => {
|
|
|
763
782
|
[]);
|
|
764
783
|
expect(iso2KnowsPathToIso4).toContain(iso3Id);
|
|
765
784
|
// Second message: iso1 -> iso4 should use hop-derived knowledge
|
|
766
|
-
const sendSpy = jest.spyOn(iso3,
|
|
785
|
+
const sendSpy = jest.spyOn(iso3, "sendDeviceMessage");
|
|
767
786
|
const secondMessage = {
|
|
768
787
|
deviceMessageId: (0, peers_sdk_1.newid)(),
|
|
769
788
|
fromDeviceId: iso1.userContext.deviceId(),
|
|
770
789
|
toDeviceId: iso4.userContext.deviceId(),
|
|
771
790
|
dataContextId: isolatedUserId,
|
|
772
791
|
ttl: 5,
|
|
773
|
-
payload: [
|
|
774
|
-
hops: []
|
|
792
|
+
payload: ["ping", 2],
|
|
793
|
+
hops: [],
|
|
775
794
|
};
|
|
776
795
|
const response = await iso1.sendDeviceMessage(secondMessage);
|
|
777
796
|
expect(response.statusCode).toBe(200);
|
|
@@ -791,16 +810,16 @@ describe("connection-manager", () => {
|
|
|
791
810
|
const devices = [];
|
|
792
811
|
// Create longer chain: outer1 <-> center <-> outer2 <-> outer3
|
|
793
812
|
// This tests indirect path discovery (outer3 is 2 hops from center)
|
|
794
|
-
const center = await connectionManagerFactory(isolatedUserId,
|
|
795
|
-
const outer1 = await connectionManagerFactory(isolatedUserId,
|
|
796
|
-
const outer2 = await connectionManagerFactory(isolatedUserId,
|
|
797
|
-
const outer3 = await connectionManagerFactory(isolatedUserId,
|
|
813
|
+
const center = await connectionManagerFactory(isolatedUserId, "center-device-id-0000");
|
|
814
|
+
const outer1 = await connectionManagerFactory(isolatedUserId, "outer1-device-id-0000");
|
|
815
|
+
const outer2 = await connectionManagerFactory(isolatedUserId, "outer2-device-id-0000");
|
|
816
|
+
const outer3 = await connectionManagerFactory(isolatedUserId, "outer3-device-id-0000");
|
|
798
817
|
devices.push(center, outer1, outer2, outer3);
|
|
799
818
|
await connectDeviceManagers(outer1, center);
|
|
800
819
|
await connectDeviceManagers(center, outer2);
|
|
801
820
|
await connectDeviceManagers(outer2, outer3);
|
|
802
821
|
// Clear all hops data
|
|
803
|
-
devices.forEach(d => d.deviceMessages.hopsMap.clear());
|
|
822
|
+
devices.forEach((d) => d.deviceMessages.hopsMap.clear());
|
|
804
823
|
const centerId = center.userContext.deviceId();
|
|
805
824
|
const outer1Id = outer1.userContext.deviceId();
|
|
806
825
|
const outer2Id = outer2.userContext.deviceId();
|
|
@@ -813,8 +832,8 @@ describe("connection-manager", () => {
|
|
|
813
832
|
toDeviceId: outer1Id,
|
|
814
833
|
dataContextId: isolatedUserId,
|
|
815
834
|
ttl: 5,
|
|
816
|
-
payload: [
|
|
817
|
-
hops: []
|
|
835
|
+
payload: ["ping"],
|
|
836
|
+
hops: [],
|
|
818
837
|
});
|
|
819
838
|
// Center should have learned about the path outer3 <-> outer2 <-> center
|
|
820
839
|
// Center's hopsMap now knows: outer3<->outer2, outer2<->center
|
|
@@ -826,25 +845,25 @@ describe("connection-manager", () => {
|
|
|
826
845
|
// outer2 has path to outer3 (distance 1), outer1 does not
|
|
827
846
|
expect(centerToOuter3).toContain(outer2Id);
|
|
828
847
|
expect(centerToOuter3).not.toContain(outer1Id);
|
|
829
|
-
await Promise.all(devices.map(d => d.dispose()));
|
|
848
|
+
await Promise.all(devices.map((d) => d.dispose()));
|
|
830
849
|
});
|
|
831
850
|
it("should prioritize shorter hop-derived paths", async () => {
|
|
832
851
|
const isolatedUserId = (0, peers_sdk_1.newid)();
|
|
833
852
|
// Create network with multiple paths of different lengths:
|
|
834
853
|
// source -> shortPath -> target (2 hops)
|
|
835
854
|
// source -> longPath1 -> longPath2 -> target (3 hops)
|
|
836
|
-
const source = await connectionManagerFactory(isolatedUserId,
|
|
837
|
-
const shortPath = await connectionManagerFactory(isolatedUserId,
|
|
838
|
-
const longPath1 = await connectionManagerFactory(isolatedUserId,
|
|
839
|
-
const longPath2 = await connectionManagerFactory(isolatedUserId,
|
|
840
|
-
const target = await connectionManagerFactory(isolatedUserId,
|
|
855
|
+
const source = await connectionManagerFactory(isolatedUserId, "source-device-id-000");
|
|
856
|
+
const shortPath = await connectionManagerFactory(isolatedUserId, "shortpath-device-id-0");
|
|
857
|
+
const longPath1 = await connectionManagerFactory(isolatedUserId, "longpath1-device-id-0");
|
|
858
|
+
const longPath2 = await connectionManagerFactory(isolatedUserId, "longpath2-device-id-0");
|
|
859
|
+
const target = await connectionManagerFactory(isolatedUserId, "target-device-id-0000");
|
|
841
860
|
await connectDeviceManagers(source, shortPath);
|
|
842
861
|
await connectDeviceManagers(source, longPath1);
|
|
843
862
|
await connectDeviceManagers(shortPath, target);
|
|
844
863
|
await connectDeviceManagers(longPath1, longPath2);
|
|
845
864
|
await connectDeviceManagers(longPath2, target);
|
|
846
865
|
// Clear hops
|
|
847
|
-
[source, shortPath, longPath1, longPath2, target].forEach(d => d.deviceMessages.hopsMap.clear());
|
|
866
|
+
[source, shortPath, longPath1, longPath2, target].forEach((d) => d.deviceMessages.hopsMap.clear());
|
|
848
867
|
// First, learn the topology by sending messages through both paths
|
|
849
868
|
// Short path message
|
|
850
869
|
await target.sendDeviceMessage({
|
|
@@ -853,8 +872,8 @@ describe("connection-manager", () => {
|
|
|
853
872
|
toDeviceId: source.userContext.deviceId(),
|
|
854
873
|
dataContextId: isolatedUserId,
|
|
855
874
|
ttl: 5,
|
|
856
|
-
payload: [
|
|
857
|
-
hops: []
|
|
875
|
+
payload: ["learn-short"],
|
|
876
|
+
hops: [],
|
|
858
877
|
});
|
|
859
878
|
// Long path message (force it through longPath by sending from longPath2)
|
|
860
879
|
await longPath2.sendDeviceMessage({
|
|
@@ -863,24 +882,27 @@ describe("connection-manager", () => {
|
|
|
863
882
|
toDeviceId: source.userContext.deviceId(),
|
|
864
883
|
dataContextId: isolatedUserId,
|
|
865
884
|
ttl: 5,
|
|
866
|
-
payload: [
|
|
867
|
-
hops: []
|
|
885
|
+
payload: ["learn-long"],
|
|
886
|
+
hops: [],
|
|
868
887
|
});
|
|
869
888
|
// Source should now know both paths to target
|
|
870
889
|
// When querying, it should prioritize shortPath (distance 1 to target) over longPath1 (distance 2)
|
|
871
|
-
const sourceConnections = [
|
|
890
|
+
const sourceConnections = [
|
|
891
|
+
shortPath.userContext.deviceId(),
|
|
892
|
+
longPath1.userContext.deviceId(),
|
|
893
|
+
];
|
|
872
894
|
const candidates = source.deviceMessages.hopsMap.getDevicesLikelyToReach(target.userContext.deviceId(), sourceConnections, []);
|
|
873
895
|
// shortPath should be first (shorter distance)
|
|
874
896
|
if (candidates.length >= 2) {
|
|
875
897
|
expect(candidates[0]).toBe(shortPath.userContext.deviceId());
|
|
876
898
|
}
|
|
877
|
-
await Promise.all([source, shortPath, longPath1, longPath2, target].map(d => d.dispose()));
|
|
899
|
+
await Promise.all([source, shortPath, longPath1, longPath2, target].map((d) => d.dispose()));
|
|
878
900
|
});
|
|
879
901
|
it("should cleanup stale hop entries during periodic cleanup", async () => {
|
|
880
902
|
const isolatedUserId = (0, peers_sdk_1.newid)();
|
|
881
903
|
const device = await connectionManagerFactory(isolatedUserId, (0, peers_sdk_1.newid)());
|
|
882
904
|
// Manually add some hop observations
|
|
883
|
-
device.deviceMessages.hopsMap.addHopsObservation([
|
|
905
|
+
device.deviceMessages.hopsMap.addHopsObservation(["deviceA", "deviceB", "deviceC"]);
|
|
884
906
|
expect(device.deviceMessages.hopsMap.size).toBeGreaterThan(0);
|
|
885
907
|
// Cleanup with 0ms threshold should clear everything
|
|
886
908
|
device.deviceMessages.hopsMap.cleanupStaleEntries(0);
|
|
@@ -894,7 +916,8 @@ describe("connection-manager", () => {
|
|
|
894
916
|
const connMan1 = await connectionManagerFactory();
|
|
895
917
|
const connMan2 = await connectionManagerFactory();
|
|
896
918
|
await connectDeviceManagers(connMan1, connMan2);
|
|
897
|
-
|
|
919
|
+
// biome-ignore lint/complexity/useLiteralKeys: bracket access required — private `connectionStates` is not visible with dot notation from this test module
|
|
920
|
+
const connection = Array.from(connMan1["connectionStates"].keys())[0];
|
|
898
921
|
const indirectIds = connMan1.getConnectionIndirectRemoteDeviceIds(connection);
|
|
899
922
|
expect(indirectIds).toEqual([]);
|
|
900
923
|
await Promise.all([connMan1.dispose(), connMan2.dispose()]);
|
|
@@ -917,9 +940,7 @@ describe("connection-manager", () => {
|
|
|
917
940
|
const connection = connMan1.getDeviceConnection(connMan2.userContext.deviceId());
|
|
918
941
|
expect(connection).toBeDefined();
|
|
919
942
|
const indirectIds = connMan1.getConnectionIndirectRemoteDeviceIds(connection);
|
|
920
|
-
expect(indirectIds).toEqual([
|
|
921
|
-
connMan3.userContext.deviceId(),
|
|
922
|
-
]);
|
|
943
|
+
expect(indirectIds).toEqual([connMan3.userContext.deviceId()]);
|
|
923
944
|
await Promise.all([connMan1.dispose(), connMan2.dispose(), connMan3.dispose()]);
|
|
924
945
|
});
|
|
925
946
|
it("should exclude specified device IDs", async () => {
|
|
@@ -942,16 +963,11 @@ describe("connection-manager", () => {
|
|
|
942
963
|
connMan5.refreshAllNetworkInfo(),
|
|
943
964
|
]);
|
|
944
965
|
const connection = connMan1.getDeviceConnection(connMan2.userContext.deviceId());
|
|
945
|
-
const excludeList = [
|
|
946
|
-
connMan3.userContext.deviceId(),
|
|
947
|
-
connMan4.userContext.deviceId(),
|
|
948
|
-
];
|
|
966
|
+
const excludeList = [connMan3.userContext.deviceId(), connMan4.userContext.deviceId()];
|
|
949
967
|
const filteredIds = connMan1.getConnectionIndirectRemoteDeviceIds(connection, excludeList);
|
|
950
968
|
expect(filteredIds).not.toContain(connMan3.userContext.deviceId());
|
|
951
969
|
expect(filteredIds).not.toContain(connMan4.userContext.deviceId());
|
|
952
|
-
expect(filteredIds.sort()).toEqual([
|
|
953
|
-
connMan5.userContext.deviceId(),
|
|
954
|
-
]);
|
|
970
|
+
expect(filteredIds.sort()).toEqual([connMan5.userContext.deviceId()]);
|
|
955
971
|
await Promise.all([
|
|
956
972
|
connMan1.dispose(),
|
|
957
973
|
connMan2.dispose(),
|
|
@@ -988,12 +1004,12 @@ describe("connection-manager", () => {
|
|
|
988
1004
|
spokes.push(spoke);
|
|
989
1005
|
await connectDeviceManagers(hub, spoke);
|
|
990
1006
|
}
|
|
991
|
-
await Promise.all([hub, ...spokes].map(cm => cm.refreshAllNetworkInfo()));
|
|
1007
|
+
await Promise.all([hub, ...spokes].map((cm) => cm.refreshAllNetworkInfo()));
|
|
992
1008
|
// From hub's perspective, each spoke should report the hub and other spokes
|
|
993
1009
|
const firstSpokeConnection = hub.getDeviceConnection(spokes[0].userContext.deviceId());
|
|
994
1010
|
const indirectIds = hub.getConnectionIndirectRemoteDeviceIds(firstSpokeConnection);
|
|
995
1011
|
expect(indirectIds.sort()).toEqual([]);
|
|
996
|
-
await Promise.all([hub, ...spokes].map(cm => cm.dispose()));
|
|
1012
|
+
await Promise.all([hub, ...spokes].map((cm) => cm.dispose()));
|
|
997
1013
|
});
|
|
998
1014
|
it("should return empty array when all indirect devices are excluded", async () => {
|
|
999
1015
|
const userId = (0, peers_sdk_1.newid)();
|
|
@@ -1025,7 +1041,7 @@ describe("connection-manager", () => {
|
|
|
1025
1041
|
await connectDeviceManagers(chain[i - 1], connMan);
|
|
1026
1042
|
}
|
|
1027
1043
|
}
|
|
1028
|
-
await Promise.all(chain.map(cm => cm.refreshAllNetworkInfo()));
|
|
1044
|
+
await Promise.all(chain.map((cm) => cm.refreshAllNetworkInfo()));
|
|
1029
1045
|
// From chain[0]'s perspective, check chain[1]'s indirect connections
|
|
1030
1046
|
// chain[1] is connected to chain[0] and chain[2] so chain[0] can see chain[2] indirectly
|
|
1031
1047
|
const connection = chain[0].getDeviceConnection(chain[1].userContext.deviceId());
|
|
@@ -1035,15 +1051,17 @@ describe("connection-manager", () => {
|
|
|
1035
1051
|
// chain[0].userContext.deviceId(),
|
|
1036
1052
|
chain[2].userContext.deviceId(),
|
|
1037
1053
|
].sort());
|
|
1038
|
-
await Promise.all(chain.map(cm => cm.dispose()));
|
|
1054
|
+
await Promise.all(chain.map((cm) => cm.dispose()));
|
|
1039
1055
|
});
|
|
1040
1056
|
it("should handle connection with no peer group devices", async () => {
|
|
1041
1057
|
const connMan1 = await connectionManagerFactory();
|
|
1042
1058
|
const connMan2 = await connectionManagerFactory();
|
|
1043
1059
|
await connectDeviceManagers(connMan1, connMan2);
|
|
1044
1060
|
// Clear peer group devices to test edge case
|
|
1045
|
-
|
|
1046
|
-
|
|
1061
|
+
// biome-ignore lint/complexity/useLiteralKeys: private `syncGroups` — bracket access only from outside this module
|
|
1062
|
+
connMan1["syncGroups"] = {};
|
|
1063
|
+
// biome-ignore lint/complexity/useLiteralKeys: private `connectionStates` — bracket access only from outside this module
|
|
1064
|
+
const connection = Array.from(connMan1["connectionStates"].keys())[0];
|
|
1047
1065
|
const indirectIds = connMan1.getConnectionIndirectRemoteDeviceIds(connection);
|
|
1048
1066
|
expect(indirectIds).toEqual([]);
|
|
1049
1067
|
await Promise.all([connMan1.dispose(), connMan2.dispose()]);
|
|
@@ -1093,7 +1111,7 @@ describe("connection-manager", () => {
|
|
|
1093
1111
|
const connMan2 = await connectionManagerFactory(userId, (0, peers_sdk_1.newid)());
|
|
1094
1112
|
await connectDeviceManagers(connMan1, connMan2);
|
|
1095
1113
|
const path = connMan1.getPathToDevice(connMan2.userContext.deviceId());
|
|
1096
|
-
expect(path.pathType).toBe(
|
|
1114
|
+
expect(path.pathType).toBe("direct");
|
|
1097
1115
|
expect(path.throughDeviceIds).toEqual([connMan1.userContext.deviceId()]);
|
|
1098
1116
|
await Promise.all([connMan1.dispose(), connMan2.dispose()]);
|
|
1099
1117
|
});
|
|
@@ -1101,7 +1119,7 @@ describe("connection-manager", () => {
|
|
|
1101
1119
|
const connMan = await connectionManagerFactory();
|
|
1102
1120
|
const nonExistentDeviceId = (0, peers_sdk_1.newid)();
|
|
1103
1121
|
const path = connMan.getPathToDevice(nonExistentDeviceId);
|
|
1104
|
-
expect(path.pathType).toBe(
|
|
1122
|
+
expect(path.pathType).toBe("unknown");
|
|
1105
1123
|
expect(path.throughDeviceIds).toEqual([]);
|
|
1106
1124
|
await connMan.dispose();
|
|
1107
1125
|
});
|
|
@@ -1119,7 +1137,7 @@ describe("connection-manager", () => {
|
|
|
1119
1137
|
connMan3.refreshAllNetworkInfo(),
|
|
1120
1138
|
]);
|
|
1121
1139
|
const path = connMan1.getPathToDevice(connMan3.userContext.deviceId());
|
|
1122
|
-
expect(path.pathType).toBe(
|
|
1140
|
+
expect(path.pathType).toBe("indirect");
|
|
1123
1141
|
expect(path.throughDeviceIds).toContain(connMan2.userContext.deviceId());
|
|
1124
1142
|
await Promise.all([connMan1.dispose(), connMan2.dispose(), connMan3.dispose()]);
|
|
1125
1143
|
});
|
|
@@ -1132,7 +1150,7 @@ describe("connection-manager", () => {
|
|
|
1132
1150
|
await connectDeviceManagers(connMan2, connMan3);
|
|
1133
1151
|
// Don't refresh network info - connMan1 won't know about connMan3
|
|
1134
1152
|
const path = connMan1.getPathToDevice(connMan3.userContext.deviceId());
|
|
1135
|
-
expect(path.pathType).toBe(
|
|
1153
|
+
expect(path.pathType).toBe("unknown");
|
|
1136
1154
|
expect(path.throughDeviceIds).toEqual([]);
|
|
1137
1155
|
await Promise.all([connMan1.dispose(), connMan2.dispose(), connMan3.dispose()]);
|
|
1138
1156
|
});
|
|
@@ -1149,7 +1167,7 @@ describe("connection-manager", () => {
|
|
|
1149
1167
|
connMan3.refreshAllNetworkInfo(),
|
|
1150
1168
|
]);
|
|
1151
1169
|
const path = connMan1.getPathToDevice(connMan3.userContext.deviceId());
|
|
1152
|
-
expect(path.pathType).not.toBe(
|
|
1170
|
+
expect(path.pathType).not.toBe("unknown");
|
|
1153
1171
|
expect(path.throughDeviceIds.length).toBeGreaterThan(0);
|
|
1154
1172
|
await Promise.all([connMan1.dispose(), connMan2.dispose(), connMan3.dispose()]);
|
|
1155
1173
|
});
|
|
@@ -1171,7 +1189,7 @@ describe("connection-manager", () => {
|
|
|
1171
1189
|
]);
|
|
1172
1190
|
const path = connMan1.getPathToDevice(connMan3.userContext.deviceId());
|
|
1173
1191
|
// Should return direct path since it checks allConnections first
|
|
1174
|
-
expect(path.pathType).toBe(
|
|
1192
|
+
expect(path.pathType).toBe("direct");
|
|
1175
1193
|
expect(path.throughDeviceIds).toEqual([connMan1.userContext.deviceId()]);
|
|
1176
1194
|
await Promise.all([connMan1.dispose(), connMan2.dispose(), connMan3.dispose()]);
|
|
1177
1195
|
});
|
|
@@ -1198,7 +1216,7 @@ describe("connection-manager", () => {
|
|
|
1198
1216
|
connMan4.refreshAllNetworkInfo(),
|
|
1199
1217
|
]);
|
|
1200
1218
|
const path = connMan1.getPathToDevice(connMan4.userContext.deviceId());
|
|
1201
|
-
expect(path.pathType).toBe(
|
|
1219
|
+
expect(path.pathType).toBe("indirect");
|
|
1202
1220
|
expect(path.throughDeviceIds.length).toBeGreaterThan(0);
|
|
1203
1221
|
// Should include either connMan2 or connMan3 as intermediate device
|
|
1204
1222
|
const hasValidPath = path.throughDeviceIds.includes(connMan2.userContext.deviceId()) ||
|
|
@@ -1222,20 +1240,20 @@ describe("connection-manager", () => {
|
|
|
1222
1240
|
await connectDeviceManagers(chain[i - 1], connMan);
|
|
1223
1241
|
}
|
|
1224
1242
|
}
|
|
1225
|
-
await Promise.all(chain.map(cm => cm.refreshAllNetworkInfo()));
|
|
1243
|
+
await Promise.all(chain.map((cm) => cm.refreshAllNetworkInfo()));
|
|
1226
1244
|
// Check path from chain[0] to chain[2] (2 hops away)
|
|
1227
1245
|
const path = chain[0].getPathToDevice(chain[2].userContext.deviceId());
|
|
1228
|
-
expect(path.pathType).toBe(
|
|
1246
|
+
expect(path.pathType).toBe("indirect");
|
|
1229
1247
|
expect(path.throughDeviceIds.length).toBeGreaterThan(0);
|
|
1230
1248
|
// Should include chain[1] as intermediate device
|
|
1231
1249
|
expect(path.throughDeviceIds).toContain(chain[1].userContext.deviceId());
|
|
1232
|
-
await Promise.all(chain.map(cm => cm.dispose()));
|
|
1250
|
+
await Promise.all(chain.map((cm) => cm.dispose()));
|
|
1233
1251
|
});
|
|
1234
1252
|
it("should return 'unknown' when device has no connections", async () => {
|
|
1235
1253
|
const connMan = await connectionManagerFactory();
|
|
1236
1254
|
const targetDeviceId = (0, peers_sdk_1.newid)();
|
|
1237
1255
|
const path = connMan.getPathToDevice(targetDeviceId);
|
|
1238
|
-
expect(path.pathType).toBe(
|
|
1256
|
+
expect(path.pathType).toBe("unknown");
|
|
1239
1257
|
expect(path.throughDeviceIds).toEqual([]);
|
|
1240
1258
|
await connMan.dispose();
|
|
1241
1259
|
});
|
|
@@ -1244,7 +1262,7 @@ describe("connection-manager", () => {
|
|
|
1244
1262
|
const ownDeviceId = connMan.userContext.deviceId();
|
|
1245
1263
|
const path = connMan.getPathToDevice(ownDeviceId);
|
|
1246
1264
|
// Querying for own device should return unknown (not in allConnections)
|
|
1247
|
-
expect(path.pathType).toBe(
|
|
1265
|
+
expect(path.pathType).toBe("unknown");
|
|
1248
1266
|
await connMan.dispose();
|
|
1249
1267
|
});
|
|
1250
1268
|
it("should return first non-unknown path from sync devices", async () => {
|
|
@@ -1261,7 +1279,7 @@ describe("connection-manager", () => {
|
|
|
1261
1279
|
]);
|
|
1262
1280
|
const path = connMan1.getPathToDevice(connMan3.userContext.deviceId());
|
|
1263
1281
|
// Should find path through syncDevice
|
|
1264
|
-
expect(path.pathType).not.toBe(
|
|
1282
|
+
expect(path.pathType).not.toBe("unknown");
|
|
1265
1283
|
expect(path.throughDeviceIds.length).toBeGreaterThan(0);
|
|
1266
1284
|
await Promise.all([connMan1.dispose(), connMan2.dispose(), connMan3.dispose()]);
|
|
1267
1285
|
});
|