/* * Copyright (c) 2022. * Author Peter Placzek (tada5hi) * For the full copyright and license information, * view the LICENSE file that was distributed with this source code. */ import { Manager, Socket, ManagerOptions } from 'socket.io-client'; import {Context} from "@nuxt/types"; type SocketModuleManagerConfiguration = {url: string, options?: Partial}; class SocketModule { protected ctx: Context; protected manager : Manager; protected sockets : Map; //-------------------------------------------------------------------- constructor(ctx: Context, managerConfiguration : SocketModuleManagerConfiguration) { this.ctx = ctx; this.sockets = new Map(); this.manager = new Manager(managerConfiguration.url, { autoConnect: false, ...managerConfiguration.options }); this.subscribeStore(); } private subscribeStore() { if (typeof this.ctx === 'undefined') return; this.ctx.store.subscribe((mutation: any, state: any) => { switch (mutation.type) { case 'auth/unsetToken': case 'auth/setToken': this.sockets.forEach((value: Socket, key: string) => { this.reconnect(key); }); break } }); } //-------------------------------------------------------------------- public use(namespace?: string) : Socket { if(typeof this.manager === 'undefined') { throw new Error('Manager not initialized...'); } if(typeof namespace === 'undefined') { namespace = '/'; } let socket = this.sockets.get(namespace); if(typeof socket !== 'undefined') { return socket; } const getToken = (cb) => { let token : {accessToken: string, [key: string] : any} | undefined = this.ctx.$authWarehouse.get('token'); if(typeof token === 'undefined') { token = this.ctx.store.getters['auth/token']; } if(typeof token !== 'undefined') { return cb({token: token.accessToken}); } return cb(); } getToken.bind(this); socket = this.manager.socket(namespace, { auth: getToken }); if(!process.server) { socket.connect(); } this.sockets.set(namespace, socket); return socket; } public unUse(namespace?: string) { if(typeof namespace === 'undefined') { namespace = '/'; } if(this.sockets.has(namespace)) { this.sockets.delete(namespace); } } //-------------------------------------------------------------------- public reconnect(namespace: string) { if(!this.sockets.has(namespace)) return; const socket = this.sockets.get(namespace); socket.disconnect(); setTimeout(() => { socket.connect(); },0); this.sockets.set(namespace, socket); } } export default SocketModule;