import { io } from 'socket.io-client'; class SocketManager { constructor() { this.socket = io('', { transports: ["websocket"], autoConnect: false }); this.emit = this.emit.bind(this); this.on = this.on.bind(this); this.off = this.off.bind(this); this.connectPromise = null; this.pendingListeners = new Map(); } on(event, callback) { // If socket is already connected, register the listener directly if (this.socket.connected) { this.socket.on(event, callback); return; } // Store the listener to be registered when connection is established if (!this.pendingListeners.has(event)) { this.pendingListeners.set(event, new Set()); } this.pendingListeners.get(event).add(callback); // If not already connecting, initiate connection if (!this.connectPromise) { this.connect(); } // Register the listener now, it will receive events once connected this.socket.on(event, callback); } off(event, callback) { // Remove from socket listeners this.socket.off(event, callback); // Remove from pending listeners if present if (this.pendingListeners.has(event)) { const listeners = this.pendingListeners.get(event); listeners.delete(callback); if (listeners.size === 0) { this.pendingListeners.delete(event); } } } connect() { if (this.connectPromise) return this.connectPromise; this.connectPromise = new Promise((resolve, reject) => { this.socket.connect(); this.socket.once('connect', () => { resolve(); }); this.socket.once('connect_error', (error) => { this.connectPromise = null; reject(error); }); }); return this.connectPromise; } emit(event, ...args) { return new Promise((resolve, reject) => { if (!this.socket.connected) { // If not already connecting, start connection if (!this.connectPromise) { this.connect(); } // Wait for connection before emitting this.connectPromise .then(() => { this.socket.emit(event, ...args); resolve(); }) .catch((error) => { reject(error); }); } else { // Socket already connected, emit directly this.socket.emit(event, ...args); resolve(); } }); } } // Create singleton instance const socketManager = new SocketManager(); // Attach to window object window.socketManager = socketManager; export default socketManager;