localStorage as the primary data store. All reads and writes go through src/app/services/storage.ts, which provides typed accessors, dispatches change events, and handles cloud sync for authenticated users.
localStorage keys
Every key is prefixed withsmartmove- to avoid collisions.
| Constant | Key | Stores |
|---|---|---|
RECENT_STOPS | smartmove-recent-stops | Recently viewed stops |
RECENT_CONNECTIONS | smartmove-recent-connections | Recent origin–destination pairs |
QUICK_ACCESS | smartmove-quick-access | Pinned quick access items |
ACTIVE_ROUTES | smartmove-active-routes | Currently followed routes |
DEPARTURE_STATIONS | smartmove-departure-stations | Saved departure board stations |
COMMUTER_ROUTES | smartmove-commuter-routes | Saved commuter mode routes |
LIKED_ROUTES | smartmove-liked-routes | Bookmarked routes |
THEME_MODE | smartmove-theme | Selected theme (light, dark, or system) |
LANGUAGE | smartmove-language | Selected locale code |
NOTIFICATIONS | smartmove-notifications | Notification preference |
PRIVACY_LOCATION | smartmove-privacy-location | Location privacy setting |
PRIVACY_ANALYTICS | smartmove-privacy-analytics | Analytics privacy setting |
Types
Generic helpers
storage.ts exposes two generic read/write helpers used throughout the app:
saveToStorage calls syncKeyToCloud after every write. syncKeyToCloud checks for an active Supabase session and silently no-ops if the user is not authenticated.
Window events
Every meaningful write dispatches a custom window event so components can reactively update without a shared store:| Event | Fired when |
|---|---|
recent-stops-changed | Recent stops list is updated |
recent-connections-changed | Recent connections list is updated |
liked-routes-changed | A route is bookmarked or removed |
active-routes-changed | An active route is added or cleared |
commuter-routes-changed | Commuter routes are saved |
quick-access-changed | Quick access items are updated |
departure-stations-changed | Departure stations are updated |
theme-changed | Theme preference is changed |
language-changed | Language preference is changed |
Cloud sync
Two functions handle full bidirectional sync:syncKeyToCloud) runs automatically after every saveToStorage call when the user is authenticated. It maps each storage key to the corresponding Supabase table:
| Key | Supabase table |
|---|---|
THEME_MODE, LANGUAGE, NOTIFICATIONS, PRIVACY_* | user_preferences |
RECENT_STOPS | user_stops |
RECENT_CONNECTIONS | user_connections |
QUICK_ACCESS | quick_access |
COMMUTER_ROUTES | commuter_routes |
LIKED_ROUTES | liked_routes |
ACTIVE_ROUTES | active_routes |
DEPARTURE_STATIONS | departure_stations |
Sync is fire-and-forget. It never blocks the UI. If a sync fails, the data remains intact in localStorage and will sync again on the next write or login.
Itinerary storage
Active route itineraries are stored separately to keep theACTIVE_ROUTES list lean. Each itinerary is keyed by route ID:
smartmove-followed-itinerary and smartmove-route-itin-{routeId} respectively.
Database schema
Supabase table definitions and column types.
Row level security
How RLS policies isolate user data.