UNPKG

transfer-stats

Version:

Track download/upload and provide transfer stats

165 lines (137 loc) 4.72 kB
'use strict'; /** * Track download/upload and provide transfer stats */ const FixedArray = require('fixed-array'); module.exports = class Transfer { constructor(options) { this.bpsLog = FixedArray(5); const settings = typeof options === 'object' ? options : {}; this.bytesTotal = typeof settings.bytesTotal === 'number' ? settings.bytesTotal : null; this.bytesCompleted = typeof settings.bytesCompleted === 'number' ? settings.bytesCompleted : 0; this.lastBytesCompleted = this.bytesCompleted; this.startDateTime = null; this.pausedTotalTime = 0; this.started = false; this.finished = false; this.paused = false; const klass = this; this.stats = { get started() { return klass.started; }, get paused() { return klass.paused; }, get finished() { return klass.finished; }, get bytesTotal() { return klass.bytesTotal; }, get bytesCompleted() { return klass.bytesCompleted; }, get startDateTime() { return klass.startDateTime; }, get endDateTime() { return klass.endDateTime; }, get percentage() { const bytesRemaining = this.bytesRemaining, bytesTotal = this.bytesTotal; if (typeof bytesRemaining !== 'number' || typeof bytesTotal !== 'number') return null; return parseFloat((1 - bytesRemaining / bytesTotal).toFixed(10)); }, get bytesRemaining() { const bytesTotal = this.bytesTotal, bytesCompleted = this.bytesCompleted; if (typeof bytesTotal !== 'number') return null; return bytesTotal - bytesCompleted; }, get msElapsed() { const startDateTime = this.startDateTime; if (!startDateTime) return 0; const currentDateTime = new Date().getTime(); return currentDateTime - klass.pausedTotalTime - startDateTime; }, get bytesPerSecond() { const bpsLog = klass.bpsLog; const mean = bpsLog.mean(); if (mean < 0.0001) return 0; return mean; }, get bytesPerSecondSharp() { // Get's the exact BPS of the last update rather than the mean of the last 5 const bpsLog = klass.bpsLog; const bpsArr = bpsLog.values(); return bpsArr[bpsArr.length - 1]; }, get msTotal() { const bytesPerSecond = this.bytesPerSecond, bytesTotal = this.bytesTotal; if (typeof bytesTotal !== 'number') return null; return Math.floor(bytesTotal / bytesPerSecond * 1000); }, get msRemaining() { const msTotal = this.msTotal, msElapsed = this.msElapsed, bytesRemaining = this.bytesRemaining; if (typeof msTotal !== 'number') return null; if (bytesRemaining === 0) return 0; return msTotal - msElapsed; } }; } updateBytes(newBytesCompleted) { if (!this.started) { throw new Error('Transfer not started. Call start() before you call updateBytes()'); } if (!this.paused) { const lastBytesCompleted = this.bytesCompleted || 0; const currentTime = new Date().getTime(); const lastUpdatedDateTime = this.updatedDateTime || new Date().getTime(); const updatedDateTime = currentTime; const bps = (newBytesCompleted - lastBytesCompleted) / (updatedDateTime - lastUpdatedDateTime) * 1000; this.bpsLog.push(bps); this.lastUpdatedDateTime = lastUpdatedDateTime; this.updatedDateTime = updatedDateTime; this.lastBytesCompleted = lastBytesCompleted; } this.bytesCompleted = newBytesCompleted; } start() { this.started = true; if (!this.startDateTime) { const currentTime = new Date().getTime(); this.startDateTime = currentTime; this.lastUpdatedDateTime = currentTime; this.updatedDateTime = currentTime; } } pause() { const paused = this.paused; if (paused) return; const currentTime = new Date().getTime(); this.pausedStartDateTime = currentTime; this.bpsLog = FixedArray(5); this.paused = true; } resume() { const pausedStartDateTime = this.pausedStartDateTime, pausedTotalTime = this.pausedTotalTime, paused = this.paused; if (!paused) return; const currentTime = new Date().getTime(); const msPauseDuration = currentTime - (pausedStartDateTime || 0); this.pausedTotalTime = pausedTotalTime + msPauseDuration; this.updatedDateTime = currentTime; this.paused = false; } finish() { this.finished = true; this.started = false; this.endDateTime = new Date().getTime(); } };