Rewrites the desktop mirror as services/sync/SyncEngine: a persistent outbox, per-account server-clock keyset cursors with paging, pulls that never overwrite unsent local edits, deletions both ways through sync_tombstones and per-row failure isolation. It now covers history titles and favorites, dictionary, every meeting's memos and documents, memo tags, user commands and dictation/meeting templates, and registers the desktop as a device that the phone can disconnect. Fixes shipped defects: the first pull after sign-in fetched nothing, only the first meeting's children were pushed, team meetings leaked into the personal database and lost team_id on re-push, and Realtime never connected because Electron's Node 20 has no global WebSocket (ws is now the transport). Anonymous local-mode records are imported into the first account that signs in. The settings sync section is translated and shows pending/rejected changes; synced screens reload on app:dataChanged.
10 lines
575 B
TypeScript
10 lines
575 B
TypeScript
// src/main/services/sync/realtime-transport.ts
|
|
// Electron 33 메인 프로세스(Node 20)에는 전역 WebSocket이 없어 Supabase Realtime이 연결하지 못한다.
|
|
// ws는 브라우저 WebSocket API와 호환되지만 이벤트 핸들러 선언이 달라 타입만 한 번 맞춘다.
|
|
|
|
import WebSocket from 'ws'
|
|
import type { SupabaseClientOptions } from '@supabase/supabase-js'
|
|
|
|
type RealtimeTransport = NonNullable<NonNullable<SupabaseClientOptions<'public'>['realtime']>['transport']>
|
|
|
|
export const nodeRealtimeTransport = WebSocket as unknown as RealtimeTransport
|