export class SocketHandler { constructor(url) { this.url = url; this.socket = new WebSocket(url); this.socket.addEventListener('open', (e) => { this.callbacks.open.forEach(cb => cb(e)); }) this.socket.addEventListener('message', (e) => { const data = JSON.parse(e.data); this.callbacks.message.forEach((listener, index) => { if (listener.type && listener.type !== data.type) { return; } listener.cb(data.type, data.data, e); if (listener.once) { this.callbacks.message.splice(index, 1); } }); }); this.callbacks = { open: [], message: [], close: [], }; this.initialized = false; this.gameToken = null; } async initGame() { this.initialized = false; this.gameToken = null; return this.sendAndWaitForResult('game.init', { playerCount: 4, }); } async joinGame(gameId) { this.initialized = false; this.gameToken = null; return this.sendAndWaitForResult('game.join', { gameID: gameId, }); } playCard(card) { if (!this.initialized) { return; } this.send('card.play', { color: card.color, value: card.value, }); } drawCard() { if (!this.initialized) { return; } this.send('card.draw', {}) } selectColor(color) { if (!this.initialized) { return; } this.send('card.color', { color }); } send(type, data) { this.socket.send(JSON.stringify({ type, data, })); } async sendAndWaitForResult(type, data) { return new Promise((resolve, reject) => { this.send(type, data); this.callbacks.message.push({ type: type + '.result', once: true, cb: (type, data) => { resolve(data); }, }); }); } onOpen(callback) { this.callbacks.open.push(callback); } onMessage(callback) { this.callbacks.message.push(callback); } }