// The JS CONTROL for test_daemon_longlived.py.
//
// Same shape as session-daemon: join one topic on the public DHT and report
// `peers=N` on a pulse, so the SAME Python driver and the SAME accounting can
// measure both implementations. The point is not to test hyperswarm — it is to
// find out what the public DHT's own connect-failure rate looks like, so our
// number has something to be compared against.
//
// node js_peer.js --topic <seed> [--seconds N]
//
// The topic is BLAKE2b(seed), exactly as daemon/main.cpp derives it, so a JS
// peer and a C++ daemon on the same seed land on the same topic.
const Hyperswarm = require('hyperswarm')
const sodium = require('sodium-universal')
const b4a = require('b4a')
const argv = process.argv.slice(2)
function arg (name, dflt) {
const i = argv.indexOf(name)
return i === -1 ? dflt : argv[i + 1]
}
const seed = arg('--topic', null)
const seconds = Number(arg('--seconds', '0'))
if (!seed) {
console.error('usage: node js_peer.js --topic <seed> [--seconds N]')
process.exit(1)
}
const topic = b4a.alloc(32)
sodium.crypto_generichash(topic, b4a.from(seed))
const swarm = new Hyperswarm()
let peers = 0
swarm.on('connection', (conn) => {
peers++
pulse()
conn.on('error', () => {})
conn.on('close', () => { peers--; pulse() })
// Say something, so the connection is real rather than merely opened.
conn.write(b4a.from('hello'))
conn.on('data', () => {})
})
function pulse () {
const dht = swarm.dht
const up = dht && dht.bootstrapped ? 'up' : 'connecting'
console.log(`[js] dht=${up} peers=${peers}`)
}
async function main () {
await swarm.dht.ready()
pulse()
swarm.join(topic, { server: true, client: true })
await swarm.flush()
pulse()
const timer = setInterval(pulse, 5000)
if (seconds > 0) {
setTimeout(async () => {
clearInterval(timer)
await swarm.destroy()
process.exit(0)
}, seconds * 1000)
}
}
main().catch((err) => { console.error(err); process.exit(1) })