import { Server as SocketServer } from "socket.io" ; import { SocketServerEvents , SocketClientEvents , SocketEventHandler } from "@uno-game/protocols" ; import ErrorHandler from "@uno-game/error-handler" ; import { SocketCallback , SocketClient , SocketContext , SocketRoomNameMap , } from "@/Protocols/SocketProtocol" ; class SocketService { private io : SocketServer ; on < ReceivedData extends unknown , ResponseData extends unknown > ( client , event , handler ) { client . on ( event , async ( data , callback ) => { try { const result = await handler ( data ) ; this . callback ( callback , null , result ) ; } catch ( error ) { ErrorHandler . handle ( error ) ; this . callback ( callback , error . name , null ) ; } } ) ; } setup ( socket ) { const socketWithDisabledBinary = ( socket as any ) . binary ( false ) ; this . io = socketWithDisabledBinary as SocketServer ; } emitRoomEvent < Data extends unknown > ( context , id , event , data ) { const roomName = this . mountRoomName ( context , id ) ; this . emitEvent ( roomName , event , data ) ; } removeListener ( client , context , id ) { const roomName = this . mountRoomName ( context , id ) ; client . leave ( roomName ) ; } setupListener ( client , context , id ) { const roomName = this . mountRoomName ( context , id ) ; client . join ( roomName ) ; } private mountRoomName ( context , id ) { const socketRoomNameMap = { game : `game:${ id }` , player : `player:${ id }` , chat : `chat:${ id }` , } ; const roomName = socketRoomNameMap [ context ] ; return roomName ; } private emitEvent ( roomId , event , data ) { const socket = this . io ; socket . to ( roomId ) . emit ( event , data ) ; } private callback ( callback , error , data ) { if ( typeof callback === "function" ) { callback ( error , data ) ; } } } export default new SocketService ( ) ;