UNPKG

rjweb-server

Version:

Easy and Robust Way to create a Web Server with Many Easy-to-use Features in NodeJS

240 lines (239 loc) 7.42 kB
"use strict"; 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 WsConnect_exports = {}; __export(WsConnect_exports, { default: () => WSConnect }); module.exports = __toCommonJS(WsConnect_exports); var import_Base = __toESM(require("./Base")); var import_parseContent = __toESM(require("../../functions/parseContent")); class WSConnect extends import_Base.default { /** * Initializes a new Instance of a Web Context * @since 7.0.0 */ constructor(controller, localContext, ws) { super(controller, localContext); /** * The Type of this Request * @since 5.7.0 */ this.type = "connect"; this.rawWs = ws; } /** * Close the Socket and send a Code + Message to the Client (automatically Formatted) * * This will instantly close the socket connection with a status code and * message of choice, after calling and successfully closing the `.onClose()` * callback will be called to finish the task. * @example * ``` * ctr.close(401, { * message: 'this is json!' * }) * * // or * * ctr.close(401, 'this is text!') * ``` * @since 5.4.0 */ close(code, message) { this.ctx.continueSend = false; { (async () => { let result; try { result = await (0, import_parseContent.default)(message, false, this.ctg.logger); } catch (err) { this.ctx.handleError(err); return true; } try { this.rawWs.cork(() => this.rawWs.end(code, result.content)); } catch { } return true; })(); } return this; } /** * Print a Message to the Client (automatically Formatted) * * This will send a new websocket message to the client as soon * as the event loop allows it to execute the async task of parsing * the message content. * @example * ``` * ctr.print({ * message: 'this is json!' * }) * * // or * * ctr.print('this is text!') * ``` * @since 5.4.0 */ print(message, options = {}) { const prettify = options?.prettify ?? false; { (async () => { let result; try { result = await (0, import_parseContent.default)(message, prettify, this.ctg.logger); } catch (err) { this.ctx.handleError(err); return true; } try { this.rawWs.cork(() => this.rawWs.send(result.content)); this.ctg.webSockets.messages.outgoing.increase(); this.ctg.data.outgoing.increase(result.content.byteLength); } catch { } return true; })(); } return this; } /** * Print a references value every time it changes * * This will print when the provided reference changes state similarly * to the `.printStream()` method which listen to a streams `data` event. * @example * ``` * const ref = new Reference('Hello') * * ctr.printRef(ref) * * ref.set('Ok') * ``` * @since 7.2.0 */ printRef(reference, options = {}) { const prettify = options?.prettify ?? false; const ref = reference["onChange"](async (value) => { let data; try { data = (await (0, import_parseContent.default)(value, prettify, this.ctg.logger)).content; } catch (err) { return this.ctx.handleError(err); } try { this.rawWs.send(data); this.ctg.webSockets.messages.outgoing.increase(); this.ctg.data.outgoing.increase(data.byteLength); } catch { } }); this.ctx.refListeners.push({ ref: reference, refListener: ref }); return this; } /** * Remove a reference subscription * * This will remove the listener of a reference from the * current socket. May be slow when having many references * attached to the socket. * @example * ``` * const ref = new Reference('Hello') * * ctr.printRef(ref) * * ref.set('Ok') * * ctr.removeRef(ref) * ``` * @since 7.2.0 */ removeRef(reference) { const index = this.ctx.refListeners.findIndex(({ ref }) => Object.is(ref, reference)); if (index >= 0) { reference["removeOnChange"](this.ctx.refListeners[index].refListener); this.ctx.refListeners.splice(index, 1); } return this; } /** * Print the `data` event of a Stream to the Client * * This will print the `data` event of a stream to the client * in real time. This shouldnt be used over `.printRef()` but is * useful when working with something like a `fs.ReadStream` for * some reason. * @example * ``` * const fileStream = fs.createReadStream('./profile.png') * ctr.printStream(fileStream) * ``` * @since 5.4.0 */ printStream(stream, options = {}) { const prettify = options?.prettify ?? false; const destroyAbort = options?.destroyAbort ?? true; const destroyStream = () => { stream.destroy(); }; const dataListener = async (data) => { try { data = (await (0, import_parseContent.default)(data, prettify, this.ctg.logger)).content; } catch (err) { return this.ctx.handleError(err); } try { this.rawWs.send(data); this.ctg.webSockets.messages.outgoing.increase(); this.ctg.data.outgoing.increase(data.byteLength); } catch { } }, closeListener = () => { if (destroyAbort) this.ctx.events.unlist("requestAborted", destroyStream); }, errorListener = (error) => { this.ctx.handleError(error); stream.removeListener("data", dataListener).removeListener("close", closeListener).removeListener("error", errorListener); }; if (destroyAbort) this.ctx.events.listen("requestAborted", destroyStream); stream.on("data", dataListener).once("close", closeListener).once("error", errorListener); this.ctx.events.listen( "requestAborted", () => stream.removeListener("data", dataListener).removeListener("close", closeListener).removeListener("error", errorListener) ); return this; } }