fuzzyworld

word-waltz / files / src / utils / gameRegistry.ts

gameRegistry.ts

1.7 KB · history · blame

1/**
2 * gameRegistry.ts — persists the list of games this device has participated in.
3 *
4 * Each entry stores enough to reconstruct the share URL (gameId + key) and to
5 * display a summary on the home screen without a round-trip to Firestore.
6 * The encryption key is stored in localStorage (local to this device only) —
7 * it is never sent to any server, preserving the same threat model as the URL
8 * fragment approach.
9 */
10
11import type { PlayerId } from '../types.js';
12
13export interface StoredGame {
14 gameId: string;
15 key: string; // base64url AES-GCM key
16 role: PlayerId;
17 myName: string;
18 opponentName: string; // '' if opponent hasn't joined yet
19 status: string; // last-known human-readable status, e.g. "Your turn to solve"
20 myTurn: boolean; // whether it is currently this player's turn
21 createdAt: number;
22 lastUpdated: number;
23}
24
25const REGISTRY_KEY = 'word-waltz:games';
26
27export function getStoredGames(): StoredGame[] {
28 try {
29 return JSON.parse(localStorage.getItem(REGISTRY_KEY) ?? '[]') as StoredGame[];
30 } catch {
31 return [];
32 }
33}
34
35/** Insert or update a game entry (matched by gameId). Most-recent first. */
36export function upsertStoredGame(game: StoredGame): void {
37 const existing = getStoredGames().filter(g => g.gameId !== game.gameId);
38 existing.unshift(game);
39 localStorage.setItem(REGISTRY_KEY, JSON.stringify(existing));
40}
41
42export function removeStoredGame(gameId: string): void {
43 const games = getStoredGames().filter(g => g.gameId !== gameId);
44 localStorage.setItem(REGISTRY_KEY, JSON.stringify(games));
45}
46
47export function clearStoredGames(): void {
48 localStorage.removeItem(REGISTRY_KEY);
49}