import { BehaviorSubject, distinctUntilChanged, filter, map, Observable, Observer, Subject, Unsubscribable } from "rxjs"; import { AdapterInterface, ConnectionState, TransmissionRole, TransportType, TransportServiceInterface, AdapterProfile, ClientObject } from "../interface/interface"; import ConsoleLogger from "../utils/log.utils"; import { v4 as uuidv4 } from 'uuid' /* This transport manager will be instantiating the necessary transport to deal with tranmission and receiving from different receivers So how?: */ export class AdapterBase implements AdapterInterface { protected console!: ConsoleLogger protected adapterProfile!: AdapterProfile constructor(clientId: string, adapterType: TransportType, transportService: TransportServiceInterface, role: TransmissionRole) { //logic here this.setAdapterProfile(clientId, adapterType, transportService, role) this.setupConnectionState(this.adapterProfile.transportService) } subscribe(observer: Observer): Unsubscribable { throw new Error("Method not implemented."); } protected setAdapterProfile(clientId: string, adapterType: TransportType, transportService: TransportServiceInterface, role: TransmissionRole): void { this.adapterProfile = {} as AdapterProfile this.adapterProfile.id = uuidv4() this.adapterProfile.clientId = clientId as string this.adapterProfile.connectionState = new BehaviorSubject(`OFFLINE`) this.adapterProfile.role = role this.adapterProfile.transportType = adapterType this.adapterProfile.transportService = transportService } public getAdapterProfile(type?: `id` | `clientId` | `role` | `transportId` | `transportType` | `connectionState`): string | Observable | AdapterProfile | undefined { if (!type) return this.adapterProfile; const lookup: Record = { id: this.adapterProfile.id, clientId: this.adapterProfile.clientId, role: this.adapterProfile.role, transportType: this.adapterProfile.transportType, transportId: this.adapterProfile.transportService.getInfo().transportServiceId, connectionState: this.adapterProfile.connectionState.asObservable() }; return lookup[type]; } protected setupConnectionState(transportService: TransportServiceInterface): void { transportService.subscribeForEvent().pipe( filter(event => event.type === `Transport Event`), filter(event => (event.data as ClientObject).clientId === this.adapterProfile.clientId), map(event => { if (event.event == 'Client Disconnected' || event.event == 'Server Disconnected') { return 'OFFLINE' } else { return `ONLINE` } }), distinctUntilChanged() ).subscribe((signal: ConnectionState) => { this.adapterProfile.connectionState.next(signal) if (signal == 'OFFLINE') this.console.error({ message: `${this.adapterProfile.clientId} disconnected` }) if (signal == 'ONLINE') this.console.log({ message: `${this.adapterProfile.clientId} connected and ready to go` }) }) } }