@authup/core-realtime-kit
Version:
Package containing a toolkit for the core realtime service.
138 lines (137 loc) • 4.27 kB
JavaScript
import { Manager } from "socket.io-client";
import { isObject } from "@authup/kit";
//#region src/utils/url.ts
function cleanDoubleSlashes(input = "") {
if (input.includes("://")) return input.split("://").map((str) => cleanDoubleSlashes(str)).join("://");
return input.replace(/\/+/g, "/");
}
//#endregion
//#region src/client/manager/utils.ts
function toClientManagerTokenAsyncFn(input) {
if (typeof input === "undefined") return () => void 0;
if (typeof input === "string") return () => input;
return input;
}
function isDisconnectDescription(input) {
return isObject(input) && typeof input.description === "string";
}
//#endregion
//#region src/client/manager/module.ts
var ClientManager = class {
manager;
sockets;
tokenFn;
constructor(ctx) {
this.sockets = /* @__PURE__ */ new Map();
const url = new URL(ctx.url);
const baseURL = `${url.protocol}//${url.host}`;
const options = { ...ctx.options || {} };
if (options.path) {
if (url.pathname.endsWith(options.path)) options.path = url.pathname;
else if (url.pathname !== "/") options.path = cleanDoubleSlashes(url.pathname + options.path);
} else if (url.pathname.endsWith("/socket.io")) options.path = url.pathname;
else if (url.pathname !== "/") options.path = cleanDoubleSlashes(`${url.pathname}/socket.io`);
this.manager = new Manager(baseURL, {
autoConnect: false,
...options
});
this.tokenFn = toClientManagerTokenAsyncFn(ctx.token);
}
get options() {
return this.manager.opts;
}
async connect(namespace = "/") {
const socket = this.inject(namespace);
if (socket.connected) return socket;
return new Promise((resolve, reject) => {
socket.once("connect", () => {
resolve(socket);
});
socket.once("connect_error", (err) => {
reject(err);
});
socket.connect();
});
}
async disconnect(namespace = "/") {
const socket = this.inject(namespace);
if (!socket.connected) return;
await new Promise((resolve, reject) => {
socket.once("disconnect", (reason, description) => {
if (reason === "io client disconnect") {
resolve();
return;
}
if (isDisconnectDescription(description)) {
reject(new Error(description.description));
return;
}
reject(description);
});
socket.disconnect();
});
}
async reconnect(namespace = "/") {
await this.disconnect(namespace);
return new Promise((resolve, reject) => {
setTimeout(() => {
this.connect(namespace).then((socket) => resolve(socket)).catch((err) => reject(err));
});
});
}
async reconnectAll() {
const keys = this.sockets.keys();
const promises = [];
while (true) {
const key = keys.next();
if (key.done) break;
promises.push(this.reconnect(key.value));
}
return Promise.all(promises);
}
inject(namespace = "/") {
let socket = this.sockets.get(namespace);
if (socket) return socket;
socket = this.manager.socket(namespace, { auth: (cb) => {
Promise.resolve().then(() => this.tokenFn()).then((token) => {
cb({ token });
}).catch(() => cb());
} });
this.sockets.set(namespace, socket);
return socket;
}
eject(namespace = "/") {
const socket = this.sockets.get(namespace);
if (socket) {
socket.disconnect();
this.sockets.delete(namespace);
}
}
};
//#endregion
//#region src/event/constants.ts
let EventNameSuffix = /* @__PURE__ */ function(EventNameSuffix) {
EventNameSuffix["CREATED"] = "created";
EventNameSuffix["DELETED"] = "deleted";
EventNameSuffix["UPDATED"] = "updated";
EventNameSuffix["SUBSCRIBE"] = "subscribe";
EventNameSuffix["UNSUBSCRIBE"] = "unsubscribe";
return EventNameSuffix;
}({});
//#endregion
//#region src/event/helpers.ts
function buildEventFullName(entity, event) {
return entity + (event.substring(0, 1).toUpperCase() + event.substring(1));
}
//#endregion
//#region src/helpers.ts
function isEventTarget(input) {
return typeof input === "number" || typeof input === "string" || typeof input === "undefined";
}
function isEventCallback(input, fnArgs) {
if (typeof fnArgs === "undefined") return typeof input === "function";
return typeof input === "function" && input.length >= fnArgs;
}
//#endregion
export { ClientManager, EventNameSuffix, buildEventFullName, isEventCallback, isEventTarget };
//# sourceMappingURL=index.mjs.map