UNPKG

@mojojs/core

Version:

Real-time web framework

77 lines 2.38 kB
import EventEmitter, { on } from 'node:events'; /** * WebSocket connection class. */ class WebSocket extends EventEmitter { constructor(ws, handshake, options) { super({ captureRejections: true }); this.handshake = handshake; this.jsonMode = options.jsonMode ?? false; this._ws = ws; ws.on('error', error => this.emit('error', error)); ws.on('message', this._safeMessageHandler.bind(this)); const safeHandler = this._safeHandler; ws.on('close', safeHandler.bind(this, 'close')); ws.on('ping', safeHandler.bind(this, 'ping')); ws.on('pong', safeHandler.bind(this, 'pong')); } async *[Symbol.asyncIterator]() { try { for await (const [message] of this._messageIterator()) { yield message; } } catch (error) { if (!(error instanceof Error) || error.name !== 'AbortError') throw error; } } /** * Close WebSocket connection. */ close(code, reason) { this._ws.close(code, reason); } /** * Send WebSocket ping frame. */ async ping(data) { return await new Promise(resolve => this._ws.ping(data, undefined, () => resolve())); } /** * Send WebSocket message. */ async send(message) { if (this.jsonMode === false) return await new Promise(resolve => this._ws.send(message, () => resolve())); return new Promise(resolve => this._ws.send(JSON.stringify(message), () => resolve())); } _messageIterator() { const ac = new AbortController(); this._ws.on('close', () => ac.abort()); return on(this, 'message', { signal: ac.signal }); } _safeHandler(event, ...args) { try { this.emit(event, ...args); } catch (error) { this.emit('error', error); } } _safeMessageHandler(message, isBinary) { try { if (this.jsonMode === false) { this.emit('message', isBinary ? message : message.toString()); } else { this.emit('message', JSON.parse(message.toString())); } } catch (error) { this.emit('error', error); } } } export { WebSocket }; //# sourceMappingURL=websocket.js.map