1
0
Fork 0

feat(presence): add presence channel handling in real-time updates

This commit is contained in:
Jason Fraley 2026-08-28 22:08:37 -04:00
parent 6d9b0ed8d8
commit 0eba54b8b8
3 changed files with 18 additions and 0 deletions

View file

@ -29,6 +29,7 @@ export async function GET(req: NextRequest) {
send: (data) => controller.enqueue(encoder.encode(data)),
userId: user ? Number(user.id) : undefined,
events: channel ? new Set(["presence"]) : undefined,
presenceChannel: channel ?? undefined,
};
subscribe(client);

View file

@ -41,6 +41,7 @@ export function useRealtimePresence(channel: string, active: boolean, observe =
} catch {
return;
}
if (detail.channel !== channel) return;
if (detail.action === "snapshot") setParticipants(detail.participants ?? []);
if ((detail.action === "join" || detail.action === "update") && detail.participant) {
setParticipants((current) => [

View file

@ -2,6 +2,7 @@ export interface SSEEventClient {
send: (data: string) => void;
events?: Set<string>;
userId?: number;
presenceChannel?: string;
}
const clients = new Set<SSEEventClient>();
@ -21,8 +22,23 @@ export function clientCount(): number {
export function broadcast(event: string, data: unknown): number {
const payload = `event: ${event}\ndata: ${JSON.stringify(data)}\n\n`;
const presenceChannel =
event === "presence" &&
typeof data === "object" &&
data !== null &&
"channel" in data &&
typeof data.channel === "string"
? data.channel
: undefined;
for (const client of clients) {
if (client.events && !client.events.has(event)) continue;
if (
event === "presence" &&
client.presenceChannel !== undefined &&
client.presenceChannel !== presenceChannel
) {
continue;
}
try {
client.send(payload);
} catch {