/** * Full-mesh topology — every peer connects to every other peer, up * to `maxPeers`. When capacity is reached, the lowest-scoring * existing peer is evicted to make room for the new arrival. */ import type { PeerInfo } from "../../types/peer.types.js"; import { type AdmitDecision, pickLowestScore, type TopologySelectOptions, type TopologyStrategy, } from "./topology-strategy.js"; export class FullMeshStrategy implements TopologyStrategy { public readonly name = "full-mesh" as const; public selectConnections( currentPeers: readonly PeerInfo[], newPeer: PeerInfo, options: TopologySelectOptions ): readonly PeerInfo[] { if (newPeer.id === options.selfPeerId) return []; if (currentPeers.length >= options.maxPeers) return []; return [newPeer]; } public admitOrEvict( currentPeers: readonly PeerInfo[], newPeer: PeerInfo, options: TopologySelectOptions ): AdmitDecision { if (currentPeers.some((p) => p.id === newPeer.id)) { return { admit: false }; } if (currentPeers.length < options.maxPeers) { return { admit: true }; } const newScore = options.metricsFor?.(newPeer.id)?.score ?? 1; const evictCandidate = pickLowestScore( currentPeers, options.metricsFor ); if (evictCandidate === undefined) return { admit: false }; const evictScore = options.metricsFor?.(evictCandidate.id)?.score ?? 0.5; if (newScore <= evictScore) return { admit: false }; return { admit: true, evict: evictCandidate }; } }