/** * Adapter from the internal WebSocket type (EnrichedChatMessage) to the * display-layer type (DisplayChatMessage). Lives here so ChatOverlay can * import it without touching twitchWebsocket.ts, and so the wire format * stays decoupled from rendering concerns. */ export function normalizeStreamplaceMessage( msg: EnrichedChatMessage, ): DisplayChatMessage { const record = msg.record as { text?: string; reply?: unknown }; return { id: msg.uri, source: "streamplace", channel: msg.author.handle, displayName: msg.author.displayName ?? msg.author.handle, avatarUrl: msg.author.avatarUrl, pronouns: msg.author.pronouns, color: msg.chatProfile?.color ?? undefined, text: record.text ?? "", badges: (msg.badges ?? []).map((b) => ({ badgeType: b.badgeType })), isReply: !!record.reply, streamerAvatarUrl: msg.streamerAvatarUrl, timestamp: new Date(msg.indexedAt), }; }