import { createContext, useContext, useMemo, useSyncExternalStore } from "react"; import { useApplication } from "./application-provider.js"; /** * @typedef {{ * sessionState: import("../../application/ports/in/application-api.js").SessionState, * beginSignIn: import("../../application/ports/in/application-api.js").ApplicationApi["session"]["beginSignIn"], * signOut: import("../../application/ports/in/application-api.js").ApplicationApi["session"]["signOut"], * recover: import("../../application/ports/in/application-api.js").ApplicationApi["session"]["recover"] * }} SessionContextValue */ const SessionContext = createContext( /** @type {SessionContextValue | null} */ (null), ); /** * @param {{ children: React.ReactNode }} props */ export function SessionProvider({ children }) { const { session } = useApplication(); 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() { const session = useContext(SessionContext); if (!session) { throw new Error("SessionProvider is required"); } return session; }