38 lines
1.2 KiB
TypeScript
38 lines
1.2 KiB
TypeScript
import { rtc } from '@chat-app/shared';
|
|
import type { CallSignal } from '@chat-app/shared/rtc';
|
|
import type { AppSupabaseClient } from '@chat-app/shared/supabase';
|
|
|
|
// Thin wrapper around Supabase realtime broadcast for call signaling.
|
|
// One channel per peer userId. Subscriptions live for the lifetime of
|
|
// the AuthProvider's session; teardown returns a no-arg unsubscribe.
|
|
|
|
export type SignalListener = (signal: CallSignal) => void;
|
|
|
|
export function subscribeCallSignals(
|
|
client: AppSupabaseClient,
|
|
myUserId: string,
|
|
onSignal: SignalListener,
|
|
): () => void {
|
|
const ch = client.channel(rtc.signalTopic(myUserId));
|
|
ch.on('broadcast', { event: 'signal' }, (msg) => {
|
|
if (msg.payload && typeof msg.payload === 'object') {
|
|
onSignal(msg.payload as CallSignal);
|
|
}
|
|
});
|
|
void ch.subscribe();
|
|
return () => {
|
|
void client.removeChannel(ch);
|
|
};
|
|
}
|
|
|
|
export async function sendCallSignal(
|
|
client: AppSupabaseClient,
|
|
toUserId: string,
|
|
payload: CallSignal,
|
|
): Promise<void> {
|
|
const ch = client.channel(rtc.signalTopic(toUserId));
|
|
await ch.subscribe();
|
|
await ch.send({ type: 'broadcast', event: 'signal', payload });
|
|
await client.removeChannel(ch);
|
|
}
|