Add navigator.onLine guard to SWR refresh IIFEs so background
network calls don't fire in offline mode (prevents fake-IDB leakage
in tests via MSW default handlers).
Fix IDB isolation in affected test files by flushing pending macro
tasks then clearing IDB tables in beforeEach, so stale IDB writes
from previous tests' background IIFEs don't bleed into the next test.
Restore loadBudgetItems and refreshPlaces to apply background refresh
results to store state.
Move tags/categories API calls before the main Promise.all in
loadTrip so MSW handlers resolve during the await window.
navigator.onLine is unreliable on Android — returns true whenever any
network interface is up, regardless of actual reachability. This caused
all repo reads to take the API branch and either wait 5 s for the SW
NetworkFirst timeout (cache hit) or hang indefinitely (cache miss).
- All read repos (list/get) now return cached IndexedDB data instantly
and carry a background refresh promise that resolves to fresh data or
null on failure. Callers that opted in (loadTrip, loadTrips) apply
fresh data silently when it arrives.
- tripStore.loadTrip: Promise.all now reads all 7 resources from
IndexedDB (instant), fires network refreshes in background, sets
isLoading: false immediately, then applies fresh data via a second
Promise.all when ready. Tags/categories use upsertTags/upsertCategories.
- DashboardPage.loadTrips: same pattern — renders from cache instantly,
silently updates trip list on refresh.
- axios timeout set to 8 s so requests can never hang indefinitely.
- SW networkTimeoutSeconds lowered from 5 to 2 as defence in depth.
Add type-selector UI in the file import modal letting users choose which
GPX elements (waypoints, routes, tracks) or KML/KMZ elements (points,
paths) to import. KML LineString placemarks are now imported as path
places with route_geometry.
Performance improvements:
- Extract MemoPlaceRow with React.memo and contentVisibility:auto to cut
unnecessary re-renders in PlacesSidebar
- Add weatherQueue to cap concurrent weather fetches at 3
- Replace sequential per-place deletes with a single bulkDelete API call
(new DELETE /places/bulk endpoint + deletePlacesMany service)
- Memoize atlas/photo/weather service calls to avoid redundant requests
- Add multi-select mode to PlacesSidebar for bulk operations
Add large GPX/KML/KMZ fixtures for integration/perf testing and two
profiler analysis scripts under scripts/.