rjweb-server
Version:
Easy and Robust Way to create a Web Server with Many Easy-to-use Features in NodeJS
201 lines (200 loc) • 7.68 kB
JavaScript
;
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 __export = (target, all) => {
for (var name in all)
__defProp(target, name, { get: all[name], enumerable: true });
};
var __copyProps = (to, from, except, desc) => {
if (from && typeof from === "object" || typeof from === "function") {
for (let key of __getOwnPropNames(from))
if (!__hasOwnProp.call(to, key) && key !== except)
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
}
return to;
};
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
// If the importer is in node compatibility mode or this is not an ESM
// file that has been converted to a CommonJS file using a Babel-
// compatible transform (i.e. "__esModule" has not been set), then set
// "default" to the CommonJS "module.exports" for node compatibility.
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
mod
));
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
var handleDashboard_exports = {};
__export(handleDashboard_exports, {
dashboardIndexRoute: () => dashboardIndexRoute,
dashboardWsRoute: () => dashboardWsRoute,
default: () => statsRoute
});
module.exports = __toCommonJS(handleDashboard_exports);
var import_parseURL = __toESM(require("../parseURL"));
var import_rjutils_collection = require("rjutils-collection");
var import_dataStat = require("../../classes/dataStat");
var import_path = __toESM(require("../../classes/path"));
var import_stream = require("stream");
var import__ = require("../../index");
var import_promises = __toESM(require("fs/promises"));
var import_os = __toESM(require("os"));
const dashboardIndexRoute = (ctg) => ({
type: "http",
method: "GET",
path: new import_path.default("GET", "/"),
onRequest: async (ctr) => await statsRoute(ctr, ctg, "http"),
data: {
validations: [],
headers: {}
},
context: { data: {}, keep: true }
});
const dashboardWsRoute = (ctg) => ({
type: "websocket",
path: new import_path.default("GET", "/"),
onConnect: async (ctr) => await statsRoute(ctr, ctg, "socket"),
data: {
validations: [],
headers: {}
},
context: { data: {}, keep: true }
});
const hashCode = (value) => {
return value.split("").reduce((a, b) => {
a = (a << 5) - a + b.charCodeAt(0);
return a & a;
}, 0).toString(16).replace("-", "M");
};
const runStats = async (ctg) => {
const date = /* @__PURE__ */ new Date();
const startTime = date.getTime();
const startUsage = process.cpuUsage();
const previousHours = (0, import_dataStat.getPreviousHours)();
const staticFiles = await new Promise(async (resolve) => {
let staticFiles2 = 0;
for (let staticNumber = 0; staticNumber < ctg.routes.static.length; staticNumber++) {
staticFiles2 += (await (0, import_rjutils_collection.getFilesRecursively)(ctg.routes.static[staticNumber].location, true)).length;
}
resolve(staticFiles2);
});
const cpuUsage = await new Promise((resolve) => setTimeout(() => {
const currentUsage = process.cpuUsage(startUsage);
const currentTime = (/* @__PURE__ */ new Date()).getTime();
const timeDelta = (currentTime - startTime) * 5 * coreCount;
resolve((currentUsage.system + currentUsage.user) / timeDelta);
}, 500));
return {
requests: {
total: ctg.requests.stats.total,
perSecond: ctg.requests.stats.perSecond,
hours: Array.from({ length: 5 }, (value, index) => ({
hour: previousHours[index],
amount: ctg.requests.stats[previousHours[index]]
}))
},
webSockets: {
opened: {
total: ctg.webSockets.opened.stats.total,
perSecond: ctg.webSockets.opened.stats.perSecond,
hours: Array.from({ length: 5 }, (value, index) => ({
hour: previousHours[index],
amount: ctg.webSockets.opened.stats[previousHours[index]]
}))
},
messages: {
incoming: {
total: ctg.webSockets.messages.incoming.stats.total,
perSecond: ctg.webSockets.messages.incoming.stats.perSecond,
hours: Array.from({ length: 5 }, (value, index) => ({
hour: previousHours[index],
amount: ctg.webSockets.messages.incoming.stats[previousHours[index]]
}))
},
outgoing: {
total: ctg.webSockets.messages.outgoing.stats.total,
perSecond: ctg.webSockets.messages.outgoing.stats.perSecond,
hours: Array.from({ length: 5 }, (value, index) => ({
hour: previousHours[index],
amount: ctg.webSockets.messages.outgoing.stats[previousHours[index]]
}))
}
}
},
data: {
incoming: {
total: ctg.data.incoming.stats.total,
perSecond: ctg.data.incoming.stats.perSecond,
hours: Array.from({ length: 5 }, (value, index) => ({
hour: previousHours[index],
amount: ctg.data.incoming.stats[previousHours[index]]
}))
},
outgoing: {
total: ctg.data.outgoing.stats.total,
perSecond: ctg.data.outgoing.stats.perSecond,
hours: Array.from({ length: 5 }, (value, index) => ({
hour: previousHours[index],
amount: ctg.data.outgoing.stats[previousHours[index]]
}))
}
},
cpu: {
time: `${date.getHours()}:${date.getMinutes()}:${date.getSeconds()}`,
usage: cpuUsage.toFixed(2)
},
memory: {
time: `${date.getHours()}:${date.getMinutes()}:${date.getSeconds()}`,
usage: process.memoryUsage().heapUsed + process.memoryUsage().external
},
routes: {
user: ctg.routes.normal.length + ctg.routes.websocket.length,
automatic: ctg.routes.htmlBuilder.length
},
staticFiles,
internalLogs: ctg.logger["logs"],
middlewares: ctg.middlewares.length,
cached: ctg.cache.files.objectCount + ctg.cache.middlewares.objectCount + ctg.cache.routes.objectCount
};
};
const coreCount = import_os.default.cpus().length;
async function statsRoute(ctr, ctg, type) {
switch (type) {
case "http": {
if (ctr.type !== "http")
return;
const dashboard = (await import_promises.default.readFile(`${__dirname}/dashboard.html`, "utf8")).replaceAll("/rjweb-dashboard", (0, import_parseURL.default)(ctg.options.dashboard.path).path).replace("1.1.1", import__.Version);
ctr.headers.set("content-type", "text/html");
return ctr.print(dashboard);
}
case "socket": {
if (ctr.type !== "connect")
return;
if (ctg.options.dashboard.password && ctr.queries.get("password") !== hashCode(ctg.options.dashboard.password))
return ctr.close(1, {
error: "password"
});
let interval = null;
ctr.printStream((() => {
const readable = new import_stream.Readable({
objectMode: true,
read() {
},
destroy() {
clearInterval(interval);
}
});
interval = setInterval(() => readable.push(runStats(ctg)), ctg.options.dashboard.updateInterval);
setImmediate(() => readable.push(runStats(ctg)));
return readable;
})());
}
}
}
// Annotate the CommonJS export names for ESM import in node:
0 && (module.exports = {
dashboardIndexRoute,
dashboardWsRoute
});