// Cross-machine StateBase reader. Run on tabertron; joins room R's
// announce topic on the REAL public DHT and reads what stortron's
// dedicated-server daemon wrote via UDS. Proves cross-machine game-state
// replication end-to-end (not in-process testnet).
//
// bare test/xmachine-read.js <roomId> [keyToWatch]
//
// PASS = the reader's view contains state written on the other machine.
import fs from 'bare-fs'
import path from 'bare-path'
import os from 'bare-os'
import crypto from 'hypercore-crypto'
import { StateBase } from '../lib/state-base.js'
const ROOM_ID = Bare.argv[2]
const WATCH = Bare.argv[3] || null
if (!ROOM_ID) { console.error('usage: bare test/xmachine-read.js <roomId> [key]'); Bare.exit(2) }
const roomTag = crypto.hash(Buffer.from(String(ROOM_ID), 'utf-8')) // same derivation as router._getStateBase
const dir = path.join(os.tmpdir(), 'xmachine-read-' + Date.now())
fs.mkdirSync(dir, { recursive: true })
console.log('roomId:', ROOM_ID)
console.log('roomTag:', roomTag.toString('hex').slice(0, 16) + '…')
console.log('announceTopic:', StateBase.announceTopic(roomTag).toString('hex').slice(0, 16) + '…')
const sb = new StateBase(dir, roomTag) // network:true, public DHT
let exitCode = 1
try {
await sb.ready()
console.log('\njoined announce swarm on public DHT — waiting to converge (up to 60s)...')
const t0 = Date.now()
while (Date.now() - t0 < 60000) {
if (sb.hasBootstrap) {
const all = await sb.list('')
const keys = Object.keys(all)
if (keys.length > 0) {
console.log('\nconverged at +' + ((Date.now() - t0) / 1000).toFixed(1) + 's — ' + keys.length + ' keys in view')
if (WATCH) {
const v = await sb.get(WATCH)
console.log('watched key ' + WATCH + ' = ' + JSON.stringify(v))
}
// show the world/sky + any test keys
for (const k of keys) {
if (k.startsWith('state:') || k.startsWith('probe:') || k.startsWith('e2e:')) {
console.log(' ' + k + ' = ' + JSON.stringify(all[k]))
}
}
console.log('\nPASS — read cross-machine state written on the other daemon.')
exitCode = 0
break
}
}
await new Promise(r => setTimeout(r, 1000))
}
if (exitCode !== 0) {
console.log('\nFAIL — never converged. hasBootstrap=' + sb.hasBootstrap)
}
} catch (err) {
console.error('error:', err.message); console.error(err.stack)
} finally {
try { await sb.close() } catch {}
try { fs.rmSync(dir, { recursive: true, force: true }) } catch {}
Bare.exit(exitCode)
}