var __create = Object.create; var __defProp = Object.defineProperty; var __getOwnPropDesc = Object.getOwnPropertyDescriptor; var __getOwnPropNames = Object.getOwnPropertyNames; var __getProtoOf = Object.getPrototypeOf; var __hasOwnProp = Object.prototype.hasOwnProperty; var __markAsModule = (target) => __defProp(target, "__esModule", { value: true }); var __export = (target, all) => { for (var name in all) __defProp(target, name, { get: all[name], enumerable: true }); }; var __reExport = (target, module2, copyDefault, desc) => { if (module2 && typeof module2 === "object" || typeof module2 === "function") { for (let key of __getOwnPropNames(module2)) if (!__hasOwnProp.call(target, key) && (copyDefault || key !== "default")) __defProp(target, key, { get: () => module2[key], enumerable: !(desc = __getOwnPropDesc(module2, key)) || desc.enumerable }); } return target; }; var __toESM = (module2, isNodeMode) => { return __reExport(__markAsModule(__defProp(module2 != null ? __create(__getProtoOf(module2)) : {}, "default", !isNodeMode && module2 && module2.__esModule ? { get: () => module2.default, enumerable: true } : { value: module2, enumerable: true })), module2); }; var __toCommonJS = /* @__PURE__ */ ((cache) => { return (module2, temp) => { return cache && cache.get(module2) || (temp = __reExport(__markAsModule({}), module2, 1), cache && cache.set(module2, temp), temp); }; })(typeof WeakMap !== "undefined" ? /* @__PURE__ */ new WeakMap() : 0); // packages/sockets-client/src/Main.ts var Main_exports = {}; __export(Main_exports, { RouterSendErrors: () => ISendErrors_default, StartErrors: () => IStartErrors_default, StopErrors: () => IStopErrors_default, default: () => Main_default }); var import_events2 = __toESM(require("events"), 1); var import_merge_deep = __toESM(require("merge-deep"), 1); // packages/sockets-client/src/router/ISendErrors.ts var ISendErrors = /* @__PURE__ */ ((ISendErrors2) => { ISendErrors2["notAlive"] = "ENotAlive"; return ISendErrors2; })(ISendErrors || {}); var ISendErrors_default = ISendErrors; // packages/sockets-client/src/IState.ts var IState = /* @__PURE__ */ ((IState2) => { IState2[IState2["dead"] = 0] = "dead"; IState2[IState2["connecting"] = 1] = "connecting"; IState2[IState2["connected"] = 2] = "connected"; IState2[IState2["stopping"] = 3] = "stopping"; return IState2; })(IState || {}); var IState_default = IState; // packages/sockets-client/src/IStartErrors.ts var IStartErrors = /* @__PURE__ */ ((IStartErrors2) => { IStartErrors2["failedToConnect"] = "EFailedToConnect"; IStartErrors2["alreadyStarting"] = "EAlreadyStarting"; IStartErrors2["currentlyClosing"] = "ECurrentlyClosing"; IStartErrors2["alreadyConnected"] = "EAlreadyConnected"; return IStartErrors2; })(IStartErrors || {}); var IStartErrors_default = IStartErrors; // packages/sockets-client/src/IStopErrors.ts var IStopErrors = /* @__PURE__ */ ((IStopErrors2) => { IStopErrors2["notConnected"] = "ENotConnected"; IStopErrors2["alreadyStopping"] = "EAlreadyStopping"; IStopErrors2["currentlyStarting"] = "ECurrentlyStarting"; return IStopErrors2; })(IStopErrors || {}); var IStopErrors_default = IStopErrors; // packages/sockets-client/src/router/IChannel.ts var import_events = __toESM(require("events"), 1); var import_bson = require("bson"); var IChannel = class extends import_events.default { #name; #settings; #alive; #ws; constructor(name, ws, settings) { super(); this.#name = name; this.#settings = settings; this.#alive = !ws.internalSocketHost?.CLOSED; this.#ws = ws; ws.on("close", () => { this.#alive = false; }); ws.on("message-unprocessed", async (message) => { let finalOut; if (typeof message === "string") { try { finalOut = JSON.parse(message); } catch { return; } } else { try { if (typeof message.arrayBuffer !== "undefined") { finalOut = (0, import_bson.deserialize)(message.arrayBuffer()); } else { finalOut = (0, import_bson.deserialize)(message); } } catch { return; } } if (typeof finalOut.body !== "object" || Array.isArray(finalOut.body) || typeof finalOut.channel !== "string") { return; } if (this.#name === finalOut.channel) { this.emit("message", finalOut.body); } }); } async send(message) { if (!this.#alive) { const error = new Error("The connection is not alive"); error.name = ISendErrors_default.notAlive; throw error; } let serialized; const fullMessage = { channel: this.#name, body: message }; if (this.#settings.data.send.useBSON) { const replaceBinary = (obj) => { const newObj = obj; if (newObj instanceof Buffer || newObj.data?.buffer instanceof ArrayBuffer) { return new import_bson.Binary([...newObj.data]); } Object.keys(newObj).forEach((key) => { if (typeof newObj[key] === "object") { newObj[key] = replaceBinary(newObj[key]); } }); return newObj; }; serialized = (0, import_bson.serialize)(replaceBinary(fullMessage)); } else { serialized = JSON.stringify(fullMessage); } this.#ws.internalSocketHost?.send(serialized); } }; var IChannel_default = IChannel; // packages/sockets-client/src/router/IRouter.ts var IRouter = class { #ws; #settings; constructor(ws, settings) { this.#ws = ws; this.#settings = settings; } channel(name) { return new IChannel_default(name, this.#ws, this.#settings); } }; // packages/sockets-client/src/Main.ts var defaultSettings = { port: 5e3, host: "0.0.0.0", ssl: false, data: { send: { useBSON: true } } }; var SocketsClient = class extends import_events2.default { #settings; #ws; #state = IState_default.dead; #router; constructor(settings = {}) { super(); this.#settings = (0, import_merge_deep.default)(defaultSettings, settings); this.#router = new IRouter(this, this.#settings); } async start() { if (this.#state === IState_default.stopping) { const error = new Error("The socket client is currently stopping"); error.name = IStartErrors_default.currentlyClosing; throw error; } if (this.#state === IState_default.connecting) { const error = new Error("The client is already starting"); error.name = IStartErrors_default.alreadyStarting; throw error; } if (this.#state === IState_default.connected) { const error = new Error("The client is already connected"); error.name = IStartErrors_default.alreadyConnected; throw error; } this.#state = IState_default.connecting; const connectAddress = `${this.#settings.ssl ? "wss" : "ws"}://${this.#settings.host}:${this.#settings.port}`; const isNodeEnv = typeof WebSocket === "undefined"; const WebSocketClient = isNodeEnv ? (await import("websocket")).default.w3cwebsocket : WebSocket; const ws = new WebSocketClient(connectAddress); const wsOnOpen = () => new Promise((resolve, reject) => { ws.onclose = () => { this.emit("close"); }; ws.onopen = () => { resolve(); }; ws.onmessage = (msg) => { this.emit("message-unprocessed", msg.data); }; ws.onerror = () => { reject(); }; }); try { await wsOnOpen(); this.#state = IState_default.connected; this.#ws = ws; this.emit("ready"); } catch { this.#state = IState_default.dead; const error = new Error("Failed to connect to the server"); error.name = IStartErrors_default.failedToConnect; throw error; } } async stop() { if (this.#state === IState_default.dead) { const error = new Error("The client is already dead"); error.name = IStopErrors_default.alreadyStopping; throw error; } if (this.#state === IState_default.connecting) { const error = new Error("The client is already connecting"); error.name = IStopErrors_default.currentlyStarting; throw error; } if (this.#state === IState_default.stopping) { const error = new Error("The client is already stopping"); error.name = IStopErrors_default.alreadyStopping; throw error; } this.#state = IState_default.stopping; this.#ws?.close(); this.#state = IState_default.dead; } get router() { return this.#router; } get internalSocketHost() { return this.#ws; } }; var Main_default = SocketsClient; module.exports = __toCommonJS(Main_exports); // Annotate the CommonJS export names for ESM import in node: 0 && (module.exports = { RouterSendErrors, StartErrors, StopErrors });