1import type { PairedDevice } from "./sync-types";23export const MESH_WAITER_RETRY_DELAY_MS = 2_000;4export const MESH_WAITER_MAX_RETRY_DELAY_MS = 30_000;56export function isRouteCapableMeshPeer(device: PairedDevice): boolean {7 8 9 const trusted =10 device.trustSource === "direct" || device.trustSource === "vouched";11 return (12 trusted &&13 (device.deviceType === "extension" ||14 device.deviceType === "android" ||15 device.deviceType === "ios") &&16 typeof device.longTermPublicKeyHex === "string" &&17 /^[0-9a-f]{64}$/.test(device.longTermPublicKeyHex) &&18 typeof device.rendezvousSecretHex === "string" &&19 /^[0-9a-f]{64}$/.test(device.rendezvousSecretHex)20 );21}222324export function weDialMeshPeer(25 ourLongTermPublicKeyHex: string,26 peerLongTermPublicKeyHex: string,27): boolean {28 if (29 !/^[0-9a-f]{64}$/.test(ourLongTermPublicKeyHex) ||30 !/^[0-9a-f]{64}$/.test(peerLongTermPublicKeyHex) ||31 ourLongTermPublicKeyHex === peerLongTermPublicKeyHex32 ) {33 return false;34 }35 return ourLongTermPublicKeyHex < peerLongTermPublicKeyHex;36}3738export function selectDialTargets(39 devices: PairedDevice[],40 ourLongTermPublicKeyHex: string,41): PairedDevice[] {42 return devices.filter(43 (device) =>44 isRouteCapableMeshPeer(device) &&45 weDialMeshPeer(46 ourLongTermPublicKeyHex,47 device.longTermPublicKeyHex!,48 ),49 );50}5152export function nextMeshWaiterRetryDelay(53 current: number,54 succeeded: boolean,55): number {56 return succeeded57 ? MESH_WAITER_RETRY_DELAY_MS58 : Math.min(current * 2, MESH_WAITER_MAX_RETRY_DELAY_MS);59}