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)), send: (data) => controller.enqueue(encoder.encode(data)),
userId: user ? Number(user.id) : undefined, userId: user ? Number(user.id) : undefined,
events: channel ? new Set(["presence"]) : undefined, events: channel ? new Set(["presence"]) : undefined,
presenceChannel: channel ?? undefined,
}; };
subscribe(client); subscribe(client);

View file

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

View file

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