OverviewFilesCommitsIssuesDocsReleasesPeers

godot-keet / tests / query-rooms.mjs

145 lines · javascript ref:
/**
 * query-rooms.mjs — List all rooms and their current metadata
 * Usage: bare tests/query-rooms.mjs
 */

import Pipe from 'bare-pipe'
import FramedStream from 'framed-stream'
import b4a from 'b4a'

const SOCKET = '/tmp/keet-daemon.sock'
let rpcId = 0

function connect () {
  const pipe = new Pipe(SOCKET)
  const framed = new FramedStream(pipe)
  const pending = new Map()

  framed.on('data', (buf) => {
    try {
      const msg = JSON.parse(b4a.toString(buf))
      const cb = pending.get(msg.id)
      if (cb) {
        pending.delete(msg.id)
        if (msg.ok !== undefined && msg.data !== undefined) msg.result = msg.data
        cb(msg)
      }
    } catch {}
  })

  function call (method, params = {}) {
    return new Promise((resolve, reject) => {
      const id = ++rpcId
      const timeout = setTimeout(() => {
        pending.delete(id)
        reject(new Error(`RPC timeout: ${method}`))
      }, 15000)
      pending.set(id, (msg) => {
        clearTimeout(timeout)
        if (msg.error) reject(new Error(msg.error.message || msg.error))
        else resolve(msg.result)
      })
      const payload = JSON.stringify({ jsonrpc: '2.0', id, method, params })
      framed.write(b4a.from(payload))
    })
  }

  function close () { framed.destroy(); pipe.destroy() }
  return { call, close }
}

async function run () {
  const client = connect()

  // Check available meta routes
  let hasList = true
  try {
    await client.call('introspect')
  } catch {}

  const rooms = await client.call('rooms')

  // Try meta.list, fall back to per-room meta.get
  let allMeta = {}
  try {
    allMeta = await client.call('meta.list')
  } catch {
    // meta.list not available, fetch per room
    for (const room of rooms) {
      const id = room.roomId || room.id
      try {
        const meta = await client.call('meta.get', { roomId: id })
        if (meta && Object.keys(meta).length > 0) {
          allMeta[id] = meta
        }
      } catch {}
    }
  }

  console.log(`\n=== ${rooms.length} rooms total, ${Object.keys(allMeta).length} have metadata ===\n`)

  const withMeta = []
  const withoutMeta = []

  for (const room of rooms) {
    const id = room.roomId || room.id
    const title = room.title || '(untitled)'
    const meta = allMeta[id]

    if (meta && Object.keys(meta).filter(k => !k.startsWith('_')).length > 0) {
      withMeta.push({ id, title, meta })
    } else {
      withoutMeta.push({ id, title })
    }
  }

  if (withMeta.length > 0) {
    console.log('--- ROOMS WITH METADATA ---\n')
    for (const { id, title, meta } of withMeta) {
      const clean = {}
      for (const [k, v] of Object.entries(meta)) {
        if (!k.startsWith('_')) clean[k] = v
      }
      console.log(`  "${title}" (${id.slice(0, 16)}...)`)
      console.log(`    ${JSON.stringify(clean)}`)
    }
  }

  if (withoutMeta.length > 0) {
    console.log('\n--- ROOMS WITHOUT METADATA ---\n')
    for (const { id, title } of withoutMeta) {
      console.log(`  "${title}" (${id.slice(0, 16)}...)`)
    }
  }

  // Get room details for ALL rooms
  console.log('\n--- ROOM DETAILS ---\n')
  for (const room of rooms) {
    const id = room.roomId || room.id
    const title = room.title || '(untitled)'
    try {
      const info = await client.call('room', { roomId: id })
      const roomType = info.digest?.settings?.roomType
      const memberCount = info.status?.memberCount || info.digest?.memberCount || '?'
      const connected = info.status?.connectedPeers || '?'
      const isWritable = info.status?.isWritable
      const hasMeta = !!allMeta[id]
      const typeLabel = roomType === 1 ? 'Default' : roomType === 2 ? 'Broadcast' : roomType === 3 ? 'DM' : `type=${roomType}`
      console.log(`  "${title}" [${typeLabel}] members=${memberCount} connected=${connected} writable=${isWritable} meta=${hasMeta}`)
      console.log(`    id: ${id}`)
    } catch (err) {
      console.log(`  "${title}" — error: ${err.message}`)
    }
  }

  console.log('\n=== SUMMARY ===')
  console.log(`  With metadata: ${withMeta.length}`)
  console.log(`  Without metadata: ${withoutMeta.length}`)
  console.log(`  Total rooms: ${rooms.length}`)

  client.close()
  setTimeout(() => Bare.exit(0), 500)
}

run().catch(err => { console.error('FATAL:', err.message); Bare.exit(1) })