export class SyncClient { constructor({ onEvent, onError }) { this.socket = null this.onEvent = onEvent this.onError = onError } connect(baseUrl, roomCode, deviceId) { this.close() const wsBase = baseUrl.replace(/\/$/, '').replace('http://', 'ws://').replace('https://', 'wss://') this.socket = uni.connectSocket({ url: `${wsBase}/ws?roomCode=${encodeURIComponent(roomCode)}&deviceId=${encodeURIComponent(deviceId)}`, complete: () => {} }) this.socket.onMessage((message) => { const data = JSON.parse(message.data) this.onEvent(data.type, data.payload || {}) }) this.socket.onError((err) => this.onError(JSON.stringify(err))) this.socket.onClose(() => this.onError('websocket closed')) } close() { if (this.socket) { this.socket.close({}) this.socket = null } } setSource(source) { this.send('setSource', source) } play(positionMs) { this.send('play', { positionMs }) } pause(positionMs) { this.send('pause', { positionMs }) } syncToLive() { this.send('syncToLive', { state: 'playing', positionMs: 0, targetLatencyMs: 3000 }) } send(type, payload) { if (!this.socket) return this.socket.send({ data: JSON.stringify({ type, payload }) }) } }