State Management
Resibibo uses a layered state management approach.
Overview
| Layer | Technology | Purpose |
|---|---|---|
| UI State | Zustand | Auth tokens, chat messages, sync state |
| Local Data | React Query + react-query-kit | Local database reads/writes with caching |
| Server Data | React Query | API calls for receipts, agent, categories |
| Key-Value | MMKV | Settings, tokens, preferences |
Zustand Stores
Auth Store (lib/auth/)
Manages authentication state:
- Current user object
- Access and refresh tokens
- Login/logout actions
- Token refresh with mutex lock
Chat Store (lib/chat-store.ts)
Manages AI chat state:
- Message history (persisted per session)
- Typing indicator state
- Quick action prompts
Sync Store (lib/sync/sync-store.ts)
Manages sync state:
- Sync enabled/disabled
- Last sync timestamp
- Sync in-progress flag
- Pending changes count
React Query + react-query-kit
Local database operations are wrapped with react-query-kit for automatic caching and invalidation.
Queries (reads)
// src/db/hooks/use-transactions.ts
export const useTransactions = createQuery({
queryKey: ["transactions"],
fetcher: (variables) => getTransactions(db, variables),
});
Mutations (writes)
export const useInsertTransaction = createMutation({
mutationFn: (data) => insertTransaction(db, data),
onSuccess: () => {
// Invalidate related queries
queryClient.invalidateQueries({ queryKey: ["transactions"] });
queryClient.invalidateQueries({ queryKey: ["spending-summary"] });
queryClient.invalidateQueries({ queryKey: ["budgets"] });
},
});
The queryClient is imported from @/api/common/api-provider.