- TripPlannerPage: change splash effect dep from `trip` (object ref) to
`trip?.id` (primitive) — background refreshes no longer reset the 1500 ms
timer on every new object reference, fixing the forever-splash on SPA nav
- tripRepo.list: await upserts on the cold-IDB path so the next mount reads
from Dexie instead of hitting the network again, fixing the remount skeleton
- tripSyncManager: add stale-flag detection (>2 min resets _syncing), 90 s
hard timeout via Promise.race, parallel post-sync prefetch via
Promise.allSettled, and updated header comment to reflect manual-only policy
- OfflineTab: guard handleResync with a 120 s client-side timeout that
interrupts and clears the spinner if syncAll stalls
Three changes:
- tripSyncManager: add interrupt() so trip page load can stop competing
background bundle sync requests; also try clearing blobCache before
falling back to full clearAll() on QuotaExceededError
- TripPlannerPage: call tripSyncManager.interrupt() when mounting so
loadTrip gets network priority over background syncAll
- TripPlannerPage: show a 'go back to dashboard' link after 12 seconds
on the splash screen so users are never stuck with no escape
When IDB storage is full, syncTrip() throws an AbortError wrapping
QuotaExceededError. Now: clear that trip's existing data and retry once;
if quota is still exceeded, wipe all IDB data so the next sync starts
fresh rather than silently failing on every subsequent call.