@entityauth/react
v0.0.22
Published
React provider and hooks for Entity Auth client SDK.
Maintainers
Readme
@entityauth/react
React provider and hooks for Entity Auth client SDK. Framework-agnostic (no Next.js dependency).
Install
pnpm add @entityauth/react @entityauth/auth-clientUsage
import {
EntityAuthProvider,
createEntityAuthFacade,
useEntityAuth,
useMe,
} from "@entityauth/react";
const facade = createEntityAuthFacade({
baseURL: process.env.NEXT_PUBLIC_ENTITY_AUTH_URL,
initialSnapshot: { isLoadingUser: true },
});
export function App({ children }: { children: React.ReactNode }) {
return (
<EntityAuthProvider facade={facade}>{children}</EntityAuthProvider>
);
}
function Example() {
const { isAuthenticated, login, logout, loading } = useEntityAuth();
const { me } = useMe();
return (
<div>
<div>Authenticated: {String(isAuthenticated)}</div>
{loading ? "Loading…" : <pre>{JSON.stringify(me, null, 2)}</pre>}
<button
onClick={() =>
login({ email: "[email protected]", password: "secret" })
}
>
Login
</button>
<button onClick={() => logout()}>Logout</button>
</div>
);
}API
createEntityAuthFacade(options)→ lazily-configured singleton facade that coordinates tokens, localStorage, andEntityAuthClientEntityAuthProvider→ wrap your React tree; requires a facade instance and (optionally) pre-hydrated snapshotuseEntityAuth()→{ facade, ea, snapshot, accessToken, refreshToken, loading, isAuthenticated, login, logout, applyTokens }useMe<T>()→{ me: T | null, loading: boolean }usePeopleService()→ unified hook for people-related operations (search, invitations, friends)
People Service
The usePeopleService hook provides a unified interface for managing invitations, friend requests, and user search:
import { usePeopleService } from "@entityauth/react";
function PeopleComponent() {
const {
// Search
searchUsers,
searchLoading,
searchError,
// Invitations
listSentInvitations,
listReceivedInvitations,
startInvitation,
acceptInvitation,
declineInvitation,
revokeInvitation,
resendInvitation,
invitationsLoading,
invitationsError,
// Friends
listSentFriendRequests,
listReceivedFriendRequests,
startFriendRequest,
acceptFriendRequest,
declineFriendRequest,
cancelFriendRequest,
friendsLoading,
friendsError,
// Friend connections
listFriendConnections,
removeFriendConnection,
connectionsLoading,
connectionsError,
} = usePeopleService();
// Example: Search users
const handleSearch = async (query: string) => {
try {
const results = await searchUsers(query, 10);
console.log("Found users:", results);
} catch (error) {
console.error("Search failed:", error);
}
};
// Example: Send invitation
const handleInvite = async (orgId: string, userId: string, role: string) => {
try {
const result = await startInvitation(orgId, userId, role);
console.log("Invitation sent:", result);
} catch (error) {
console.error("Invitation failed:", error);
}
};
return (
<div>
{searchLoading && <div>Searching...</div>}
{searchError && <div>Error: {searchError.message}</div>}
{/* Your UI */}
</div>
);
}Types
type PersonSummary = {
id: string;
email: string | null;
username: string | null;
alreadyInvited?: boolean;
alreadyFriends?: boolean;
};
type Invitation = {
id: string;
orgId: string;
inviteeUserId: string;
role: string;
status: string;
expiresAt: number;
createdAt: number;
respondedAt?: number;
createdBy?: string;
};
type FriendRequest = {
id: string;
requesterId: string;
targetUserId: string;
status: string;
createdAt: number;
respondedAt?: number;
};
type FriendConnection = {
id: string;
email: string | null;
username: string | null;
since: number;
createdAt: number;
};
type PeopleError =
| { type: "network"; message: string }
| { type: "auth"; message: string }
| { type: "validation"; message: string }
| { type: "unknown"; message: string };Notes
- Call
facade.ready()once on boot (the provider will do this for you whenautoReadyis left enabled). createEntityAuthFacadeautomatically sets the SDK singleton soSDK.*helpers reuse the same underlying client.- No framework-specific integration; safe for CRA, Vite, Remix, etc.
- All
usePeopleServicemethods require authentication (user must be logged in).
