UNPKG

outers

Version:

outers - a all in one package for your day to day use

285 lines 20.7 kB
"use strict"; var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } return new (P || (P = Promise))(function (resolve, reject) { function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } step((generator = generator.apply(thisArg, _arguments || [])).next()); }); }; var __classPrivateFieldSet = (this && this.__classPrivateFieldSet) || function (receiver, state, value, kind, f) { if (kind === "m") throw new TypeError("Private method is not writable"); if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a setter"); if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot write private member to an object whose class did not declare it"); return (kind === "a" ? f.call(receiver, value) : f ? f.value = value : state.set(receiver, value)), value; }; var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (receiver, state, kind, f) { if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a getter"); if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot read private member from an object whose class did not declare it"); return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver); }; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; var _CreateClusterByClass_ExpressServer, _CreateClusterByClass_PORT, _CreateClusterByClass_NumberOfWorkers, _CreateClusterByClass_BeforeListenFunctions, _CreateClusterByClass_AfterListenFunctions, _CreateClusterByClass_FunctionMiddlewares, _CreateClusterByClass_GlobalResponseObject, _CreateClusterByClass_EnableTrustProxy; Object.defineProperty(exports, "__esModule", { value: true }); /* eslint-disable @typescript-eslint/ban-types */ /* eslint-disable @typescript-eslint/no-explicit-any */ // main code for creating a cluster in node js const node_os_1 = require("node:os"); // Import os module const express_1 = __importDefault(require("express")); // Import express module const node_cluster_1 = __importDefault(require("node:cluster")); // Import Cluster module const { isPrimary } = node_cluster_1.default; // Import isPrimary from Cluster const Console_log_1 = require("../../Logs/Console.log"); // Import Console module // Main Class class CreateClusterByClass { // Constructor /** * Creates an instance of the server configuration class. * This constructor initializes the server with the specified Express server, port, * and optional configurations for workers, middleware, and pre/post listen functions. * * @param {Express} ExpressServer - The Express server instance. If not provided, a new Express instance is created. * @param {number} PORT - The port number on which the Express server will listen. * @param {number} [NumberOfWorkers=cpus().length] - Optional. The number of worker processes to spawn in cluster mode. * Defaults to the number of CPU cores available. * @param {Function[]} [BeforeListenFunctions=[]] - Optional. An array of functions to execute before the server starts listening. * @param {Function[]} [AfterListenFunctions=[]] - Optional. An array of functions to execute after the server starts listening. * @param {Function[]} [FunctionMiddlewares=[]] - Optional. An array of middleware functions to apply to the Express server. */ constructor(ExpressServer, PORT, NumberOfWorkers, BeforeListenFunctions, AfterListenFunctions, FunctionMiddlewares, EnableTrustProxy) { // Properties _CreateClusterByClass_ExpressServer.set(this, void 0); // Express Server Instance _CreateClusterByClass_PORT.set(this, void 0); // Port Number to Listen // Private Properties _CreateClusterByClass_NumberOfWorkers.set(this, void 0); // Number of Copies of Workers _CreateClusterByClass_BeforeListenFunctions.set(this, void 0); // Any Functions to run before listen _CreateClusterByClass_AfterListenFunctions.set(this, void 0); // Any Functions to run after listen _CreateClusterByClass_FunctionMiddlewares.set(this, void 0); // Any Middlewares to apply _CreateClusterByClass_GlobalResponseObject.set(this, void 0); // Any ResponseObject _CreateClusterByClass_EnableTrustProxy.set(this, void 0); // Enable Trust Proxy __classPrivateFieldSet(this, _CreateClusterByClass_ExpressServer, ExpressServer !== null && ExpressServer !== void 0 ? ExpressServer : (0, express_1.default)(), "f"); // Express Server Instance __classPrivateFieldSet(this, _CreateClusterByClass_PORT, PORT, "f"); // Active Server Instance __classPrivateFieldSet(this, _CreateClusterByClass_NumberOfWorkers, NumberOfWorkers !== null && NumberOfWorkers !== void 0 ? NumberOfWorkers : (0, node_os_1.cpus)().length, "f"); // Number of Copies of Workers __classPrivateFieldSet(this, _CreateClusterByClass_BeforeListenFunctions, BeforeListenFunctions !== null && BeforeListenFunctions !== void 0 ? BeforeListenFunctions : [], "f"); // Any Functions to run before listen __classPrivateFieldSet(this, _CreateClusterByClass_AfterListenFunctions, AfterListenFunctions !== null && AfterListenFunctions !== void 0 ? AfterListenFunctions : [], "f"); // Any Functions to run after listen __classPrivateFieldSet(this, _CreateClusterByClass_FunctionMiddlewares, FunctionMiddlewares !== null && FunctionMiddlewares !== void 0 ? FunctionMiddlewares : [], "f"); // Any Middlewares to apply __classPrivateFieldSet(this, _CreateClusterByClass_GlobalResponseObject, { ActiveServer: __classPrivateFieldGet(this, _CreateClusterByClass_ExpressServer, "f"), ActiveWorker: __classPrivateFieldGet(this, _CreateClusterByClass_NumberOfWorkers, "f"), TotalBeforeFunctions: __classPrivateFieldGet(this, _CreateClusterByClass_BeforeListenFunctions, "f").length, TotalAfterFunctions: __classPrivateFieldGet(this, _CreateClusterByClass_AfterListenFunctions, "f").length, ActiveMiddlewares: __classPrivateFieldGet(this, _CreateClusterByClass_FunctionMiddlewares, "f"), TotalCPU: (0, node_os_1.cpus)().length, TotalFreeRam: `${((0, node_os_1.freemem)() / 1024 / 1024 / 1024).toFixed(2)} GB`, TotalRam: `${((0, node_os_1.totalmem)() / 1024 / 1024 / 1024).toFixed(2)} GB`, Architecture: (0, node_os_1.arch)(), Platform: (0, node_os_1.platform)(), }, "f"); __classPrivateFieldSet(this, _CreateClusterByClass_EnableTrustProxy, EnableTrustProxy !== null && EnableTrustProxy !== void 0 ? EnableTrustProxy : false, "f"); // Enable Trust Proxy } // Start Server Method /** * Starts the server using the configured Express instance and port. It initializes * workers based on the number of workers specified if running in a cluster mode. * This method also applies any configured middlewares and executes before and after * listen functions as part of the server startup process. * * @returns {Promise<ResponseObject | undefined>} A promise that resolves to a ResponseObject * containing the server and active worker information if the server starts successfully, or * undefined if an error occurs. * @throws {Error} Throws an error if the Express server instance or port is not provided. * * The method leverages clustering if `isPrimary` is true, creating workers and managing * their lifecycle. For the worker processes, or when `isPrimary` is false, it applies * middlewares, runs before listen functions, starts the Express server, and then runs * after listen functions. * * Note: `Console` is used for logging, and `ClusterConfig`, `platform`, `arch`, `freemem`, * `cpus` are assumed to be available in the scope for cluster and system information logging. */ StartServer() { return __awaiter(this, void 0, void 0, function* () { // Check if User Provided Express Server or not if (!__classPrivateFieldGet(this, _CreateClusterByClass_ExpressServer, "f") || !__classPrivateFieldGet(this, _CreateClusterByClass_ExpressServer, "f") === undefined) { throw new Error("Express Server is not provided"); // Error Message for Server Start } // Check if User Provided Port or not if (!__classPrivateFieldGet(this, _CreateClusterByClass_PORT, "f") || __classPrivateFieldGet(this, _CreateClusterByClass_PORT, "f") === undefined) { throw new Error("Port is not provided"); // Error Message for Server Start } // Number of Workers to be forked let ProcessCopy = __classPrivateFieldGet(this, _CreateClusterByClass_NumberOfWorkers, "f"); // Copy Number of Workers if (isPrimary) { // If the cluster is the primary node // Print CPU Count (0, Console_log_1.bright)(`${(0, node_os_1.platform)()} ${(0, node_os_1.arch)()} server : ${((0, node_os_1.freemem)() / 1024 / 1024 / 1024).toFixed(2)} GB Free Ram : ${(0, node_os_1.cpus)()[0].model}`); // Create a worker according to the number that is specified while (ProcessCopy > 0) { node_cluster_1.default.fork(); ProcessCopy--; } // Listen for Cluster Online node_cluster_1.default.on("online", (worker) => { (0, Console_log_1.green)(`🚀 Worker ${worker.process.pid} started 🚀`); (0, Console_log_1.blue)(`Environment Variables Loaded Successfully in Worker : ${worker.process.pid}`); __classPrivateFieldGet(this, _CreateClusterByClass_GlobalResponseObject, "f").ActiveWorker++; // Increment Active Worker Count by 1 (0, Console_log_1.yellow)(`Worker ${worker.process.pid} is listening`); }); // Listen for Cluster Exit node_cluster_1.default.on("exit", (worker) => { (0, Console_log_1.red)(`Worker ${worker.process.pid} died`); __classPrivateFieldGet(this, _CreateClusterByClass_GlobalResponseObject, "f").ActiveWorker++; // Increment Active Worker Count by 1 node_cluster_1.default.fork(); (0, Console_log_1.green)(`🚀 Worker ${worker.process.pid} restarted 🚀`); (0, Console_log_1.blue)(`Environment Variables Loaded Successfully in Worker : ${worker.process.pid}`); __classPrivateFieldGet(this, _CreateClusterByClass_GlobalResponseObject, "f").ActiveWorker++; // Increment Active Worker Count by 1 (0, Console_log_1.yellow)(`Worker ${worker.process.pid} is listening`); }); } else { // Enable trust proxy for Express Server __classPrivateFieldGet(this, _CreateClusterByClass_EnableTrustProxy, "f") === true ? __classPrivateFieldGet(this, _CreateClusterByClass_ExpressServer, "f").set("trust proxy", true) : (0, Console_log_1.yellow)("Trust Proxy is not enabled, if you are working behind a proxy, please enable it to get the real IP Address"); // Apply Function Middlewares to Express Server Instance like CORS, Body Parser, etc. if (__classPrivateFieldGet(this, _CreateClusterByClass_FunctionMiddlewares, "f").length > 0 || __classPrivateFieldGet(this, _CreateClusterByClass_FunctionMiddlewares, "f") !== undefined) { __classPrivateFieldGet(this, _CreateClusterByClass_FunctionMiddlewares, "f").forEach((FunctionMiddleware) => { __classPrivateFieldGet(this, _CreateClusterByClass_ExpressServer, "f").use(FunctionMiddleware); // Apply Middleware to Express Server Instance one by one }); // Apply Middlewares to Express Server Instance } // Run Before Listen Functions if (__classPrivateFieldGet(this, _CreateClusterByClass_BeforeListenFunctions, "f").length > 0 || __classPrivateFieldGet(this, _CreateClusterByClass_BeforeListenFunctions, "f") !== undefined) { for (const ListenFunction of __classPrivateFieldGet(this, _CreateClusterByClass_BeforeListenFunctions, "f")) { yield ListenFunction(); // Run Before Listen Functions one by one } } // Server Listen try { const ActiveServer = __classPrivateFieldGet(this, _CreateClusterByClass_ExpressServer, "f").listen(__classPrivateFieldGet(this, _CreateClusterByClass_PORT, "f"), () => __awaiter(this, void 0, void 0, function* () { (0, Console_log_1.green)(`🚀 Server is listening on Port ${__classPrivateFieldGet(this, _CreateClusterByClass_PORT, "f")} 🚀`); // Print Message for Server Start // Run After Listen Functions if (__classPrivateFieldGet(this, _CreateClusterByClass_AfterListenFunctions, "f").length > 0 || __classPrivateFieldGet(this, _CreateClusterByClass_AfterListenFunctions, "f") !== undefined) { for (const ListenFunction of __classPrivateFieldGet(this, _CreateClusterByClass_AfterListenFunctions, "f")) { yield ListenFunction(); // Run Function one by one } } })); // Start Server on Port // Return the Active Server Instance in Response Object __classPrivateFieldGet(this, _CreateClusterByClass_GlobalResponseObject, "f").ActiveServer = ActiveServer; // Active Server Instance After Listen return Object.freeze(__classPrivateFieldGet(this, _CreateClusterByClass_GlobalResponseObject, "f")); // Return Response Object to User for further use } catch (error) { (0, Console_log_1.red)(`Error in Starting Server : ${error}`); // Print Error Message for Server Start return Object.freeze(Object.assign({ Error: error }, __classPrivateFieldGet(this, _CreateClusterByClass_GlobalResponseObject, "f"))); // Return Error to User } } }); } // Set Number of Workers Method /** * Sets the number of worker processes to be used in cluster mode. * This method updates the instance's number of workers with the provided value, * ensuring that it is a positive number. * * @param {number} NumberOfWorkers - The new number of worker processes to be set. * Must be a positive integer. * @throws {Error} Throws an error if `NumberOfWorkers` is not provided, * is not a number, or is less than or equal to zero. */ SetNumberOfWorkers(NumberOfWorkers) { if (!NumberOfWorkers) { throw new Error("Number of Workers is not provided"); // Error Message for Server Start } if (typeof NumberOfWorkers !== "number") { throw new Error("Number of Workers is not a Number"); // Error Message for Server Start } if (NumberOfWorkers <= 0) { throw new Error("Number of Workers is not a Positive Number"); // Error Message for Server Start } // Update Number of Workers __classPrivateFieldSet(this, _CreateClusterByClass_NumberOfWorkers, NumberOfWorkers, "f"); // Set Number of Workers } // Add Before Listen Function Method /** * Adds a function to be executed before the server starts listening. * This method appends the provided function to the list of functions to run * before the server starts listening for incoming requests. * * @param {Function} FunctionToRun - The function to be added to the list of functions to run. * @throws {Error} Throws an error if `FunctionToRun` is not provided or is not a function. */ AddBeforeListenFunction(FunctionToRun) { if (!FunctionToRun) { throw new Error("Function to Run is not provided"); // Error Message for Server Start } if (typeof FunctionToRun !== "function") { throw new Error("Function to Run is not a Function"); // Error Message for Server Start } __classPrivateFieldGet(this, _CreateClusterByClass_BeforeListenFunctions, "f").push(FunctionToRun); // Add Function to Before Listen Functions } // Add After Listen Function Method /** * Adds a function to be executed after the server starts listening. * This method appends the provided function to the list of functions to run * after the server starts listening for incoming requests. * * @param {Function} FunctionToRun - The function to be added to the list of functions to run. * @throws {Error} Throws an error if `FunctionToRun` is not provided or is not a function. */ AddAfterListenFunction(FunctionToRun) { if (!FunctionToRun) { throw new Error("Function to Run is not provided"); // Error Message for Server Start } if (typeof FunctionToRun !== "function") { throw new Error("Function to Run is not a Function"); // Error Message for Server Start } __classPrivateFieldGet(this, _CreateClusterByClass_AfterListenFunctions, "f").push(FunctionToRun); // Add Function to After Listen Functions } // Add Function Middleware Method /** * Adds a middleware function to the list of middleware functions to be applied * to the Express server instance. * * @param {Function} FunctionToRun - The function to be added to the list of middleware functions to run. * @throws {Error} Throws an error if `FunctionToRun` is not provided or is not a function. */ AddFunctionMiddleware(FunctionToRun) { if (!FunctionToRun) { throw new Error("Function to Run is not provided"); // Error Message for Server Start } if (typeof FunctionToRun !== "function") { throw new Error("Function to Run is not a Function"); // Error Message for Server Start } __classPrivateFieldGet(this, _CreateClusterByClass_FunctionMiddlewares, "f").push(FunctionToRun); // Add Function to Function Middlewares } // Enable Trust Proxy Method /** * Controls the Trust Proxy setting. * @param {boolean} Status - The value indicating whether to enable or disable Trust Proxy. * @throws {Error} If Trust Proxy is already enabled. * @throws {Error} If the provided value is not a boolean. */ ControlTrustProxy(Status) { // Check if Trust Proxy is already enabled or not if (__classPrivateFieldGet(this, _CreateClusterByClass_EnableTrustProxy, "f") === true) { throw new Error("Trust Proxy is already enabled"); // Error Message for Server Start } // Check inserted value is boolean or not if (typeof Status !== "boolean") { throw new Error("TPlease provide a boolean value to enable Trust Proxy"); // Error Message for Server Start } // Enable Trust Proxy __classPrivateFieldSet(this, _CreateClusterByClass_EnableTrustProxy, Status, "f"); // Enable Trust Proxy } } _CreateClusterByClass_ExpressServer = new WeakMap(), _CreateClusterByClass_PORT = new WeakMap(), _CreateClusterByClass_NumberOfWorkers = new WeakMap(), _CreateClusterByClass_BeforeListenFunctions = new WeakMap(), _CreateClusterByClass_AfterListenFunctions = new WeakMap(), _CreateClusterByClass_FunctionMiddlewares = new WeakMap(), _CreateClusterByClass_GlobalResponseObject = new WeakMap(), _CreateClusterByClass_EnableTrustProxy = new WeakMap(); exports.default = CreateClusterByClass; //# sourceMappingURL=CreateClusterByClass.method.js.map