// import { Observable } from 'rxjs'; import { SocketService } from 'ag-sockets/dist/browser'; import { ClientAdminActions } from '../../client/clientAdminActions'; import { IAdminServerActions, ModelTypes } from '../../common/adminInterfaces'; import { removeItem } from '../../common/utils'; import { Subscription } from '../../common/interfaces'; import { MINUTE } from '../../common/constants'; type OnModel = (item: T | undefined) => void; interface ModelSubscriberConfig { fix?: (item: T) => void; } interface ModelSubscription { value: T | undefined; timeout: any; callbacks: OnModel[]; } const unsubscribeTimeout = 1 * MINUTE; export class ModelSubscriber { private subscriptions = new Map>(); // private observables = new Map>(); constructor( private type: ModelTypes, private socket: SocketService, private config: ModelSubscriberConfig = {}, private defaultValue: T | undefined = undefined, ) { } // for(id: string) { // return this.createObservable(id); // } // private createObservable(id: string) { // return new Observable(observer => { // this.socket.server.subscribe(this.model, id); // return () => { // this.socket.server.unsubscribe(this.model, id); // }; // }); // } get(id: string) { const subscription = this.subscriptions.get(id); return subscription && subscription.value; } subscribe(id: string, callback: OnModel): Subscription { const subscription = this.subscriptions.get(id); if (subscription) { if (subscription.timeout) { clearTimeout(subscription.timeout); subscription.timeout = 0; } subscription.callbacks.push(callback); if (subscription.value !== undefined) { callback(subscription.value); } } else { this.socket.server.subscribe(this.type, id); this.subscriptions.set(id, { value: this.defaultValue, timeout: 0, callbacks: [callback], }); } return { unsubscribe: () => this.unsubscribe(id, callback), }; } unsubscribe(id: string, callback: OnModel) { const subscription = this.subscriptions.get(id); if (subscription) { removeItem(subscription.callbacks, callback); if (subscription.callbacks.length === 0) { subscription.timeout = setTimeout(() => { this.socket.server.unsubscribe(this.type, id); this.subscriptions.delete(id); }, unsubscribeTimeout); } } } update(id: string, update: T) { const subscription = this.subscriptions.get(id); if (update !== undefined && this.config.fix) { this.config.fix(update); } if (subscription) { subscription.value = update; subscription.callbacks.forEach(c => c(update)); } } connected() { this.subscriptions.forEach((_, id) => { this.socket.server.subscribe(this.type, id); }); } }