aeharding / aeharding/wingover
map: keep MapKit usable offline (tiles are already cached; reauth is the lock)
- Vorherrschende Sprache
- TypeScript
- Sterne
- 0
- Forks
- 0
- Ø Merge
- 4 Std. 2 Min.
- Gemergte PRs (30 T.)
- 6
Beschreibung
Follow-on to #164. #164 guarantees the track always draws. This issue is about keeping the **basemap** too, so an in-flight restart out of coverage still shows the ground you were just flying over.
## The key finding: the tiles are already on the device
MapKit serves tiles with `cache-control: public, max-age=604800` (7 days), and WebKit's cache persists across launches. So a flight flown with service has already downloaded the tiles for that exact area. Nothing is missing offline. MapKit simply refuses to start, so the data is locked, not absent.
**Proven:** capture every MapKit response online, then load the app in a fresh browser with a hard network block, serving only the captured bytes. MapKit initialises completely and paints a full Apple basemap (terrain, labels, coastlines, attribution) with zero network. 75/75 replayed, no console errors.
Note `no-store` on the bootstrap does not prevent this. It binds the browser's HTTP cache, not storage we control.
## What actually blocks an offline relaunch
Only two responses. Everything else is already cached and long-lived.
| endpoint | cache-control | offline? |
|---|---|---|
| `/mk/6.0.x/libs/mapkit.core.*.js` | `max-age=31322996` (~362d) | cached, fine |
| `/md/v1/vtile`, `/ttile`, `/icon` | `max-age=604800` (7d), `s-maxage=2` | cached, fine |
| `/mk/6/mapkit.core.js` (version pointer) | `max-age=23..275` | **expires, blocks** |
| `/ma/bootstrap` (auth) | `max-age=0, no-cache, no-store` | **never cached, blocks** |
So a shim serving just those two from local storage could let WebKit's own cache supply the rest.
## Open question: does reauth cap it?
`/ma/bootstrap` returns an `accessKey` with `expiresInSeconds: 1800`, and the key embeds an issue timestamp. Forcing `expiresInSeconds: 0` in a replay produced an initialised map that painted **no tiles** (empty grid) - but that test *tells* MapKit the key is dead, which a verbatim replay does not. A stored bootstrap still says `1800`, so MapKit may compute the deadline from receipt and never learn otherwise, with no server present to disagree.
An experiment is running: capture untouched, wait out the full 30 minutes, replay verbatim. Result decides scope:
- **Tiles paint:** no practical ceiling; the shim is worth building.
- **Empty grid:** reauth caps continuity at ~30 min from last bootstrap, and only owned tiles give multi-hour coverage.
## Mechanism (PWA and native are different problems)
- **PWA** (`https://wingover.app`): service workers work. `src/sw.ts` (workbox) already exists. Note no `registerSW` call was found in `src/` or `index.html`, so the worker may not be registering at all today - worth checking separately.
- **Native** (`tauri://localhost`): a custom scheme, where WebKit does **not** run service workers. The PWA worker does nothing for the app. `NSURLProtocol` does not see WKWebView traffic and `setURLSchemeHandler` only handles custom schemes, so neither helps. The candidate is `WKWebsiteDataStore.proxyConfigurations` (public API, iOS 17+), routing webview traffic through a proxy we run. Untested.
## Before building
Apple's MapKit JS terms need a real read. Their own `max-age=604800` sanctions a browser cache; a custom store that replays their responses is a different question, and this ships on the App Store.
Beitragsleitfaden
Für dieses Repository ist kein Beitragsleitfaden indexiert
Bewertung
Dieses Issue wurde noch nicht bewertet.