constructor(options = {}) {
        // Only accept object as a parameter type for options
        if (options == null || typeof options !== 'object')
            throw new Error(
                'HyperExpress: HyperExpress.Server constructor only accepts an object type for the options parameter.'
            );

        // Initialize extended Router instance
        super();
        super._is_app(true);

        // Store options locally for access throughout processing
        wrap_object(this.#options, options);

        // Expose the options object for future use
        this._options = this.#options;
        try {
            // Create underlying uWebsockets App or SSLApp to power HyperExpress
            const { cert_file_name, key_file_name } = options;
            this.#options.is_ssl = cert_file_name && key_file_name; // cert and key are required for SSL
            if (this.#options.is_ssl) {
                // Convert the certificate and key file names to absolute system paths
                this.#options.cert_file_name = to_forward_slashes(path.resolve(cert_file_name));
                this.#options.key_file_name = to_forward_slashes(path.resolve(key_file_name));

                // Create an SSL app with the provided SSL options
                this.#uws_instance = uWebSockets.SSLApp(this.#options);
            } else {
                // Create a non-SSL app since no SSL options were provided
                this.#uws_instance = uWebSockets.App(this.#options);
            }
        } catch (error) {
            // Convert all the options to string values for logging purposes
            const _options = Object.keys(options)
                .map((key) => `options.${key}: "${options[key]}"`)
                .join('\n');

            // Throw error if uWebsockets.js fails to initialize
            throw new Error(
                `new HyperExpress.Server(): Failed to create new Server instance due to an invalid configuration in options.\n${_options}`
            );
        }

        // Initialize the HostManager for this Server instance
        this.#hosts = new HostManager(this);
    }
@param {Object} options Server Options
@param {String=} options.cert_file_name Path to SSL certificate file to be used for SSL/TLS.
@param {String=} options.key_file_name Path to SSL private key file to be used for SSL/TLS.
@param {String=} options.passphrase Strong passphrase for SSL cryptographic purposes.
@param {String=} options.dh_params_file_name Path to SSL Diffie-Hellman parameters file.
@param {Boolean=} options.ssl_prefer_low_memory_usage Specifies uWebsockets to prefer lower memory usage while serving SSL.
@param {Boolean=} options.fast_buffers Buffer.allocUnsafe is used when set to true for faster performance.
@param {Boolean=} options.fast_abort Determines whether HyperExpress will abrubptly close bad requests. This can be much faster but the client does not receive an HTTP status code as it is a premature connection closure.
@param {Boolean=} options.trust_proxy Specifies whether to trust incoming request data from intermediate proxy(s)
@param {Number=} options.max_body_buffer Maximum body content to buffer in memory before a request data is handled. Behaves similar to `highWaterMark` in Node.js streams.
@param {Number=} options.max_body_length Maximum body content length allowed in bytes. For Reference: 1kb = 1024 bytes and 1mb = 1024kb.
@param {Boolean=} options.auto_close Whether to automatically close the server instance when the process exits. Default: true
@param {Object} options.streaming Global content streaming options.
@param {import('stream').ReadableOptions=} options.streaming.readable Global content streaming options for Readable streams.
@param {import('stream').WritableOptions=} options.streaming.writable Global content streaming options for Writable streams.