{"version":3,"sources":["../../src/network/Network.ts"],"sourcesContent":["import Connection from './Connection.js';\nimport { uuid, log, Pool } from '../utils/index.js';\nimport type Listener from './types/Listener.js';\nimport Server from './Server.js';\n\nclass Network {\n    /* *\n     * this class will handle the connections of a node in the network.\n     * this node can be in either a server or a client.\n     * in a server it will have a Server instance and it will handle the nodes connections\n     * in a client it will have a pool of connections to other servers\n     * Each Node will have a NetworkNode\n     * */\n\n    public id: string;\n    // this is where a node store its server,\n    // which in turn stores its connections to clients\n    public server: Server | null;\n    public name: string;\n    private listeners: Listener[];\n    // this is where we store our connections to servers\n    public connections: Pool<Connection>;\n    // callback for when a new service connection is made\n    public serviceConnectionCallback?: Function;\n    // callback for when a service disconnects\n    public serviceDisconnectCallback?: Function;\n    // callback for when a new listener is added\n    public newListenersCallback?: Function;\n\n\n    constructor({ name = '', id = undefined } : { name?: string, id?: string }) {\n        //log(`[Network][${name}] netowrk created`);\n        this.name = name;\n        this.listeners = [];\n        this.id = id || uuid();\n        this.server = null;\n        this.connections = new Pool();\n        this.serviceConnectionCallback = undefined;\n        this.serviceDisconnectCallback = undefined;\n        this.newListenersCallback = undefined;\n    }\n\n    async connect({ name, host, port, as } : { name?: string, host: string, port: number, as?: string }): Promise<Connection> {\n        /* this function connects to a server instance or a Node Manager\n         * and it keeps track of the conenction by adding it to a pool of server connection\n         * it uses the name as the key in the pool\n         * then run the callback */\n        const connection = new Connection({\n            name : this.name, host, port, id: this.id,\n            onSetListeners: this.newListenersCallback\n        });\n        // await connection and handshake\n        await connection.connected();\n        // get the name of the target service\n        let server_name = connection.getTargetName();\n        if(server_name === undefined)\n            throw new Error('Server name is undefined');\n        if(name !== undefined) // check if the name is the same\n            if(server_name !== name)\n                throw new Error(`Server name mismatch: ${server_name} !== ${name}`);\n        // if we are saving the connection as a different name\n        if(as !== undefined) server_name = as;\n        // if we already have a connection with the same id, remove it\n        if(this.connections.has(server_name)) {\n            let conn = this.connections.remove(server_name);\n            conn && conn.close();\n        }\n        // add the listeners to the new connection\n        connection.setListeners(this.listeners);\n        // add the new connection\n        this.connections.add(server_name, connection);\n        // new connection callback\n        this.serviceConnectionCallback && this.serviceConnectionCallback(connection);\n        // return the connection\n        return connection;\n    }\n\n    public async connectAll(services: { name: string, host: string, port: number }[]) {\n        log(`[Network][${this.name}] connecting to all services`, services);\n        // connect to all the services\n        let connections = await Promise.all(services.map(\n            async service => await this.connect({\n                name: service.name,\n                host: service.host,\n                port: service.port\n            })\n        )).catch((err) => {\n            log(`[Network][${this.name}] error connecting to services:`, err);\n            return [];\n        })\n        //log(`[Network][${this.name}] returning connections:`, connections);\n        return connections;\n    }\n\n    public createServer(\n        name: string, host: string, port: number,\n        listeners: Listener[] = []\n    ) {\n        // the server keeps track of it client connections\n        this.server = new Server({ name, host, port, listeners });\n    }\n\n    public close() {\n        // if we have a server we close it\n        if(this.server){\n            this.server.close()\n        }\n        // close all the connections\n        this.connections.toArray().forEach((connection: Connection) => {\n            connection.close();\n        });\n    }\n\n    public getService(name: string): Connection {\n        // get the service connection\n        let service = this.connections.get(name);\n        // if the service is not found we throw an error\n        if(service === null)\n            throw new Error(`Service ${name} not found for ${this.name}`);\n        return service;\n    }\n\n    public getServices(): Connection[] {\n        // get all the clients that are services types\n        return this.connections.toArray();\n    }\n\n    public getNode(id: string): Connection {\n        // get the client that is a node type\n        if(this.server === null) throw new Error('Server is not created');\n        let client = this.server.getClient(id);\n        // throw an error if the client is not found\n        if(client === null) throw new Error('Client not found');\n        // return the client\n        return client;\n    }\n\n    public getNodes(): Connection[] {\n        // get all the clients that are nodes types\n        let nodes = this.server?.getClients().\n            filter((conn: Connection) => conn.targetType === 'client');\n        return nodes || [];\n    }\n\n    public getConnections(): Connection[] {\n        // get all the connections\n        return this.connections.toArray().concat(this.server?.getClients() || []);\n    }\n\n    public closeService(name: string) {\n        // close the connection\n        let connection = this.connections.remove(name);\n        if(connection) connection.close();\n        // callback\n        this.serviceDisconnectCallback &&\n            this.serviceDisconnectCallback(connection);\n    }\n\n    public closeConnection(id: string) {\n        // close the connection\n        let connection = this.connections.remove(id);\n        if(connection) connection.close();\n    }\n\n    public registerListeners(listeners: Listener[]) {\n        /* this function registers the listeners to the network and overwrites the old ones */\n        //log(`[Network][RegisterListners][${this.name}]`, listeners);\n        //log(`[Network][RegisterListners][${this.name}] connections:`, this.connections);\n        // store the listeners\n        this.listeners = listeners;\n        // if we have a server created we pass the listeners to it\n        if(this.server) this.server.setListeners(this.listeners);\n        // for every conenction in out pool we register the listeners\n        this.connections.toArray().forEach((connection: Connection) => {\n            connection.setListeners(listeners);\n        });\n    }\n\n\n    public addListeners(listeners: Listener[]) {\n        /* this function adds the listeners to the network */\n        this.listeners = this.listeners.concat(listeners);\n        // if we have a server created we pass the listeners to it\n        if(this.server) this.server.addListeners(listeners);\n        // for every conenction in out pool we register the listeners\n        this.connections.toArray().forEach((connection: Connection) => {\n            connection.addListeners(listeners);\n        });\n\n    }\n\n    public getRegisteredListeners(): any {\n        // get the listeners from the server\n        let server_listeners = this.server?.getListeners() || [];\n        let connections_listeners = this.connections.toArray().map((connection: Connection) => {\n            log('inside loop conenction:', connection);\n            return { id: connection.id, listeners: connection.getListeners() };\n        });\n        // return the listeners\n        return { server: server_listeners, connections: connections_listeners };\n    }\n\n\n    /* callbacks */\n    public onNodeConnection(callback: (connection: Connection) => void) {\n        if(this.server === null) throw new Error('Server is not created');\n        this.server.onConnection(callback);\n    }\n\n    public onNodeDisconnect(callback: (connection: Connection) => void) {\n        if(this.server === null) throw new Error('Server is not created');\n        this.server.onDisconnect(callback);\n    }\n\n    public onServiceConnection(callback: (connection: Connection) => void) {\n        // set the network listners to the connection\n        this.serviceConnectionCallback = callback;\n    }\n\n    public onServiceDisconnect(callback: (connection: Connection) => void) {\n        this.serviceDisconnectCallback = callback;\n    }\n\n    public onNewListeners(callback: (listeners: Listener[]) => void) {\n        this.newListenersCallback = callback;\n    }\n\n}\n\nexport default Network;\n"],"mappings":"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","names":["Connection","Server"]}