UNPKG

ufiber

Version:

Next-gen webserver for node-js developer

128 lines (126 loc) 4.02 kB
const require_rolldown_runtime = require('./_virtual/rolldown_runtime.cjs'); const require_tools = require('./utils/tools.cjs'); const require_consts = require('./consts.cjs'); const require_context = require('./http/context.cjs'); require('./http/index.cjs'); const require_compose = require('./router/compose.cjs'); const require_index$1 = require('./router/index.cjs'); let uws = require("../uws"); uws = require_rolldown_runtime.__toESM(uws); let node_path = require("node:path"); node_path = require_rolldown_runtime.__toESM(node_path); //#region src/ufiber.ts /** * The Fiber class extends the functionality of the Router class. * It sets up routing and allows for custom options to be passed. */ var Fiber = class extends require_index$1.Router { uws; #name; isSSL; #methods; bodyLimit; /** * Creates an instance of the Fiber class. * * @param options - Optional configuration options for the Fiber instance. */ constructor(options = Object.create(null)) { super(); this.#name = options.name || "Fiber"; this.#methods = options.methods; this.bodyLimit = require_tools.parseBytes(options.bodyLimit || "16MB"); const opts = options.uwsOptions ?? {}; if (opts.key_file_name && opts.cert_file_name) { this.uws = uws.default.SSLApp(opts); this.isSSL = true; } else { this.uws = uws.default.App(opts); this.isSSL = false; } } /** * Add WebSocket support * * @param pattern - URL pattern for WebSocket endpoint * @param behavior - WebSocket behavior configuration * @returns this for chaining * * @example * ```ts * app.ws('/chat', { * message: (ws, message, opCode) => { * ws.send(message); * }, * open: (ws) => { * console.log('WebSocket connected'); * } * }); * ``` */ ws(pattern, behavior) { this.uws.ws(pattern, behavior); return this; } #dispatch = (res, req) => { const ctx = new require_context.Context({ req, res, isSSL: this.isSSL, appName: this.#name, bodyLimit: this.bodyLimit, methods: this.#methods }); const matchResult = this.router.match(ctx.method === "HEAD" ? "GET" : ctx.method, ctx.path); ctx[require_consts.kMatch] = matchResult; if (!matchResult) return this[require_index$1.kNotFound](ctx); if (matchResult[0].length === 1) { try { const result$1 = matchResult[0][0][0][0](ctx, async () => await this[require_index$1.kNotFound](ctx)); if (require_tools.isPromise(result$1)) result$1.catch((err) => this[require_index$1.kErrorHandler](err, ctx)); } catch (err) { this[require_index$1.kErrorHandler](err, ctx); } return; } const result = require_compose.compose(matchResult[0], { onError: this[require_index$1.kErrorHandler], onNotFound: this[require_index$1.kNotFound] })(ctx); if (require_tools.isPromise(result)) result.catch((err) => this[require_index$1.kErrorHandler](err, ctx)); }; listen(...args) { this.uws.any("/*", this.#dispatch); let port = 0; let host; let cb; if (typeof args[0] === "function") cb = args[0]; else if (typeof args[1] === "function") { port = args[0]; cb = args[1]; } else [port, host, cb] = args; const onListen = (socket) => { if (!socket) throw new Error(`Failed to listen on ${port}. No permission or address in use.`); let address; if (typeof port === "string" && isNaN(Number(port))) { const normalizedPath = port.startsWith("/") || port.startsWith("./") ? port : `./${port}`; address = node_path.default.resolve(normalizedPath); } else address = `${this.isSSL ? "https" : "http"}://${host ?? "0.0.0.0"}:${port}`; cb?.(address); }; if (typeof port === "string" && isNaN(Number(port))) this.uws.listen_unix(onListen, port); else { const numericPort = Number(port); if (host) this.uws.listen(host, numericPort, onListen); else this.uws.listen(numericPort, onListen); } const shutdown = () => { this.uws.close(); process.exit(0); }; process.on("SIGINT", shutdown); process.on("SIGTERM", shutdown); } }; //#endregion exports.Fiber = Fiber;