UNPKG

@mtdt.temp/browser-core

Version:
89 lines 3.03 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.BufferedObservable = exports.Observable = void 0; exports.mergeObservables = mergeObservables; const queueMicrotask_1 = require("./queueMicrotask"); // eslint-disable-next-line no-restricted-syntax 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(); } } } exports.Observable = Observable; 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 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); }, }; (0, queueMicrotask_1.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() { (0, queueMicrotask_1.queueMicrotask)(() => { this.maxBufferSize = this.buffer.length = 0; }); } } exports.BufferedObservable = BufferedObservable; //# sourceMappingURL=observable.js.map