'use strict'; const assert = require('assert'); const MAP = Symbol('Timing#map'); const LIST = Symbol('Timing#list'); class Timing { constructor() { this._enable = true; this[MAP] = new Map(); this[LIST] = []; this.init(); } init() { // process start time this.start('Process Start', Date.now() - Math.floor((process.uptime() * 1000))); this.end('Process Start'); if (typeof process.scriptStartTime === 'number') { // js script start execute time this.start('Script Start', process.scriptStartTime); this.end('Script Start'); } } start(name, start) { if (!name || !this._enable) return; if (this[MAP].has(name)) this.end(name); start = start || Date.now(); const item = { name, start, end: undefined, duration: undefined, pid: process.pid, index: this[LIST].length, }; this[MAP].set(name, item); this[LIST].push(item); return item; } end(name) { if (!name || !this._enable) return; assert(this[MAP].has(name), `should run timing.start('${name}') first`); const item = this[MAP].get(name); item.end = Date.now(); item.duration = item.end - item.start; return item; } enable() { this._enable = true; } disable() { this._enable = false; } clear() { this[MAP].clear(); this[LIST] = []; } toJSON() { return this[LIST]; } } module.exports = Timing;