/**
* meta-sync.mjs — Check MetadataBase state and optionally join a remote key
*
* Usage:
* bare tests/meta-sync.mjs # show current state
* bare tests/meta-sync.mjs <64-char-hex-key> # join remote MetadataBase
*/
import Pipe from 'bare-pipe'
import FramedStream from 'framed-stream'
import b4a from 'b4a'
let rpcId = 0
const pipe = new Pipe('/tmp/keet-daemon.sock')
const framed = new FramedStream(pipe)
const pending = new Map()
framed.on('data', buf => {
const msg = JSON.parse(b4a.toString(buf))
const cb = pending.get(msg.id)
if (cb) { pending.delete(msg.id); cb(msg) }
})
function call (method, params = {}) {
return new Promise((resolve, reject) => {
const id = ++rpcId
const timeout = setTimeout(() => { pending.delete(id); reject(new Error('timeout: ' + method)) }, 15000)
pending.set(id, msg => {
clearTimeout(timeout)
if (msg.ok !== undefined && msg.data !== undefined) msg.result = msg.data
if (msg.error) reject(new Error(msg.error.message || String(msg.error)))
else resolve(msg.result)
})
framed.write(b4a.from(JSON.stringify({ jsonrpc: '2.0', id, method, params })))
})
}
// Show current state
console.log('=== MetadataBase State ===\n')
try {
const keyInfo = await call('meta.key')
console.log('Key:', keyInfo.key)
console.log('Local key:', keyInfo.localKey)
console.log('Writable:', keyInfo.writable)
} catch (err) {
console.log('meta.key error:', err.message)
}
// Check how many rooms have metadata
try {
const rooms = await call('rooms')
let withMeta = 0
let withoutMeta = 0
for (const r of rooms) {
const rid = r.roomId || r.id
try {
const meta = await call('meta.get', { roomId: rid })
if (meta && meta.category) withMeta++
else withoutMeta++
} catch {
withoutMeta++
}
}
console.log(`\nRooms: ${rooms.length} total, ${withMeta} with metadata, ${withoutMeta} without`)
} catch (err) {
console.log('rooms error:', err.message)
}
// Join if key provided
const joinKey = Bare.argv[Bare.argv.length - 1]
if (joinKey && joinKey.length === 64 && /^[0-9a-f]+$/.test(joinKey)) {
console.log(`\n=== Joining MetadataBase: ${joinKey.slice(0, 16)}... ===\n`)
try {
const result = await call('meta.join', { key: joinKey })
console.log('Join result:', JSON.stringify(result, null, 2))
// Verify state after join
console.log('\n=== Post-Join State ===\n')
const keyInfo = await call('meta.key')
console.log('Key:', keyInfo.key)
console.log('Writable:', keyInfo.writable)
// Wait a bit for replication, then check metadata
console.log('\nWaiting 5s for replication...')
await new Promise(r => setTimeout(r, 5000))
const rooms = await call('rooms')
let withMeta = 0
for (const r of rooms) {
const rid = r.roomId || r.id
try {
const meta = await call('meta.get', { roomId: rid })
if (meta && meta.category) {
withMeta++
console.log(` ${(r.title || '?').padEnd(20)} cat=${meta.category}`)
}
} catch {}
}
console.log(`\n${withMeta} rooms now have metadata`)
} catch (err) {
console.log('Join error:', err.message)
}
}
pipe.destroy()
setTimeout(() => Bare.exit(0), 500)