import type { GameEvents } from "./events.js"; import type { ChatFilter } from "./chatFilter.js"; import type { EmotesDeps } from "./social.js"; export type ChatChannelKind = "global" | "party" | "proximity"; export interface ChatRateLimit { count: number; perMs: number; } export interface ChatChannelDef { id: string; kind: ChatChannelKind; radius?: number; historyLimit?: number; rateLimit?: ChatRateLimit; } export interface ChatMessage { id: string; channelId: string; fromUserId: string; body: string; at: number; } export type ChatRecipients = readonly string[] | "all"; export type ChatSendResult = { message: ChatMessage; recipients: ChatRecipients; } | { reason: string; }; export interface ChatSnapshot { messages: Record; counter: number; rateWindows?: Record>; } export interface Chat { register(def: ChatChannelDef): void; channels(): ChatChannelDef[]; send(fromUserId: string, body: string): ChatSendResult; send(fromUserId: string, channelId: string, body: string): ChatSendResult; recent(options?: { limit?: number; channelId?: string; viewerUserId?: string; }): ChatMessage[]; whisper(fromUserId: string, toUserId: string, body: string): ChatSendResult; history(channelId: string, options?: { limit?: number; viewerUserId?: string; }): ChatMessage[]; snapshot(): ChatSnapshot; hydrate(data: ChatSnapshot): void; } export interface ChatDeps { events: GameEvents; now?: () => number; party?: { membersOf(userId: string): string[]; }; proximity?: EmotesDeps; blockedBy?: (userId: string) => readonly string[]; maxBodyLength?: number; defaultRateLimit?: ChatRateLimit; filter?: ChatFilter; } export declare const DEFAULT_CHAT_RATE_LIMIT: ChatRateLimit; export declare const DEFAULT_CHAT_HISTORY_LIMIT = 100; export declare const DEFAULT_CHAT_BODY_LENGTH = 240; export declare const DEFAULT_PROXIMITY_CHAT_RADIUS = 20; export declare const WHISPER_CHANNEL_PREFIX = "whisper:"; export declare function whisperChannelId(a: string, b: string): string; export interface ChatRateLimiter { allow(key: string, atMs: number): boolean; snapshot(): Record; restore(state: Record): void; } export declare function createChatRateLimiter(limit: ChatRateLimit): ChatRateLimiter; export declare function createChat(deps: ChatDeps): Chat; /** Sanitized chat text or a displayable validation failure. */ export type ChatValidation = { ok: true; text: string; } | { ok: false; reason: string; }; /** Strip control characters and enforce the shared chat message policy before storage or broadcast. */ export declare function validateChatMessage(value: unknown, options?: { maxLength?: number; }): ChatValidation;