OverviewFilesCommitsIssuesDocsReleasesPeers

keet-daemon / test / xmachine-read.js

67 lines · javascript ref:
// 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)
}