UNPKG

@ewb/reach-react

Version:
85 lines (84 loc) 3.35 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.ReachSocketConnection = void 0; const uuid_1 = require("uuid"); const socket_io_client_1 = require("socket.io-client"); class ReachSocketConnection { constructor(service, url, namespace = '', event = '', opts = {}) { this.service = service; this.url = url; this.namespace = namespace; this.event = event; this.subscriptions = []; this.disconnected = false; this.timeouts = 0; this.maxTimeouts = 5; this.reconnect = 5000; this.socketConnection = socket_io_client_1.io(`${this.url}${namespace ? `/${namespace}` : ''}`, Object.assign({ reconnection: true, reconnectionDelay: 2000, reconnectionAttempts: 10, reconnectionDelayMax: 10000, autoConnect: true, withCredentials: true }, opts)); this.init(); } subscribe(callback, filter) { const _id = uuid_1.v4(); this.subscriptions.push({ _id, callback, filter, }); return unsubscribe(this.subscriptions, _id); } emit(event, ...args) { this.socketConnection.emit(event, args); } on(event, fn) { return this.socketConnection.on(event, (id, ...args) => { if (this.matchSocketId(id)) return; fn(event, id, ...args); }); } disconnect() { this.disconnected = true; this.subscriptions = []; this.socketConnection.disconnect(); this.socketConnection.close(); } init() { this.socketConnection.on('connect', () => { this.service.addSocket(this.socketConnection.id); }); this.socketConnection.once('connect', () => { this.socketConnection.onAny((event, id, ...broadcast) => { if (this.matchSocketId(id)) return; this.subscriptions.forEach((x) => x.filter ? x.filter(event, id, ...broadcast) && x.callback(event, id, ...broadcast) : x.callback(event, id, ...broadcast)); }); }); this.socketConnection.on('disconnect', () => { this.service.deleteSocket(this.socketConnection.id); }); this.socketConnection.on('error', (e) => { console.warn('SocketConnection error', this.namespace, e); if (Number(e) >= 400) { console.warn('SocketConnection disconnected'); return this.disconnect(); } if (this.socketConnection.disconnected && this.timeouts <= this.maxTimeouts) { console.warn(`SocketConnection lost connection. Reconnecting in ${this.reconnect / 1000}s`); this.timeouts++; setTimeout(() => this.socketConnection.connect(), this.reconnect); } }); } matchSocketId(id) { return typeof id === 'string' && id.split(' ').includes(this.socketConnection.id); } } exports.ReachSocketConnection = ReachSocketConnection; function unsubscribe(subscriptions, _id) { return () => { const index = subscriptions.findIndex((x) => x._id === _id); subscriptions.splice(index, 1); }; }