{"version":3,"sources":["../../src/network/Server.ts"],"sourcesContent":["import { Server } from \"socket.io\";\nimport http from \"http\";\nimport { createServer } from \"http\";\nimport { Socket } from \"socket.io\";\nimport { log, Pool } from '../utils/index.js';\nimport type Listener from './types/Listener.js';\nimport Connection from \"./Connection.js\";\n\n\nclass NetworkServer {\n    /* this class will handle the logic managing the server conenctions with clilent,\n     * it will keep track of the node id and it will handle connection and dicoections */\n    private io: Server;\n    private host: string;\n    private port: number;\n    private maxTransferSize: number;\n    private clients: Pool<Connection>;\n    public name: string;\n    public isLan: boolean;\n    public connectionCallback: any;\n    public disconnectCallback: any;\n    public listeners: Listener[];\n    public httpServer?: http.Server;\n    public isReady: boolean;\n    public timeout: number;\n    private ioOptions: any;\n\n    constructor({ name, host, port, listeners } : {\n        name: string, host: string, port: number, listeners: Listener[],\n    }, options?: { timeout: number, maxTransferSize: number }) {\n        this.host = host || \"localhost\";\n        this.isLan = this.host !== 'localhost'\n        this.port = port || 0; // zero means random port\n        this.isReady = false;\n        this.maxTransferSize = options?.maxTransferSize || 1e9; // default 1GB\n        this.name = name? name : \"server\";\n        this.connectionCallback = null;\n        this.disconnectCallback = null;\n        this.clients = new Pool<Connection>();\n        this.listeners = listeners || [];\n        this.ioOptions = {\n            maxHttpBufferSize: this.maxTransferSize,\n        };\n        this.timeout = options?.timeout || 5 * 60 * 1000; // default 5 minutes\n        // initiate with the server\n        if(this.isLan){ // if we are in a over lan\n            // create a http server\n            this.httpServer = createServer();\n            this.io = new Server(this.httpServer, this.ioOptions);\n            // check if io server was created\n            if(this.io.httpServer.address() === null)\n                throw new Error(\"Host and port already in use or invalid\");\n            this.httpServer.listen(this.port, this.host, () => {\n                let address = this.httpServer?.address();\n                if(!address || typeof address === \"string\") {\n                    console.error(\"Server is not running\");\n                    return;\n                }\n                this.isReady = true;\n                this.port = address.port\n            });\n        }else{ // if we are in localhost\n            this.io = new Server(this.port, this.ioOptions);\n            // check is io server was created\n            if(this.io.httpServer.address() === null)\n                throw new Error(\"Host and port already in use or invalid\");\n            // get the port number\n            this.port = (this.io as any).httpServer.address().port;\n        }\n        // create a new socket.io client instance\n        this.io.on(\"connection\", this.handleConnection.bind(this));\n        this.io.on(\"reconnect\", () => log(\"[Server] on reconnect triggered\"));\n        this.io.on(\"disconnect\", this.handleDisconnection.bind(this));\n        // set the listener on the server socket\n        this.setListeners(this.listeners);\n    }\n\n    private async handleConnection(socket: Socket) {\n        log(\"[Server] got new connection\");\n        // make a new connectection instance\n        let connection = new Connection({\n            socket, name: this.name,\n            options: {\n                listeners: this.listeners,\n                timeout: this.timeout,\n            }\n        });\n        // await fo connection to be established\n        await connection.connected();\n        // get the id of the connection\n        let id = connection.getTargetId();\n        log(\"[Server] connection id: \", id);\n        // check if id is null\n        if(id == null) throw new Error(\"Connection id is null\");\n        // check if connection already exists\n        if(this.clients.has(id)) {\n            let client = this.clients.remove(id);\n            client && client.close();\n        }\n        // give server listeners to the connection\n        // await connection.setListeners(this.listeners);\n        // add connection to pool\n        this.clients.add(id, connection);\n        // run callback\n        if(this.connectionCallback)\n            this.connectionCallback(connection);\n    }\n\n    private handleDisconnection(socket: Socket) {\n        let socketId = socket.id\n        // filter every client based on the socket id\n        let conn = this.clients.toArray()\n        .filter((client: Connection) => client.socketId === socketId)[0];\n        // cast conn as type Connection\n        if(conn) {\n            // close the connection\n            conn.close();\n            let id = conn.getTargetId();\n            if(id === undefined)\n                throw new Error(\"Connection id is undefined\");\n            this.clients.remove(conn.getTargetId() as string);\n            // run the disconnect callback\n            if(this.disconnectCallback)\n                this.disconnectCallback(conn);\n        }\n    }\n\n    public setListeners(listeners: Listener[]) {\n        // set the listeners on the server socket\n        listeners.forEach((listener: Listener) => {\n            // run the listener callback and emit the result to the client\n            let callback = async ( ...args: any[] ) => {\n                // run the listener callback\n                let result = await listener.callback(...args);\n                // emit the result to the client\n                this.io.emit(listener.event, result);\n            }\n            // remove any previous listeners\n            this.io.removeAllListeners(listener.event);\n            // set the new listener\n            this.io.on(listener.event, callback);\n        });\n        // store the listeners\n        this.listeners = listeners;\n        // broadcast the new listeners to all clients\n        this.io.emit('_set_listeners', this.listeners);\n    }\n\n    public broadcast(event: string, data: any) {\n        // broadcast an event to all clients\n        this.io.emit(event, data);\n    }\n\n    public addListeners(listeners: Listener[]) {\n        // add a new listener to the server\n        // if we have the same event name, we will overwrite it\n        const eventMap = new Map(this.listeners.map(l => [l.event, l]));\n        listeners.forEach(l => eventMap.set(l.event, l));\n        listeners = Array.from(eventMap.values());\n        // set the listener on the server socket\n        this.setListeners(this.listeners);\n    }\n\n    public getClient(id: string) : Connection | null {\n        return this.clients.get(id);\n    }\n\n    public getClients() : Connection[] {\n        return this.clients.toArray();\n    }\n\n    public onConnection(callback: any) {\n        this.connectionCallback = callback;\n    }\n\n    public onDisconnect(callback: any) {\n        this.disconnectCallback = callback;\n    }\n\n    public getListeners() {\n        // the the listneres from the first client\n        let client = this.clients.toArray()[0];\n        // if client is null return an empty array\n        if(!client) return [];\n        // return the listeners\n        return client.getListeners();\n    }\n\n    async close() {\n        // close all sockets\n        this.io.close();\n    }\n\n}\n\nexport default NetworkServer;\n"],"mappings":"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","names":["import_http","Connection"]}