Blob cache previously leaked forever: clearTripData omitted it, entries had
no trip discriminator, and there was no size/count bound, so file blobs
survived trip eviction and could starve the map-tile cache for quota.
- BlobCacheEntry gains tripId + bytes; Dexie v3 adds a tripId index with a
backfill upgrade (legacy rows -> tripId -1, bytes from blob.size)
- clearTripData purges the trip's blobs in-transaction
- enforceBlobBudget() evicts oldest-by-cachedAt past 200 entries / 100 MB
- tripSyncManager threads tripId/bytes into puts and enforces the budget
Closes BLOCKER B4 — three reinforcing paths could serve one account's
cached data to the next user on a shared device:
- The Workbox 'api-data' cache keyed trip/user-scoped GETs by URL only
(cookie-blind). Changed to NetworkOnly; offline reads come from the
per-user IndexedDB cache via the repo layer instead.
- IndexedDB had no per-user scoping. The Dexie connection is now scoped
per user (trek-offline-u<id>) behind a Proxy so the ~19 importers keep a
stable binding; login opens the user DB, logout deletes it and returns
to the anonymous DB.
- logout() was fire-and-forget and racy: background flush/syncAll could
re-seed the DB after the wipe. It is now async and ordered — close an
auth gate, unregister sync triggers, disconnect, clear caches, delete
the user DB — and flush()/syncAll() bail when the gate is closed.