SQLite database layer for session persistence.
Tracks game sessions:
id (TEXT PRIMARY KEY): Unique session identifiercreated_at (INTEGER): Unix timestampcurrent_turn (INTEGER): Index of current playermax_players (INTEGER): Max active players (default 10)status (TEXT): waiting | active | completedTracks players in each session:
id (INTEGER PRIMARY KEY AUTOINCREMENT)session_id (TEXT): Foreign key to sessionsname (TEXT): Player display nameavatar (TEXT): Emoji avataris_active (INTEGER): 1 for active player, 0 for spectatorturn_order (INTEGER): Turn sequence numberlast_seen (INTEGER): Heartbeat timestampStores played cards:
id (INTEGER PRIMARY KEY AUTOINCREMENT)session_id (TEXT): Foreign key to sessionsplayer_name (TEXT): Who played the cardcard_type (TEXT): role | tone | token-limit | custom | image | removecontent (TEXT): Card instruction/contentimage_url (TEXT): Optional blob storage URLtimestamp (INTEGER): When card was playedStores AI-generated responses:
id (INTEGER PRIMARY KEY AUTOINCREMENT)session_id (TEXT): Foreign key to sessionsprompt (TEXT): Full system promptresponse (TEXT): AI responsetoken_count (INTEGER): Tokens usedtimestamp (INTEGER): When generatedAll database operations are in queries.ts:
createSession(id): Create new sessiongetSession(id): Fetch session by IDupdateSessionTurn(id, turn): Advance turnupdateSessionStatus(id, status): Change statusaddPlayer(sessionId, name, avatar, turnOrder): Add playergetPlayers(sessionId): Get all playersgetActivePlayers(sessionId): Get active players onlyupdatePlayerHeartbeat(sessionId, name): Update last_seenplayCard(sessionId, playerName, type, content, imageUrl?): Add card to stackgetPromptStack(sessionId): Get all played cardsremoveLastCard(sessionId): Undo last cardremoveCardsByType(sessionId, type): Clear specific card typesaveVibeResult(sessionId, prompt, response, tokens): Save AI outputgetLatestVibeResult(sessionId): Get most recent resultTables are versioned (e.g., sessions_v1). To change schema:
VERSION constant in schema.tsimport { initDatabase } from "./database/schema.ts";
import * as db from "./database/queries.ts";
// Initialize tables
await initDatabase();
// Create session
const session = await db.createSession("my-game-123");
// Add player
const player = await db.addPlayer("my-game-123", "Alice", "🎨", 0);
// Play card
await db.playCard("my-game-123", "Alice", "role", "Act as a Rust expert");
// Get stack
const stack = await db.getPromptStack("my-game-123");