import { createContext, useContext, useMemo, useSyncExternalStore, type ReactNode, } from "react"; import type { ApplicationApi, SessionState, } from "../../application/ports/in/application-api.ts"; import { useApplicationSession } from "./application-provider.tsx"; export type SessionContextValue = Readonly<{ sessionState: SessionState; beginSignIn: ApplicationApi["session"]["beginSignIn"]; signOut: ApplicationApi["session"]["signOut"]; recover: ApplicationApi["session"]["recover"]; }>; const SessionContext = createContext(null); export function SessionProvider({ children, }: Readonly<{ children: ReactNode }>) { const session = useApplicationSession(); const sessionState = useSyncExternalStore( session.subscribe, session.getSnapshot, session.getSnapshot, ); const value = useMemo( () => Object.freeze({ sessionState, beginSignIn: session.beginSignIn, signOut: session.signOut, recover: session.recover, }), [session, sessionState], ); return ( {children} ); } export function useSession(): SessionContextValue { const session = useContext(SessionContext); if (!session) { throw new Error("SessionProvider is required"); } return session; }