Skip to main content

State Management

Resibibo uses a layered state management approach.

Overview

LayerTechnologyPurpose
UI StateZustandAuth tokens, chat messages, sync state
Local DataReact Query + react-query-kitLocal database reads/writes with caching
Server DataReact QueryAPI calls for receipts, agent, categories
Key-ValueMMKVSettings, 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.

Data Flow