import * as SecureStore from "expo-secure-store"; import { create } from "zustand"; const AUTH_TOKEN_KEY = "auth_token"; interface SessionState { token: string | null; /** * False until SecureStore returns the persisted token (or confirms absence). * The API client should treat requests as unauthenticated until this flips — * see `useSessionStore.subscribe` in App.tsx for the bootstrap. */ hydrated: boolean; setToken: (token: string) => Promise; clearToken: () => Promise; } export const useSessionStore = create((set) => ({ token: null, hydrated: false, setToken: async (token: string) => { await SecureStore.setItemAsync(AUTH_TOKEN_KEY, token); set({ token }); }, clearToken: async () => { await SecureStore.deleteItemAsync(AUTH_TOKEN_KEY); set({ token: null }); }, })); /** * Bootstrap the session by reading SecureStore once. Call from App.tsx before * mounting the navigator. Resolves after the store reflects whatever was in * persistent storage. */ export async function hydrateSession(): Promise { try { const token = await SecureStore.getItemAsync(AUTH_TOKEN_KEY); useSessionStore.setState({ token: token ?? null, hydrated: true }); } catch { // SecureStore failures are non-fatal — proceed unauthenticated. useSessionStore.setState({ token: null, hydrated: true }); } }