Files
blind_chess/packages/shared/src/protocol.ts
T
claude (blind_chess) ce36755a89 feat(server): per-viewer capture tally on joined and update messages
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-18 20:09:26 -04:00

68 lines
1.9 KiB
TypeScript

import type {
BoardView, CaptureTally, Color, GameId, GameStatus, Mode, PlayerToken,
PromotionType, Square, EndReason,
} from './types.js';
import type { Announcement } from './moderator.js';
export type ClientMessage =
| { type: 'hello'; gameId: GameId; token?: PlayerToken; joinAs?: Color | 'auto' }
| { type: 'commit'; from: Square; to?: Square; promotion?: PromotionType }
| { type: 'resign' }
| { type: 'offer-draw' }
| { type: 'respond-draw'; accept: boolean }
| { type: 'pong' };
export type ErrorCode =
| 'game_not_found'
| 'slot_taken'
| 'spectators_disabled'
| 'not_your_turn'
| 'malformed'
| 'promotion_required'
| 'must_move_touched_piece'
| 'rate_limited'
| 'invalid_token';
export type ServerMessage =
| {
type: 'joined';
you: Color | 'spectator-rejected';
token: PlayerToken;
view: BoardView;
announcements: Announcement[];
gameStatus: GameStatus;
mode: Mode;
highlightingEnabled: boolean;
opponentConnected: boolean;
captures: CaptureTally;
aiOpponent?: { color: Color; brain: 'casual' | 'recon' };
}
| {
type: 'update';
view: BoardView;
newAnnouncements: Announcement[];
gameStatus: GameStatus;
touchedPiece?: Square;
drawOffer?: { from: Color } | null;
endReason?: EndReason;
winner?: Color | null;
captures: CaptureTally;
aiOpponent?: { color: Color; brain: 'casual' | 'recon' };
}
| { type: 'peer-status'; color: Color; connected: boolean; graceUntil?: number }
| { type: 'error'; code: ErrorCode; message: string }
| { type: 'ping' };
export interface CreateGameRequest {
mode: Mode;
side: Color | 'random';
highlightingEnabled: boolean;
vsAi?: { brain: 'casual' | 'recon' };
}
export interface CreateGameResponse {
gameId: GameId;
creatorToken: PlayerToken;
joinUrl: string | null;
}