UNPKG

@phnq/message

Version:

Asynchronous, incremental messaging client and server

123 lines (122 loc) 5.22 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 __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.ClientWebSocketTransport = exports.ServerWebSocketTransport = void 0; require("ws"); // need to explicitly import this so it gets loaded as a dependency const isomorphic_ws_1 = __importDefault(require("isomorphic-ws")); const serialize_1 = require("../serialize"); class ServerWebSocketTransport { constructor(socket) { this.socket = socket; } send(message) { return __awaiter(this, void 0, void 0, function* () { this.socket.send((0, serialize_1.serialize)(message)); }); } onReceive(receive) { this.socket.addListener('message', data => { receive((0, serialize_1.deserialize)(data.toString())); }); } close() { return __awaiter(this, void 0, void 0, function* () { return new Promise(resolve => { this.socket.addListener('close', resolve); this.socket.close(); }); }); } } exports.ServerWebSocketTransport = ServerWebSocketTransport; class ClientWebSocketTransport { constructor(url) { this.url = url; } send(message) { return __awaiter(this, void 0, void 0, function* () { yield this.connect(); if (this.socket) { this.socket.send((0, serialize_1.serialize)(message)); } }); } onReceive(onReceiveFn) { this.onReceiveFn = onReceiveFn; } close() { return __awaiter(this, void 0, void 0, function* () { return new Promise(resolve => { if (this.socket) { this.socket.addEventListener('close', resolve); this.socket.close(1000); } else { resolve(); } }); }); } isOpen() { return this.socket !== undefined && this.socket.readyState === isomorphic_ws_1.default.OPEN; } connect() { return __awaiter(this, void 0, void 0, function* () { if (this.socket && this.socket.readyState === isomorphic_ws_1.default.OPEN) { return; } else if (this.socket && this.socket.readyState === isomorphic_ws_1.default.CONNECTING) { return new Promise(resolve => { this.socket && this.socket.addEventListener('open', resolve); }); } yield new Promise((resolve, reject) => { try { this.socket = new isomorphic_ws_1.default(this.url); this.socket.addEventListener('message', event => { if (this.onReceiveFn) { this.onReceiveFn((0, serialize_1.deserialize)(event.data.toString())); } }); this.socket.addEventListener('close', () => { if (this.onClose) { this.onClose(); } this.socket = undefined; }); this.socket.addEventListener('open', resolve); this.socket.addEventListener('error', event => { var _a; const errorMessage = `Socket error (${this.url}): ${((_a = event === null || event === void 0 ? void 0 : event.error) === null || _a === void 0 ? void 0 : _a.message) || 'unknown error'}`; reject(new Error(errorMessage)); }); } catch (err) { const errorMessage = `Error creating WebSocket (${this.url}): ${err instanceof Error ? err.message : String(err)}`; reject(new Error(errorMessage)); } }); if (this.socket && this.socket.readyState === isomorphic_ws_1.default.CLOSING) { return new Promise((_, reject) => { if (this.socket) { this.socket.addEventListener('close', event => { reject(new Error(`Socket closed by server (${event.reason})`)); }); } }); } }); } } exports.ClientWebSocketTransport = ClientWebSocketTransport;