Files
Syncpad/www/src/lib/sse.ts
2026-05-02 05:49:09 +00:00

68 lines
1.8 KiB
TypeScript

import type { Note, ShareInvitation } from '@/types'
export interface SSEHandlers {
onNoteCreated: (note: Note) => void
onNoteUpdated: (note: Note) => void
onNoteDeleted: (data: { id: string }) => void
onInvitationReceived?: (invitation: ShareInvitation) => void
onError: (err: Event) => void
}
export function createSSEClient(url: string, handlers: SSEHandlers): { close: () => void } {
const eventSource = new EventSource(url)
eventSource.addEventListener('note_created', (event: MessageEvent) => {
try {
const note: Note = JSON.parse(event.data)
handlers.onNoteCreated(note)
} catch {
handlers.onError(new Event('parse_error'))
}
})
eventSource.addEventListener('note_updated', (event: MessageEvent) => {
try {
const note: Note = JSON.parse(event.data)
handlers.onNoteUpdated(note)
} catch {
handlers.onError(new Event('parse_error'))
}
})
eventSource.addEventListener('note_deleted', (event: MessageEvent) => {
try {
const data: { id: string } = JSON.parse(event.data)
handlers.onNoteDeleted(data)
} catch {
handlers.onError(new Event('parse_error'))
}
})
eventSource.addEventListener('invitation_received', (event: MessageEvent) => {
try {
const raw = JSON.parse(event.data)
const invitation: ShareInvitation = {
id: raw.id,
fromPublicKey: raw.from_public_key,
toPublicKey: raw.to_public_key,
encryptedGroupKey: raw.encrypted_group_key,
iv: raw.iv,
noteId: raw.note_id,
noteTitle: raw.note_title,
created_at: raw.created_at,
}
handlers.onInvitationReceived?.(invitation)
} catch {
handlers.onError(new Event('parse_error'))
}
})
eventSource.onerror = (err: Event) => {
handlers.onError(err)
}
return {
close: () => eventSource.close(),
}
}