export class UIEventSource{ public data : T; private _callbacks = []; constructor(data: T) { this.data = data; } public addCallback(callback: ((latestData : T) => void)) { this._callbacks.push(callback); return this; } public setData(t: T): void { if (this.data === t) { return; } this.data = t; this.ping(); } public ping(): void { for (const callback of this._callbacks) { callback(this.data); } } public map(f: ((T) => J)): UIEventSource { const self = this; this.addCallback(function () { newSource.setData(f(self.data)); newSource.ping(); }); const newSource = new UIEventSource( f(this.data) ); return newSource; } }