Files
clean-architecture-frontend…/src/presentation/providers/session-provider.tsx
T

56 lines
1.4 KiB
TypeScript

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<SessionContextValue | null>(null);
export function SessionProvider({
children,
}: Readonly<{ children: ReactNode }>) {
const session = useApplicationSession();
const sessionState = useSyncExternalStore(
session.subscribe,
session.getSnapshot,
session.getSnapshot,
);
const value = useMemo<SessionContextValue>(
() =>
Object.freeze({
sessionState,
beginSignIn: session.beginSignIn,
signOut: session.signOut,
recover: session.recover,
}),
[session, sessionState],
);
return (
<SessionContext.Provider value={value}>{children}</SessionContext.Provider>
);
}
export function useSession(): SessionContextValue {
const session = useContext(SessionContext);
if (!session) {
throw new Error("SessionProvider is required");
}
return session;
}