/** * Presence seam: tracks which thread each socket has in the foreground so the notification * projector can suppress push for a thread the recipient is actively viewing. Async so it can be * backed by Redis across replicas (prod) or an in-memory Map on a single instance (dev). */ export interface PresencePort { /** Record a socket's foregrounded thread (null when the window is blurred / no thread open). */ setFocus(socketId: string, userId: string, threadId: string | null): Promise; /** Forget everything about a socket (on disconnect). */ clearSocket(socketId: string): Promise; /** True if ANY of the user's sockets currently has this thread in the foreground. */ isViewing(userId: string, threadId: string): Promise; } export const PRESENCE_PORT = Symbol('PRESENCE_PORT');