// GatewayClient — the typed facade the screens call. Both the real Connect/ // FlatBuffers transport and the in-memory mock implement it. Domain failures (the // gateway's result_code) and edge failures (Connect error codes) are normalised // into a thrown GatewayError carrying a stable `code` the UI maps to an i18n // message. import type { AccountRef, ChatMessage, EvalResult, FriendCode, GameList, GameView, GcgExport, History, HintResult, Invitation, InvitationSettings, LinkResult, MatchResult, MoveResult, Profile, ProfileUpdate, PushEvent, Session, StateView, Stats, Tile, Variant, WordCheckResult, } from './model'; /** GatewayError carries a stable code (the gateway result_code, or an edge code). */ export class GatewayError extends Error { readonly code: string; constructor(code: string, message?: string) { super(message ?? code); this.name = 'GatewayError'; this.code = code; } } /** A tile the player is submitting (rack/blank already resolved to a letter). */ export interface PlacedTile { row: number; col: number; letter: string; blank: boolean; } /** Unsubscribe handle for the live stream. */ export type Unsubscribe = () => void; export interface GatewayClient { // --- auth (unauthenticated) --- authTelegram(initData: string): Promise; authGuest(locale?: string): Promise; authEmailRequest(email: string): Promise; authEmailLogin(email: string, code: string): Promise; // --- profile / lists --- profileGet(): Promise; gamesList(): Promise; // --- lobby --- lobbyEnqueue(variant: Variant): Promise; lobbyPoll(): Promise; /** Leave the auto-match pool (idempotent); a cancelled quick-match must not stay queued. */ lobbyCancel(): Promise; // --- game --- // Stage 13: the play loop exchanges alphabet indices, so submit/evaluate/exchange/ // check-word take the game's variant (to map letters<->indices via the cached alphabet // table), and gameState's includeAlphabet asks the server to embed that table. gameState(gameId: string, includeAlphabet: boolean): Promise; gameHistory(gameId: string): Promise; submitPlay(gameId: string, dir: 'H' | 'V', tiles: PlacedTile[], variant: Variant): Promise; pass(gameId: string): Promise; exchange(gameId: string, tiles: string[], variant: Variant): Promise; resign(gameId: string): Promise; hint(gameId: string): Promise; evaluate(gameId: string, dir: 'H' | 'V', tiles: PlacedTile[], variant: Variant): Promise; checkWord(gameId: string, word: string, variant: Variant): Promise; complaint(gameId: string, word: string, note: string): Promise; /** Hide a finished game from the caller's own lobby list (Stage 17); per-account, irreversible. */ hideGame(gameId: string): Promise; // --- draft (Stage 17) --- /** The player's server-persisted client-side composition (rack order + board tiles), so a * reload or a second device resumes the same arrangement. The JSON is opaque to the * gateway; the client owns the {rack_order, board_tiles} shape. */ draftGet(gameId: string): Promise; draftSave(gameId: string, json: string): Promise; // --- chat --- chatPost(gameId: string, body: string): Promise; chatList(gameId: string): Promise; nudge(gameId: string): Promise; // --- friends (Stage 8) --- friendsList(): Promise; friendsIncoming(): Promise; /** Addressees the caller has already requested (pending or declined); cannot re-request. */ friendsOutgoing(): Promise; friendRequest(accountId: string): Promise; friendRespond(requesterId: string, accept: boolean): Promise; friendCancel(accountId: string): Promise; unfriend(accountId: string): Promise; friendCodeIssue(): Promise; friendCodeRedeem(code: string): Promise; // --- blocks (Stage 8) --- blocksList(): Promise; block(accountId: string): Promise; unblock(accountId: string): Promise; // --- invitations (Stage 8) --- invitationsList(): Promise; invitationCreate(inviteeIds: string[], settings: InvitationSettings): Promise; invitationAccept(invitationId: string): Promise; invitationDecline(invitationId: string): Promise; invitationCancel(invitationId: string): Promise; // --- profile / stats / history (Stage 8) --- profileUpdate(p: ProfileUpdate): Promise; statsGet(): Promise; exportGcg(gameId: string): Promise; // --- account linking & merge (Stage 11) --- linkEmailRequest(email: string): Promise; linkEmailConfirm(email: string, code: string): Promise; linkEmailMerge(email: string, code: string): Promise; linkTelegram(data: string): Promise; linkTelegramMerge(data: string): Promise; // --- live stream --- subscribe(onEvent: (e: PushEvent) => void, onError?: (err: unknown) => void): Unsubscribe; /** Set or clear the bearer token used for authenticated calls and the stream. */ setToken(token: string | null): void; } export type { GameView, Tile };