@mtdt.temp/browser-core
Version:
Datadog browser core utilities.
100 lines • 3.64 kB
JavaScript
import { setInterval, clearInterval } from './timer';
import { removeItem } from './utils/arrayUtils';
import { addDuration, relativeNow, ONE_MINUTE } from './utils/timeUtils';
const END_OF_TIMES = Infinity;
export const CLEAR_OLD_VALUES_INTERVAL = ONE_MINUTE;
let cleanupHistoriesInterval = null;
const cleanupTasks = new Set();
function cleanupHistories() {
cleanupTasks.forEach((task) => task());
}
export function createValueHistory({ expireDelay, maxEntries, }) {
let entries = [];
if (!cleanupHistoriesInterval) {
cleanupHistoriesInterval = setInterval(() => cleanupHistories(), CLEAR_OLD_VALUES_INTERVAL);
}
const clearExpiredValues = () => {
const oldTimeThreshold = relativeNow() - expireDelay;
while (entries.length > 0 && entries[entries.length - 1].endTime < oldTimeThreshold) {
entries.pop();
}
};
cleanupTasks.add(clearExpiredValues);
/**
* Add a value to the history associated with a start time. Returns a reference to this newly
* added entry that can be removed or closed.
*/
function add(value, startTime) {
const entry = {
value,
startTime,
endTime: END_OF_TIMES,
remove: () => {
removeItem(entries, entry);
},
close: (endTime) => {
entry.endTime = endTime;
},
};
if (maxEntries && entries.length >= maxEntries) {
entries.pop();
}
entries.unshift(entry);
return entry;
}
/**
* Return the latest value that was active during `startTime`, or the currently active value
* if no `startTime` is provided. This method assumes that entries are not overlapping.
*
* If `option.returnInactive` is true, returns the value at `startTime` (active or not).
*/
function find(startTime = END_OF_TIMES, options = { returnInactive: false }) {
for (const entry of entries) {
if (entry.startTime <= startTime) {
if (options.returnInactive || startTime <= entry.endTime) {
return entry.value;
}
break;
}
}
}
/**
* Helper function to close the currently active value, if any. This method assumes that entries
* are not overlapping.
*/
function closeActive(endTime) {
const latestEntry = entries[0];
if (latestEntry && latestEntry.endTime === END_OF_TIMES) {
latestEntry.close(endTime);
}
}
/**
* Return all values with an active period overlapping with the duration,
* or all values that were active during `startTime` if no duration is provided,
* or all currently active values if no `startTime` is provided.
*/
function findAll(startTime = END_OF_TIMES, duration = 0) {
const endTime = addDuration(startTime, duration);
return entries
.filter((entry) => entry.startTime <= endTime && startTime <= entry.endTime)
.map((entry) => entry.value);
}
/**
* Remove all entries from this collection.
*/
function reset() {
entries = [];
}
/**
* Stop internal garbage collection of past entries.
*/
function stop() {
cleanupTasks.delete(clearExpiredValues);
if (cleanupTasks.size === 0 && cleanupHistoriesInterval) {
clearInterval(cleanupHistoriesInterval);
cleanupHistoriesInterval = null;
}
}
return { add, find, closeActive, findAll, reset, stop };
}
//# sourceMappingURL=valueHistory.js.map