embark/lib/versions/npmTimer.js

100 lines
3.6 KiB
JavaScript

const {PerformanceObserver, performance} = require('perf_hooks');
const _ = require('underscore');
require('colors');
const i18n = require('../i18n/i18n.js');
i18n.setOrDetectLocale('en');
class NpmTimer{
constructor(options){
this._logger = (options.logger && typeof options.logger.info == 'function') ? options.logger : console;
this._packageName = options.packageName;
this._version = options.version;
this._showSpinner = options.showSpinner || false;
this._spinnerStyle = options.spinnerStyle || 'dots';
this._interval = options.interval || 750;
// define mark and measurement names
this._startMark = 'downloadStart' + this._packageName + this._version;
this._ongoingMark = 'downloadOngoingMark' + this._packageName + this._version;
this._downloadOngoing = 'downloadOngoing' + this._packageName + this._version;
this._endMark = 'downloadEnd' + this._packageName + this._version;
this._downloadComplete = 'downloadComplete' + this._packageName + this._version;
this.observer.observe({entryTypes: ['measure']});
}
get observer(){
if(typeof this._observer == 'undefined'){
this._observer = new PerformanceObserver((items) => {
let entry;
let strDuration;
// find any download ongoing measurements we've made
entry = _.last(_.where(items.getEntries(), {name: this._downloadOngoing}));
if(entry){
// ongoing performance mark
strDuration = __('Downloading and installing {{packageName}} {{version}}... ({{duration}}ms elapsed)', {packageName: this._packageName, version: this._version, duration: entry.duration});
if(this._spinner) this._spinner.text = strDuration;
}
else{
// otherwise, find our download complete measurement
entry = _.last(_.where(items.getEntries(), {name: this._downloadComplete}));
if(entry){
strDuration = __('Finished downloading and installing {{packageName}} {{version}} in {{duration}}ms', {packageName: this._packageName, version: this._version, duration: entry.duration});
performance.clearMarks();
if(this._spinner) this._spinner.succeed(strDuration);
}
}
// log our measurement and make it red if it has taken too long
if(!this._showSpinner && entry && strDuration){
if(entry.duration > 4000){
strDuration = strDuration.red;
}
this._logger.info(strDuration);
}
});
}
return this._observer;
}
start(){
let self = this;
const strDownloadStart = __("Downloading and installing {{packageName}} {{version}}...", {packageName: this._packageName, version: this._version});
if(this._showSpinner){
const ora = require('ora');
this._spinner = ora({
spinner: this._spinnerStyle,
text: strDownloadStart
}).start();
}else{
this._logger.info(strDownloadStart);
}
// mark our start time
performance.mark(this._startMark);
// function that continually updates the console to show user that we're downloading a library
this._intOngoingDownload = setInterval(
function(){
performance.mark(self._ongoingMark);
performance.measure(self._downloadOngoing, self._startMark, self._ongoingMark);
}, this._interval);
}
end(){
// stop updating console for ongoing download
clearInterval(this._intOngoingDownload);
performance.mark(this._endMark);
performance.measure(this._downloadComplete, this._startMark, this._endMark);
}
}
module.exports = NpmTimer;