servertime
Version:
Add server-timing header to your node.js app, with nanosecond precision.
125 lines (100 loc) • 3.03 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = void 0;
function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
/**
* Keeps track of timing data for events and turns that data into a `server-timing` header.
*/
class Timer {
/* We use a "dummy" timer which does nothing in production mode. */
constructor(options) {
_defineProperty(this, "_isDummy", void 0);
_defineProperty(this, "_clock", void 0);
_defineProperty(this, "_records", void 0);
this._isDummy = options.isDummy || false;
this._clock = options.clock;
this._records = {};
}
/**
* Start timing an event.
* @param slug - The slug to use for timing. The same slug must be supplied to `end(slug)` in order
* for this timing to show up in the final header.
* @param [label] - Label to use in the server-timing header.
*/
start(slug, label) {
if (this._isDummy) {
return;
}
if (this._records[slug]) {
console.error(`serverTime: Attempting to add slug we've already seen ${slug}`);
} else {
this._records[slug] = {
label: label || slug,
start: this._clock.start()
};
}
}
/**
* Stop timing an event.
* @param slug - The slug to supplied to `start()`.
*/
end(slug) {
if (this._isDummy) {
return;
}
const record = this._records[slug];
if (record) {
record.time = this._clock.diff(record.start);
}
}
/**
* Set the timing for an event.
* @param slug - The slug to use for timing.
* @param ms - Time, in milliseconds. Can be a float.
*/
setTime(slug, l, m) {
const ms = m ? m : l;
const label = m ? l : slug;
this._records[slug] = {
label,
time: ms
};
}
/**
* Time the duration of a promise.
* @param slug - The slug to use for timing.
* @param promise - The promise to time.
* @return - Returns the passed in `promise`.
*/
timePromise(slug, l, p) {
const promise = p ? p : l;
const label = p ? l : slug;
if (!this._isDummy) {
this.start(slug, label);
promise.then(() => this.end(slug), () => this.end(slug));
}
return promise;
}
/**
* Return the server-timing header.
* @return {string} - The header.
*/
getHeader() {
if (this._isDummy) {
return null;
}
return Object.keys(this._records) // Filter out any results where we never called 'end'
.filter(slug => 'time' in this._records[slug]).map(slug => {
const record = this._records[slug];
if (!record.label || record.label === slug) {
return `${slug};dur=${this._records[slug].time}`;
} else {
return `${slug};desc="${this._records[slug].label}";dur=${this._records[slug].time}`;
}
}).join(', ');
}
}
exports.default = Timer;
//# sourceMappingURL=Timer.js.map