import { PowerSyncContext } from '@powersync/react' import { useEffect, useState } from 'react' import { createRoot } from 'react-dom/client' import { App, type Room, type Session } from './App.tsx' import { Landing } from './Landing.tsx' import { navigate, signInHref } from './nav.ts' import { createConnector, openDatabase } from './powersync.ts' const appBase = document.documentElement.dataset.appBase ?? '' const assetBase = document.documentElement.dataset.assetBase ?? `${appBase}/_assets` const db = openDatabase(assetBase) function routeFromLocation() { let path = location.pathname if (appBase && path.startsWith(appBase)) path = path.slice(appBase.length) const m = /^\/r\/([a-z0-9]{4,24})\/?$/i.exec(path) return m ? { room: m[1]!.toLowerCase() } : { room: null } } async function getJson(url: string, init?: RequestInit): Promise<{ ok: boolean; status: number; body: T }> { const res = await fetch(url, { credentials: 'same-origin', ...init }) return { ok: res.ok, status: res.status, body: (await res.json().catch(() => ({}))) as T } } type RoomState = | { kind: 'loading' } | { kind: 'missing'; message: string } | { kind: 'ready'; room: Room; session: Session } function RoomRoute({ slug }: { slug: string }) { const [state, setState] = useState({ kind: 'loading' }) useEffect(() => { let cancelled = false void (async () => { const r = await getJson<{ room?: Room; error?: string }>(`${appBase}/api/rooms/${slug}`) if (!r.ok || !r.body.room) { if (!cancelled) setState({ kind: 'missing', message: r.body.error ?? 'That room does not exist.' }) return } const room = r.body.room const s = await getJson(`${appBase}/api/session?world=${room.worldId}`) if (cancelled) return const session = s.ok ? s.body : { signedIn: false, worldId: room.worldId, powersyncUrl: 'https://powersync.invalid' } await db.disconnect() void db.connect(createConnector(appBase), { params: { world_id: room.worldId } }) ;(window as unknown as { __wb: unknown }).__wb = { db, session, room } setState({ kind: 'ready', room, session }) })() return () => { cancelled = true } }, [slug]) if (state.kind === 'loading') { return (
) } if (state.kind === 'missing') { return (

Room not found

{state.message}

Sign in to build

) } return } function Root() { const [route, setRoute] = useState(routeFromLocation) useEffect(() => { const on = () => setRoute(routeFromLocation()) addEventListener('popstate', on) return () => removeEventListener('popstate', on) }, []) useEffect(() => { if (!route.room) void db.disconnect() }, [route.room]) return route.room ? : } createRoot(document.getElementById('root')!).render( , )