UNPKG

slavery-js

Version:

A simple clustering app that allows you to scale an application on multiple thread, containers or machines

235 lines 7.09 kB
import { __publicField } from "../chunk-V6TY7KAL.js"; import { io } from "socket.io-client"; class Connection { /* * @param Node: Node * @param socket: Socket * @param host: string * @param port: number * @param id: string * @param name: string * */ constructor({ socket, host, port, id, name, listeners, timeout, onConnect, onDisconnect, onSetListeners }) { /* * this class is manager for the socket instance * it takes either a socket or a host and port to create the socket * if it takes the host and port it will consider that connection is a server * if it takes a socket it will consider that connection is a client * * it manages conenction, the listeners and the available emitters */ __publicField(this, "socket"); __publicField(this, "request_id", 0); // this node information __publicField(this, "name"); __publicField(this, "id"); __publicField(this, "listeners", []); __publicField(this, "type"); __publicField(this, "host"); __publicField(this, "port"); // is connected or not __publicField(this, "isConnected"); // ot target of the socket __publicField(this, "socketId"); __publicField(this, "targetType"); __publicField(this, "targetName"); __publicField(this, "targetId"); __publicField(this, "targetListeners", []); __publicField(this, "targetHost"); __publicField(this, "targetPort"); // callbacks __publicField(this, "onConnectCallback"); __publicField(this, "onDisconnectCallback"); __publicField(this, "onSetListenersCallback"); __publicField(this, "send", this.query); this.onConnectCallback = onConnect || (() => { }); this.onDisconnectCallback = onDisconnect || (() => { }); this.onSetListenersCallback = onSetListeners || (() => { }); if (listeners) this.listeners = listeners; if (socket && name) { this.type = "server"; this.name = name; this.targetType = "client"; this.socket = socket; this.targetId = socket.handshake.auth.id; this.isConnected = true; } else if (host && port && id) { this.type = "client"; this.targetType = "server"; this.id = id; this.socket = io(`ws://${host}:${port}`, { auth: { id }, timeout: timeout || 1e3 * 60 // 1 minute }); this.isConnected = false; } else throw new Error("Connection must have either a socket and a name or a host and port"); this.socketId = this.socket.id; this.initilaizeListeners(); } initilaizeListeners() { this.listeners.forEach((l) => { this.socket.removeAllListeners(l.event); this.socket.on(l.event, this.respond(l.event, async (parameters) => { return await l.callback(parameters); })); }); this.socket.on("_listeners", this.respond("_listeners", () => this.getListeners())); this.socket.on("_set_listeners", this.respond("_set_listeners", (listeners) => { this.targetListeners = listeners.map((event) => ({ event, callback: () => { } })); this.onSetListenersCallback(this.targetListeners); return "ok"; })); this.socket.on("_name", this.respond("_name", () => this.name)); this.socket.on("_id", () => this.id); this.socket.on("connect", async () => { this.targetName = await this.queryTargetName(); this.targetListeners = await this.queryTargetListeners(); this.isConnected = true; this.onConnectCallback(this); }); this.socket.on("reconnect", async (attempt) => { this.targetName = await this.queryTargetName(); this.targetListeners = await this.queryTargetListeners(); this.isConnected = true; this.onConnectCallback(this); }); this.socket.on("diconnect", () => { this.isConnected = false; this.onDisconnectCallback(this); }); } async connected() { return new Promise((resolve, reject) => { let interval; let timeout; interval = setInterval(() => { if (this.isConnected) { clearInterval(interval); clearTimeout(timeout); resolve(true); } }, 100); timeout = setTimeout(() => { clearInterval(interval); reject(false); }, 1e3 * 60); }); } getType() { return this.type; } on(event, callback) { this.socket.on(event, callback); } emit(event, data) { this.socket.emit(event, data); } getName() { return this.name; } // this is the id of the conenction? getId() { return this.id; } getTargetName() { return this.targetName; } // this is the id of the target client getTargetId() { return this.targetId; } async setListeners(listeners) { listeners.forEach((l) => { this.listeners.push(l); this.socket.removeAllListeners(l.event); this.socket.on(l.event, this.respond(l.event, async (parameters) => { return await l.callback(parameters); })); }); if (this.type === "server") { await this.query("_set_listeners", listeners.map((listener) => listener.event)); } } addListeners(listeners) { const eventMap = new Map(this.listeners.map((l) => [l.event, l])); listeners.forEach((l) => eventMap.set(l.event, l)); this.listeners = Array.from(eventMap.values()); this.setListeners(this.listeners); } getTargetListeners() { return this.targetListeners; } onSetListeners(callback) { this.onSetListenersCallback = callback; } onConnect(callback) { this.onConnectCallback = callback; } onDisconnect(callback) { this.onDisconnectCallback = callback; } queryTargetListeners() { return this.query("_listeners"); } queryTargetName() { return this.query("_name"); } // this function need to be awaited query(event, data) { return new Promise((resolve, reject) => { let timeout = setTimeout(() => { reject("timeout"); }, 1e3 * 60); let request_id = ++this.request_id; if (this.request_id >= Number.MAX_SAFE_INTEGER - 1) this.request_id = 0; this.socket.emit(event, { data, request_id }); this.socket.on(event + `_${request_id}_response`, (response) => { clearTimeout(timeout); this.socket.removeAllListeners(event + `_${request_id}_response`); resolve(response); }); }); } respond(event, callback) { return async (parameters) => { let data = parameters.data; let request_id = parameters.request_id; let response = await callback(data); this.socket.emit(event + `_${request_id}_response`, response); }; } getListeners() { if (this.type === "server") return this.listeners; else if (this.type === "client") return this.socket._callbacks; else throw new Error("Connection type not recognized"); } close() { this.socket.disconnect(); } } var Connection_default = Connection; export { Connection_default as default }; //# sourceMappingURL=Connection.js.map