Files
TREK/client/src/repo/routeCacheRepo.ts
T
Maurice aa24a9eff7 fix(map): keep routed roads on the device so a whole-trip route opens drawn
With "Show whole trip" on, every leg of every day went to the router one at a
time, a second apart, and the route cache lived in memory only, so each visit
started over: a trip of a month took 30 to 45 seconds before its route was
drawn, on every open.

Routes the router answered are now also kept on the device (Dexie v14,
routeCache by RouteCalculator's cache key, a month at most, the oldest give way
past 3000). A leg found there needs no request and no pause, so a trip whose
legs did not change opens with its roads at once; only new or changed legs are
routed. Plugin routes stay in memory only, since they depend on trip and day.
The cache moves out of RouteCalculator into routeStore.ts.

Closes #2794
2026-10-25 18:59:49 +01:00

49 lines
1.7 KiB
TypeScript

import { offlineDb } from '../db/offlineDb';
/** Roads change; an answer older than this is asked again. */
const MAX_AGE_MS = 30 * 24 * 60 * 60 * 1000;
/** How many routes the device keeps before the oldest give way. */
const MAX_ROWS = 3000;
/** Pruning counts the table, so it runs every so many writes rather than on each one. */
const PRUNE_EVERY = 100;
let writes = 0;
async function prune(): Promise<void> {
const extra = (await offlineDb.routeCache.count()) - MAX_ROWS;
if (extra <= 0) return;
const oldest = await offlineDb.routeCache.orderBy('savedAt').limit(extra).primaryKeys();
await offlineDb.routeCache.bulkDelete(oldest);
}
/**
* Road routes kept on the device, by RouteCalculator's cache key, so a trip that
* shows its whole route opens with its roads instead of asking the router for
* every leg again, one a second, on every visit (#2794). A convenience only:
* anything this store cannot read or write is simply routed again.
*/
export const routeCacheRepo = {
/** The route kept under `key`, unless it is missing or too old. */
async get<T>(key: string): Promise<T | null> {
try {
const row = await offlineDb.routeCache.get(key);
if (!row || Date.now() - row.savedAt > MAX_AGE_MS) return null;
return row.route as T;
} catch {
// A closed or blocked database: the leg is routed again.
return null;
}
},
/** Keeps a route the router just answered. */
async put(key: string, route: unknown): Promise<void> {
try {
await offlineDb.routeCache.put({ key, route, savedAt: Date.now() });
writes += 1;
if (writes % PRUNE_EVERY === 0) await prune();
} catch {
// A full or blocked database: the route still serves this visit from memory.
}
},
};