@gj-kit/expo-auth recipes
Each code block reuses a public-contract example already type-checked in the package README.
1. Assemble one application session
Section titled “1. Assemble one application session”Choose storage and a refresh callback once; the package coordinates callers around that application-owned boundary.
Outcome: One app-owned session that persists login state and coordinates concurrent refreshes.
Application-owned boundary: Choose the storage adapter once and connect only your refresh-endpoint callback.
import { createAuthSession, type RefreshRequest } from '@gj-kit/expo-auth';import { createTokenStorage, createWebLocksRefreshLock } from '@gj-kit/expo-auth/storage';
declare const refresh: RefreshRequest; // Your API client classifies rotated, invalid, or transient.
export const session = createAuthSession({ storage: createTokenStorage({ keyPrefix: 'myapp.auth' }), lock: createWebLocksRefreshLock({ name: 'myapp.auth' }), refresh,});2. Handle every refresh outcome explicitly
Section titled “2. Handle every refresh outcome explicitly”Use the matcher so an omitted transient or rotated branch is a compile error.
The five endings of refresh() are consumed by key, so the omission that turns a network blip into a false logout is rejected at compile time; tokens is reachable only after narrowing to refreshed or adopted, and a refresh callback that throws arrives here as transient with the thrown value in cause.
import { matchRefreshOutcome, type RefreshOutcome } from '@gj-kit/expo-auth';
declare const outcome: RefreshOutcome; // the app owns this — it is `await session.refresh()`declare const goToSignIn: () => null; // the app owns navigationdeclare const report: (cause: unknown) => void; // the app owns telemetry
export const accessToken = matchRefreshOutcome<string | null>(outcome, { refreshed: ({ tokens }) => tokens.accessToken, // `tokens` exists here and on `adopted` only adopted: ({ tokens }) => tokens.accessToken, 'signed-out': () => goToSignIn(), invalid: () => goToSignIn(), // a definitive server rejection transient: ({ cause }) => { report(cause); // stored tokens are left untouched — a 5xx is not a sign-out return null; },});// Delete the `transient` line above and tsc refuses the call:// error TS2345: ... Property 'transient' is missing in type ... but required in type ...Use the complete API reference for every export and import path.