UNPKG

@taraai/read-write

Version:

Synchronous NoSQL/Firestore for React

258 lines (213 loc) 6.52 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = mark; exports.resource = resource; var _noop = _interopRequireDefault(require("lodash/noop")); var _debug = _interopRequireDefault(require("debug")); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } const info = (0, _debug.default)('readwrite:profile'); if (info.enabled && _debug.default.enabled('readwrite:cache')) { info(`Capturing Reducer & Firestore load times. See results with 'readwrite()'.`); } let win; try { const nodeRequire = module[`require`].bind(module); win = nodeRequire('perf_hooks'); } catch (e) {} try { win = window; } catch (e) {} const perf = win && win.performance; function mark(marker) { let context = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : ''; if (!_debug.default.enabled('readwrite:cache') || !_debug.default.enabled('readwrite:profile') || !perf) { return _noop.default; } try { const now = perf.now(); const start = `::readwrite/${marker}-${now}`; perf.mark(start); if (context) { info(`${marker}.${context}`); } return () => { perf.measure(`::readwrite/${marker}`, start); }; } catch (err) { return _noop.default; } } function resource(meta, stringify) { if (!_debug.default.enabled('readwrite:cache') || !_debug.default.enabled('readwrite:profile') || !perf) { return _noop.default; } try { const now = perf.now(); const marker = stringify(meta); let start = `::readwrite.load/${marker}-${now}`; perf.mark(start); return function () { let count = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : ''; if (!start) return; perf.measure(`::readwrite.load/${marker}.|${count}|`, start); start = null; }; } catch (err) { return _noop.default; } } if (win) { win.readwriteStats = function () { let force = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : false; if (!_debug.default.enabled('readwrite:cache') || !_debug.default.enabled('readwrite:profile') || !perf) { if (force) _debug.default.enable(typeof force === 'string' ? force : 'readwrite:*'); return; } const getMarks = _ref => { let { name } = _ref; return name.indexOf('::readwrite/') === 0; }; const getLoads = _ref2 => { let { name } = _ref2; return name.indexOf('::readwrite.load/') === 0; }; const duration = (stats, _ref3) => { let { duration, name } = _ref3; if (stats[name]) { stats[name].push(duration); } else { stats[name] = [duration]; } return stats; }; const formatTime = seconds => { if (seconds < 1000) return seconds + 'ms'; if (seconds < 1000 * 60) return (seconds / 1000).toFixed(3) + 's'; return (seconds / (1000 * 60)).toFixed(3) + ' minutes'; }; const logStats = grouped => { console.group(`Read Write Profiling`); console.table(Object.keys(grouped).map(name => { const arr = grouped[name]; const sum = arr.reduce((a, b) => a + b, 0); return { [name]: { mean: parseFloat((sum / arr.length).toFixed(2)), samples: arr.length, min: parseFloat(arr.reduce((a, b) => a < b ? a : b, arr[0]).toFixed(2)), max: parseFloat(arr.reduce((a, b) => a > b ? a : b, arr[0]).toFixed(2)), sum: parseFloat(sum.toFixed(2)) } }; }).reduce((result, item) => ({ ...result, ...item }))); console.groupEnd(); }; const marks = performance.getEntriesByType('measure').filter(getMarks).reduce(duration, {}); logStats(marks); const phases = ((last, phase) => _ref4 => { let { startTime, duration, name } = _ref4; if (last + 16 <= startTime) { phase++; } const item = { name, start: parseFloat(startTime.toFixed(2)), phase, duration: formatTime(parseFloat(duration.toFixed(2))), loaded: (/\|(\d+)\|/g.exec(name) || [0, 0])[1] }; last = startTime; return item; })(false, 0); const group = (arr, prop) => arr.reduce((stats, _ref5) => { let { phase, name, start, duration, loaded } = _ref5; if (!stats[phase]) { stats[phase] = {}; } stats[phase][name] = { start, duration, loaded }; return stats; }, {}); const logPhases = phases => { let last = 0; console.group(`Firestore Collection Loads`); Object.keys(phases).forEach(key => { const start = Object.values(phases[key]).reduce((num, _ref6) => { let { start } = _ref6; return Math.min(num, start); }, Number.MAX_VALUE); console.group(`Phase ${key} +${Math.floor(start - last)}ms`); console.table(phases[key]); console.groupEnd(); last = start; }); console.groupEnd(); }; const loads = performance.getEntriesByType('measure').filter(getLoads).map(phases); logPhases(group(loads, 'phase')); }; } if (!Object.size) { Object.size = obj => { let bytes = 0; const sizeOf = obj => { if (obj !== null && obj !== undefined) { switch (typeof obj) { case 'number': bytes += 8; break; case 'string': bytes += obj.length * 2; break; case 'boolean': bytes += 4; break; case 'object': const objClass = Object.prototype.toString.call(obj).slice(8, -1); if (objClass === 'Object' || objClass === 'Array') { for (const key in obj) { if (!obj.hasOwnProperty(key)) continue; sizeOf(obj[key]); } } else bytes += obj.toString().length * 2; break; } } return bytes; }; const formatByteSize = total => { if (total < 1024) return total + ' bytes'; if (total < 1048576) return (total / 1024).toFixed(3) + ' KiB'; if (total < 1073741824) return (total / 1048576).toFixed(3) + ' MiB'; return (total / 1073741824).toFixed(3) + ' GiB'; }; return formatByteSize(sizeOf(obj)); }; }