const test = require("tape"); const Hyperswarm = require("hyperswarm"); const sodium = require("sodium-universal"); const b4a = require("b4a"); const { default: DHTCache } = require("./"); const crypto = require("crypto"); const topicName = crypto.randomBytes(10); const topic = b4a.allocUnsafe(32); const item1 = b4a.allocUnsafe(32); const item2 = b4a.allocUnsafe(32); sodium.crypto_generichash(item1, b4a.from("item1")); sodium.crypto_generichash(item2, b4a.from("item2")); test("Basic presence test / data propagation", (t) => { t.plan(10); const peer1 = createPeer(); const peer2 = createPeer(); Promise.all([peer1, peer2]).then((peers) => { const peer1 = peers.shift(); const peer2 = peers.shift(); const p1 = new DHTCache(peer1); const p2 = new DHTCache(peer2); p1.addItem(item1.toString("hex")); p2.addItem(item2.toString("hex")); t.ok(p1.id, "Generated id 1"); t.ok(p2.id, "Generated id 2"); p1.on("online", handleOnline); p2.on("online", handleOnline); p1.on("peer-remove", handleDisconnect); let hasFinished = false; function handleOnline(list) { if (list.size === 2) { const peerData1 = [...p1.cache]; const peerData2 = [...p2.cache]; const hasP1 = peerData1 && Object.keys(peerData1).length; const hasP2 = peerData2 && Object.keys(peerData2).length; if (!hasP1 || !hasP2) { return; } p1.removeListener("online", handleOnline); p2.removeListener("online", handleOnline); t.pass("Seeing everyone online"); let p1Resolve; let p2Resolve; let p1Promise = new Promise((resolve) => { p1Resolve = resolve; }); let p2Promise = new Promise((resolve) => { p2Resolve = resolve; }); p1.on("item-added", () => { t.equals(true, p1.allCache.includes(peerData2[0])); p1Resolve(); }); p2.on("item-added", () => { t.equals(true, p2.allCache.includes(peerData1[0])); p2Resolve(); }); Promise.all([p1Promise, p2Promise]).then(() => { t.equals(true, p1.peerHasItem(peer1.keyPair.publicKey, item1)); t.equals(true, p2.peerHasItem(peer1.keyPair.publicKey, item1)); t.equals(true, p1.peerHasItem(peer2.keyPair.publicKey, item2)); t.equals(true, p2.peerHasItem(peer2.keyPair.publicKey, item2)); hasFinished = true; peer2._allConnections.get(peer1.keyPair.publicKey).end(); }); } } function handleDisconnect() { if (!hasFinished) return t.error("Disconnected before finished"); t.pass("Peer removed on disconnect"); t.end(); } t.teardown(() => { [peer1, peer2].forEach((item) => item.destroy()); }); }); }); async function createPeer() { const swarm = new Hyperswarm(); await swarm.dht.ready(); await swarm.listen(); swarm.join(topic); return swarm; }