// Probe: do TWO MetadataBase instances with the SAME deterministic
// bootstrap key (derived from a roomId) actually share state via
// Hyperswarm replication?
//
// Spins up two independent Corestores in /tmp, opens a MetadataBase
// in each with roomId set, has peer A write a field, polls peer B
// until they see it.
//
// Run: bare test/probe-shared-metabase.js
//
// PASS criteria: peer B's view contains the field A wrote, within 30s.
// FAIL means the deterministic-bootstrap mechanism alone isn't enough
// and we need explicit writer-add ops.
import fs from 'bare-fs'
import path from 'bare-path'
import os from 'bare-os'
import { MetadataBase, deriveRoomBootstrapKey } from '../lib/metadata-base.js'
const ROOM = 'probe-room-' + Math.random().toString(36).slice(2, 10)
const DEADLINE_MS = 30000
const dirA = path.join(os.tmpdir(), 'probe-meta-A-' + Date.now())
const dirB = path.join(os.tmpdir(), 'probe-meta-B-' + Date.now())
fs.mkdirSync(dirA, { recursive: true })
fs.mkdirSync(dirB, { recursive: true })
console.log('roomId:', ROOM)
console.log('bootstrap:', deriveRoomBootstrapKey(ROOM).toString('hex'))
console.log('dirA:', dirA)
console.log('dirB:', dirB)
const mbA = new MetadataBase(dirA, { roomId: ROOM })
const mbB = new MetadataBase(dirB, { roomId: ROOM })
let exitCode = 1
try {
console.log('\n[A] opening...')
await mbA.ready()
console.log('[A] base.key:', mbA.base.key.toString('hex').slice(0, 16) + '…')
console.log('[A] base.discoveryKey:', mbA.base.discoveryKey.toString('hex').slice(0, 16) + '…')
console.log('\n[B] opening...')
await mbB.ready()
console.log('[B] base.key:', mbB.base.key.toString('hex').slice(0, 16) + '…')
console.log('[B] base.discoveryKey:', mbB.base.discoveryKey.toString('hex').slice(0, 16) + '…')
const keysMatch = mbA.base.key.equals(mbB.base.key)
console.log('\nkeys match across peers?', keysMatch)
const dkeysMatch = mbA.base.discoveryKey.equals(mbB.base.discoveryKey)
console.log('discovery keys match?', dkeysMatch)
if (!keysMatch || !dkeysMatch) {
console.log('FAIL — peers opened different autobases despite deterministic bootstrap')
process.exit(1)
}
console.log('\n[A] writing room field with id =', ROOM)
await mbA.set(ROOM, { test_field: 'hello from A', ts: Date.now() })
console.log('[A] write OK; A view:', JSON.stringify(await mbA.get(ROOM)))
console.log('\n[B] polling until field appears (deadline ' + (DEADLINE_MS / 1000) + 's)...')
const t0 = Date.now()
while (Date.now() - t0 < DEADLINE_MS) {
const v = await mbB.get(ROOM)
if (v && v.test_field === 'hello from A') {
console.log('[B] saw the write at +' + ((Date.now() - t0) / 1000).toFixed(1) + 's: ' + JSON.stringify(v))
console.log('\nPASS — peers converged on shared state via deterministic bootstrap.')
exitCode = 0
break
}
await new Promise(r => setTimeout(r, 500))
}
if (exitCode !== 0) {
console.log('FAIL — B never saw A\'s write within ' + (DEADLINE_MS / 1000) + 's.')
console.log('[B] final view:', JSON.stringify(await mbB.get(ROOM)))
}
} catch (err) {
console.error('error:', err.message)
console.error(err.stack)
} finally {
try { await mbA._closing || mbA.close?.() } catch {}
try { await mbB._closing || mbB.close?.() } catch {}
fs.rmSync(dirA, { recursive: true, force: true })
fs.rmSync(dirB, { recursive: true, force: true })
process.exit(exitCode)
}