UNPKG

@mtdt.temp/browser-core

Version:
83 lines 2.74 kB
import { queueMicrotask } from './queueMicrotask'; // eslint-disable-next-line no-restricted-syntax export class Observable { constructor(onFirstSubscribe) { this.onFirstSubscribe = onFirstSubscribe; this.observers = []; } subscribe(observer) { this.addObserver(observer); return { unsubscribe: () => this.removeObserver(observer), }; } notify(data) { this.observers.forEach((observer) => observer(data)); } addObserver(observer) { this.observers.push(observer); if (this.observers.length === 1 && this.onFirstSubscribe) { this.onLastUnsubscribe = this.onFirstSubscribe(this) || undefined; } } removeObserver(observer) { this.observers = this.observers.filter((other) => observer !== other); if (!this.observers.length && this.onLastUnsubscribe) { this.onLastUnsubscribe(); } } } export function mergeObservables(...observables) { return new Observable((globalObservable) => { const subscriptions = observables.map((observable) => observable.subscribe((data) => globalObservable.notify(data))); return () => subscriptions.forEach((subscription) => subscription.unsubscribe()); }); } // eslint-disable-next-line no-restricted-syntax export class BufferedObservable extends Observable { constructor(maxBufferSize) { super(); this.maxBufferSize = maxBufferSize; this.buffer = []; } notify(data) { this.buffer.push(data); if (this.buffer.length > this.maxBufferSize) { this.buffer.shift(); } super.notify(data); } subscribe(observer) { let closed = false; const subscription = { unsubscribe: () => { closed = true; this.removeObserver(observer); }, }; queueMicrotask(() => { for (const data of this.buffer) { if (closed) { return; } observer(data); } if (!closed) { this.addObserver(observer); } }); return subscription; } /** * Drop buffered data and don't buffer future data. This is to avoid leaking memory when it's not * needed anymore. This can be seen as a performance optimization, and things will work probably * even if this method isn't called, but still useful to clarify our intent and lowering our * memory impact. */ unbuffer() { queueMicrotask(() => { this.maxBufferSize = this.buffer.length = 0; }); } } //# sourceMappingURL=observable.js.map