fix(offline): cold-boot offline from the persisted session + profile #199
Reference in New Issue
Block a user
Delete Branch "feature/offline-boot"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Part of the PWA offline mode (Phase C). Fixes the last of the three contour bugs: an installed PWA relaunched with the network off hung on the splash.
Root cause
C1 (#197) precaches the app shell, so the bundle loads offline. But
bootstrap()then adopted the persisted session and fetched the profile over the network (gateway.profileGet()) — which hangs with no network. And the profile was never persisted, so there was nothing to fall back to.Fix
session.tssaveProfile/loadProfile/clearProfile(mirroringsaveSession), written on every online adopt + refresh, cleared on logout.bootstrap()skips the session adoption + profile fetch and launches from the cached session + profile straight into the offline lobby. Without a cached profile (an install that was never online) it drops the sticky flag and boots online — the first launch must be online. The decision is the pure, unit-testedshouldBootOffline.Tests
shouldBootOfflinetruth table (477 total).offlineModeis off).Docs: ARCHITECTURE.
This closes all three contour bugs (word-check + lobby refresh landed in #198; cold-boot here). Remaining offline fast-follows — Settings Friends/Profile/Feedback gating, flip-to-offline readiness wait, B4 hint UI, the offline mock e2e — are tracked in the plan.
In a local game the human seat's account id was a synthetic 'local:human:0', so seatName's `accountId === session.userId` check never matched: the game header rendered BOTH seats as 🤖 (the vs_ai fallback), and the lobby's groupGames could not find the viewer's seat, so a human's turn read as 'Their turn' with the hourglass. Carry the real account id on the human seat (create -> record -> GameView); the robot keeps its synthetic id. Local games created before this fix keep the old display (no migration).