smartrx/ts/smartrx.classes.observablemap.ts
2022-08-05 12:50:37 +02:00

74 lines
2.3 KiB
TypeScript

import * as plugins from './smartrx.plugins.js';
import * as rxjs from './smartrx.plugins.rxjs.js';
export interface IEventEmitter<T = any> {
on: (eventNameArg: string, eventHandlerArg: (eventPayload: T) => any) => void;
}
/**
* bundles an observable with an emitter
*/
export interface IObservableEventBundle<T> {
subject: rxjs.Subject<any>;
eventRef: T;
event: string;
}
/**
* manages observables by making sure that only one observable is regsitered per event
*/
export class Observablemap {
public observableEventEmitterBundleArray = new Array<
IObservableEventBundle<IEventEmitter<unknown>>
>();
public observableEventTargetBundleArray = new Array<IObservableEventBundle<EventTarget>>();
/**
* creates a hot subject if not yet registered for the event.
* In case event has been registered before the same observable is returned.
*/
public getSubjectForEmitterEvent<T>(
emitterArg: IEventEmitter<T>,
eventArg: string
): rxjs.Subject<T> {
const existingBundle = this.observableEventEmitterBundleArray.find((bundleArg) => {
return bundleArg.eventRef === emitterArg && bundleArg.event === eventArg;
});
if (existingBundle) {
return existingBundle.subject;
} else {
const emitterObservable = rxjs.fromEvent<T>(emitterArg as any, eventArg);
const emitterSubject = new rxjs.Subject();
emitterObservable.subscribe(emitterSubject);
const newBundle: IObservableEventBundle<IEventEmitter> = {
subject: emitterSubject,
eventRef: emitterArg,
event: eventArg,
};
this.observableEventEmitterBundleArray.push(newBundle);
return newBundle.subject;
}
}
public getSubjectForEventTarget<T>(
eventTargetArg: EventTarget,
eventNameArg: string
): rxjs.Subject<T> {
const existingBundle = this.observableEventTargetBundleArray.find((bundleArg) => {
return bundleArg.eventRef === eventTargetArg && bundleArg.event === eventNameArg;
});
if (existingBundle) {
return existingBundle.subject;
} else {
const emitterSubject = new rxjs.Subject();
const newBundle: IObservableEventBundle<EventTarget> = {
subject: emitterSubject,
eventRef: eventTargetArg,
event: eventNameArg,
};
this.observableEventTargetBundleArray.push(newBundle);
return newBundle.subject;
}
}
}