import { OAuthUserAgent, getSession, deleteStoredSession, listStoredSessions } from '@atcute/oauth-browser-client'; import type { Session } from '@atcute/oauth-browser-client'; import { getHandleFromDid } from './atproto.js'; export interface AuthState { agent: OAuthUserAgent | null; did: string | null; handle: string | null; pds: string | null; loading: boolean; error: string | null; } function createAuth() { let state = $state({ agent: null, did: null, handle: null, pds: null, loading: false, error: null }); return { get agent() { return state.agent; }, get did() { return state.did; }, get handle() { return state.handle; }, get pds() { return state.pds; }, get loading() { return state.loading; }, get error() { return state.error; }, get isLoggedIn() { return state.agent !== null; }, async tryRestoreSession() { state.loading = true; state.error = null; try { const sessions = listStoredSessions(); if (sessions.length > 0) { const did = sessions[0]; const session = await getSession(did, { allowStale: true }); const agent = new OAuthUserAgent(session); state.agent = agent; state.did = session.info.sub; state.pds = session.info.aud; // Resolve handle in the background — don't block session restore getHandleFromDid(session.info.sub).then((h) => { if (h) state.handle = h; }).catch(() => {}); } } catch (_) { state.agent = null; state.did = null; state.handle = null; state.pds = null; } finally { state.loading = false; } }, setFromSession(session: Session) { const agent = new OAuthUserAgent(session); state.agent = agent; state.did = session.info.sub; state.pds = session.info.aud; }, setHandle(handle: string) { state.handle = handle; }, async signOut() { if (state.agent) { try { await state.agent.signOut(); } catch (_) {} } if (state.did) { try { deleteStoredSession(state.did as `did:${string}:${string}`); } catch (_) {} } state.agent = null; state.did = null; state.handle = null; state.pds = null; } }; } export const auth = createAuth();