@mtdt.temp/browser-core
Version:
Datadog browser core utilities.
89 lines • 3.03 kB
JavaScript
"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