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

50 lines
1.4 KiB
React

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 (
<SessionContext.Provider value={value}>{children}</SessionContext.Provider>
);
}
export function useSession() {
const session = useContext(SessionContext);
if (!session) {
throw new Error("SessionProvider is required");
}
return session;
}