// What the server tells a viewer about a room. The game's own state is // whatever GameSpec.view returned for that viewer; nothing else leaves. import type { Outcome, SeatId, TableOptions } from '../game/spec'; /** One line of table talk: from a seat, or from the Peanut Gallery when the host allows it (id SPECTATOR, signed with `name`). */ export interface ChatLine { id: SeatId; text: string; at: number; name?: string; } export interface RoomView { roomId: string; seq: number; /** The most seats the table will take. */ size: number; /** The viewer's seat, or SPECTATOR for the gallery. */ me: SeatId; /** The player who opened the table and may begin the game. */ host: SeatId; seats: { id: SeatId; name: string; bot: boolean }[]; /** Seats that still have to move before the round resolves. */ waitingOn: SeatId[]; /** The round being written, from one; null before the game begins. */ turn: number | null; over: Outcome | null; state: State | null; chat: ChatLine[]; /** How many watch from the Peanut Gallery. */ audience: number; /** The host lets the gallery talk. */ galleryTalk: boolean; /** The keeper of the site was called to a seat, and by whom. */ challenge: { by: SeatId; at: number } | null; /** Names with a seat held who have not yet sat: the last table's players, or the keeper. */ expected: string[]; /** A finished table's rematch: where it went, and who called. */ rematch: { to: string; by: SeatId } | null; /** The table this one is the rematch of. */ rematchOf: string | null; /** The host's choices for this table, every declared option filled. */ options: TableOptions; /** The keeper of the site, and where they live, for a table that calls them. */ keeper: string; keeperZone: string; } /** One line under a report: the keeper's reply, with its status, or the player's answer. */ export interface ReportLine { at: string; text: string; from: 'desk' | 'player'; status?: string; } /** A report to the keeper, with the exchange under it. */ export interface Report { id: string; at: string; roomId: string; /** The reporter's name, or "(gallery)" for a watcher. */ player: string; seat: SeatId | null; /** The round being written when the report was filed, and the ledger's length. */ turn: number | null; seq: number; happened: string; expected: string; /** The whole exchange in order: the keeper's replies and the player's answers. */ thread: ReportLine[]; /** A screenshot's file name under images/, when one was sent. */ image?: string; } /** What the ledgers add up to, for the hall's about panel. */ export interface Tally { tablesOpened: number; gamesBegun: number; gamesFinished: number; /** Distinct names of people who have taken a seat; a bot's name is not counted. */ namesSeated: number; turnsPlayed: number; /** Minutes at the table: gaps under ten minutes between one move and the next, summed. */ minutesAtTable: number; longestGameTurns: number; gamesWithBot: number; talkLines: number; firstGameAt: string | null; /** The game's own lines, summed over finished games. */ byGame: Record; }