UNPKG

latency-monitor

Version:

A generic latency monitor for node/browers

1,607 lines (1,342 loc) 229 kB
/******/ (function(modules) { // webpackBootstrap /******/ // The module cache /******/ var installedModules = {}; /******/ /******/ // The require function /******/ function __webpack_require__(moduleId) { /******/ /******/ // Check if module is in cache /******/ if(installedModules[moduleId]) /******/ return installedModules[moduleId].exports; /******/ /******/ // Create a new module (and put it into the cache) /******/ var module = installedModules[moduleId] = { /******/ i: moduleId, /******/ l: false, /******/ exports: {} /******/ }; /******/ /******/ // Execute the module function /******/ modules[moduleId].call(module.exports, module, module.exports, __webpack_require__); /******/ /******/ // Flag the module as loaded /******/ module.l = true; /******/ /******/ // Return the exports of the module /******/ return module.exports; /******/ } /******/ /******/ /******/ // expose the modules object (__webpack_modules__) /******/ __webpack_require__.m = modules; /******/ /******/ // expose the module cache /******/ __webpack_require__.c = installedModules; /******/ /******/ // identity function for calling harmony imports with the correct context /******/ __webpack_require__.i = function(value) { return value; }; /******/ /******/ // define getter function for harmony exports /******/ __webpack_require__.d = function(exports, name, getter) { /******/ if(!__webpack_require__.o(exports, name)) { /******/ Object.defineProperty(exports, name, { /******/ configurable: false, /******/ enumerable: true, /******/ get: getter /******/ }); /******/ } /******/ }; /******/ /******/ // getDefaultExport function for compatibility with non-harmony modules /******/ __webpack_require__.n = function(module) { /******/ var getter = module && module.__esModule ? /******/ function getDefault() { return module['default']; } : /******/ function getModuleExports() { return module; }; /******/ __webpack_require__.d(getter, 'a', getter); /******/ return getter; /******/ }; /******/ /******/ // Object.prototype.hasOwnProperty.call /******/ __webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); }; /******/ /******/ // __webpack_public_path__ /******/ __webpack_require__.p = ""; /******/ /******/ // Load entry module and return exports /******/ return __webpack_require__(__webpack_require__.s = 60); /******/ }) /************************************************************************/ /******/ ([ /* 0 */ /***/ (function(module, exports, __webpack_require__) { var eq = __webpack_require__(53); /** * Gets the index at which the `key` is found in `array` of key-value pairs. * * @private * @param {Array} array The array to inspect. * @param {*} key The key to search for. * @returns {number} Returns the index of the matched value, else `-1`. */ function assocIndexOf(array, key) { var length = array.length; while (length--) { if (eq(array[length][0], key)) { return length; } } return -1; } module.exports = assocIndexOf; /***/ }), /* 1 */ /***/ (function(module, exports, __webpack_require__) { var isKeyable = __webpack_require__(36); /** * Gets the data for `map`. * * @private * @param {Object} map The map to query. * @param {string} key The reference key. * @returns {*} Returns the map data. */ function getMapData(map, key) { var data = map.__data__; return isKeyable(key) ? data[typeof key == 'string' ? 'string' : 'hash'] : data.map; } module.exports = getMapData; /***/ }), /* 2 */ /***/ (function(module, exports, __webpack_require__) { var getNative = __webpack_require__(10); /* Built-in method references that are verified to be native. */ var nativeCreate = getNative(Object, 'create'); module.exports = nativeCreate; /***/ }), /* 3 */ /***/ (function(module, exports, __webpack_require__) { var root = __webpack_require__(4); /** Built-in value references. */ var Symbol = root.Symbol; module.exports = Symbol; /***/ }), /* 4 */ /***/ (function(module, exports, __webpack_require__) { var freeGlobal = __webpack_require__(27); /** Detect free variable `self`. */ var freeSelf = typeof self == 'object' && self && self.Object === Object && self; /** Used as a reference to the global object. */ var root = freeGlobal || freeSelf || Function('return this')(); module.exports = root; /***/ }), /* 5 */ /***/ (function(module, exports) { /** * Checks if `value` is classified as an `Array` object. * * @static * @memberOf _ * @since 0.1.0 * @category Lang * @param {*} value The value to check. * @returns {boolean} Returns `true` if `value` is an array, else `false`. * @example * * _.isArray([1, 2, 3]); * // => true * * _.isArray(document.body.children); * // => false * * _.isArray('abc'); * // => false * * _.isArray(_.noop); * // => false */ var isArray = Array.isArray; module.exports = isArray; /***/ }), /* 6 */ /***/ (function(module, exports, __webpack_require__) { var baseGetTag = __webpack_require__(9), isObjectLike = __webpack_require__(55); /** `Object#toString` result references. */ var symbolTag = '[object Symbol]'; /** * Checks if `value` is classified as a `Symbol` primitive or object. * * @static * @memberOf _ * @since 4.0.0 * @category Lang * @param {*} value The value to check. * @returns {boolean} Returns `true` if `value` is a symbol, else `false`. * @example * * _.isSymbol(Symbol.iterator); * // => true * * _.isSymbol('abc'); * // => false */ function isSymbol(value) { return typeof value == 'symbol' || (isObjectLike(value) && baseGetTag(value) == symbolTag); } module.exports = isSymbol; /***/ }), /* 7 */ /***/ (function(module, exports, __webpack_require__) { /* WEBPACK VAR INJECTION */(function(process) {/** * This is the web browser implementation of `debug()`. * * Expose `debug()` as the module. */ exports = module.exports = __webpack_require__(16); exports.log = log; exports.formatArgs = formatArgs; exports.save = save; exports.load = load; exports.useColors = useColors; exports.storage = 'undefined' != typeof chrome && 'undefined' != typeof chrome.storage ? chrome.storage.local : localstorage(); /** * Colors. */ exports.colors = [ 'lightseagreen', 'forestgreen', 'goldenrod', 'dodgerblue', 'darkorchid', 'crimson' ]; /** * Currently only WebKit-based Web Inspectors, Firefox >= v31, * and the Firebug extension (any Firefox version) are known * to support "%c" CSS customizations. * * TODO: add a `localStorage` variable to explicitly enable/disable colors */ function useColors() { // NB: In an Electron preload script, document will be defined but not fully // initialized. Since we know we're in Chrome, we'll just detect this case // explicitly if (typeof window !== 'undefined' && window && typeof window.process !== 'undefined' && window.process.type === 'renderer') { return true; } // is webkit? http://stackoverflow.com/a/16459606/376773 // document is undefined in react-native: https://github.com/facebook/react-native/pull/1632 return (typeof document !== 'undefined' && document && 'WebkitAppearance' in document.documentElement.style) || // is firebug? http://stackoverflow.com/a/398120/376773 (typeof window !== 'undefined' && window && window.console && (console.firebug || (console.exception && console.table))) || // is firefox >= v31? // https://developer.mozilla.org/en-US/docs/Tools/Web_Console#Styling_messages (typeof navigator !== 'undefined' && navigator && navigator.userAgent && navigator.userAgent.toLowerCase().match(/firefox\/(\d+)/) && parseInt(RegExp.$1, 10) >= 31) || // double check webkit in userAgent just in case we are in a worker (typeof navigator !== 'undefined' && navigator && navigator.userAgent && navigator.userAgent.toLowerCase().match(/applewebkit\/(\d+)/)); } /** * Map %j to `JSON.stringify()`, since no Web Inspectors do that by default. */ exports.formatters.j = function(v) { try { return JSON.stringify(v); } catch (err) { return '[UnexpectedJSONParseError]: ' + err.message; } }; /** * Colorize log arguments if enabled. * * @api public */ function formatArgs(args) { var useColors = this.useColors; args[0] = (useColors ? '%c' : '') + this.namespace + (useColors ? ' %c' : ' ') + args[0] + (useColors ? '%c ' : ' ') + '+' + exports.humanize(this.diff); if (!useColors) return; var c = 'color: ' + this.color; args.splice(1, 0, c, 'color: inherit') // the final "%c" is somewhat tricky, because there could be other // arguments passed either before or after the %c, so we need to // figure out the correct index to insert the CSS into var index = 0; var lastC = 0; args[0].replace(/%[a-zA-Z%]/g, function(match) { if ('%%' === match) return; index++; if ('%c' === match) { // we only are interested in the *last* %c // (the user may have provided their own) lastC = index; } }); args.splice(lastC, 0, c); } /** * Invokes `console.log()` when available. * No-op when `console.log` is not a "function". * * @api public */ function log() { // this hackery is required for IE8/9, where // the `console.log` function doesn't have 'apply' return 'object' === typeof console && console.log && Function.prototype.apply.call(console.log, console, arguments); } /** * Save `namespaces`. * * @param {String} namespaces * @api private */ function save(namespaces) { try { if (null == namespaces) { exports.storage.removeItem('debug'); } else { exports.storage.debug = namespaces; } } catch(e) {} } /** * Load `namespaces`. * * @return {String} returns the previously persisted debug modes * @api private */ function load() { try { return exports.storage.debug; } catch(e) {} // If debug isn't set in LS, and we're in Electron, try to load $DEBUG if (typeof process !== 'undefined' && 'env' in process) { return process.env.DEBUG; } } /** * Enable namespaces listed in `localStorage.debug` initially. */ exports.enable(load()); /** * Localstorage attempts to return the localstorage. * * This is necessary because safari throws * when a user disables cookies/localstorage * and you attempt to access it. * * @return {LocalStorage} * @api private */ function localstorage() { try { return window.localStorage; } catch (e) {} } /* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(13))) /***/ }), /* 8 */ /***/ (function(module, exports) { // Copyright Joyent, Inc. and other Node contributors. // // Permission is hereby granted, free of charge, to any person obtaining a // copy of this software and associated documentation files (the // "Software"), to deal in the Software without restriction, including // without limitation the rights to use, copy, modify, merge, publish, // distribute, sublicense, and/or sell copies of the Software, and to permit // persons to whom the Software is furnished to do so, subject to the // following conditions: // // The above copyright notice and this permission notice shall be included // in all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS // OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN // NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, // DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR // OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE // USE OR OTHER DEALINGS IN THE SOFTWARE. function EventEmitter() { this._events = this._events || {}; this._maxListeners = this._maxListeners || undefined; } module.exports = EventEmitter; // Backwards-compat with node 0.10.x EventEmitter.EventEmitter = EventEmitter; EventEmitter.prototype._events = undefined; EventEmitter.prototype._maxListeners = undefined; // By default EventEmitters will print a warning if more than 10 listeners are // added to it. This is a useful default which helps finding memory leaks. EventEmitter.defaultMaxListeners = 10; // Obviously not all Emitters should be limited to 10. This function allows // that to be increased. Set to zero for unlimited. EventEmitter.prototype.setMaxListeners = function(n) { if (!isNumber(n) || n < 0 || isNaN(n)) throw TypeError('n must be a positive number'); this._maxListeners = n; return this; }; EventEmitter.prototype.emit = function(type) { var er, handler, len, args, i, listeners; if (!this._events) this._events = {}; // If there is no 'error' event listener then throw. if (type === 'error') { if (!this._events.error || (isObject(this._events.error) && !this._events.error.length)) { er = arguments[1]; if (er instanceof Error) { throw er; // Unhandled 'error' event } else { // At least give some kind of context to the user var err = new Error('Uncaught, unspecified "error" event. (' + er + ')'); err.context = er; throw err; } } } handler = this._events[type]; if (isUndefined(handler)) return false; if (isFunction(handler)) { switch (arguments.length) { // fast cases case 1: handler.call(this); break; case 2: handler.call(this, arguments[1]); break; case 3: handler.call(this, arguments[1], arguments[2]); break; // slower default: args = Array.prototype.slice.call(arguments, 1); handler.apply(this, args); } } else if (isObject(handler)) { args = Array.prototype.slice.call(arguments, 1); listeners = handler.slice(); len = listeners.length; for (i = 0; i < len; i++) listeners[i].apply(this, args); } return true; }; EventEmitter.prototype.addListener = function(type, listener) { var m; if (!isFunction(listener)) throw TypeError('listener must be a function'); if (!this._events) this._events = {}; // To avoid recursion in the case that type === "newListener"! Before // adding it to the listeners, first emit "newListener". if (this._events.newListener) this.emit('newListener', type, isFunction(listener.listener) ? listener.listener : listener); if (!this._events[type]) // Optimize the case of one listener. Don't need the extra array object. this._events[type] = listener; else if (isObject(this._events[type])) // If we've already got an array, just append. this._events[type].push(listener); else // Adding the second element, need to change to array. this._events[type] = [this._events[type], listener]; // Check for listener leak if (isObject(this._events[type]) && !this._events[type].warned) { if (!isUndefined(this._maxListeners)) { m = this._maxListeners; } else { m = EventEmitter.defaultMaxListeners; } if (m && m > 0 && this._events[type].length > m) { this._events[type].warned = true; console.error('(node) warning: possible EventEmitter memory ' + 'leak detected. %d listeners added. ' + 'Use emitter.setMaxListeners() to increase limit.', this._events[type].length); if (typeof console.trace === 'function') { // not supported in IE 10 console.trace(); } } } return this; }; EventEmitter.prototype.on = EventEmitter.prototype.addListener; EventEmitter.prototype.once = function(type, listener) { if (!isFunction(listener)) throw TypeError('listener must be a function'); var fired = false; function g() { this.removeListener(type, g); if (!fired) { fired = true; listener.apply(this, arguments); } } g.listener = listener; this.on(type, g); return this; }; // emits a 'removeListener' event iff the listener was removed EventEmitter.prototype.removeListener = function(type, listener) { var list, position, length, i; if (!isFunction(listener)) throw TypeError('listener must be a function'); if (!this._events || !this._events[type]) return this; list = this._events[type]; length = list.length; position = -1; if (list === listener || (isFunction(list.listener) && list.listener === listener)) { delete this._events[type]; if (this._events.removeListener) this.emit('removeListener', type, listener); } else if (isObject(list)) { for (i = length; i-- > 0;) { if (list[i] === listener || (list[i].listener && list[i].listener === listener)) { position = i; break; } } if (position < 0) return this; if (list.length === 1) { list.length = 0; delete this._events[type]; } else { list.splice(position, 1); } if (this._events.removeListener) this.emit('removeListener', type, listener); } return this; }; EventEmitter.prototype.removeAllListeners = function(type) { var key, listeners; if (!this._events) return this; // not listening for removeListener, no need to emit if (!this._events.removeListener) { if (arguments.length === 0) this._events = {}; else if (this._events[type]) delete this._events[type]; return this; } // emit removeListener for all listeners on all events if (arguments.length === 0) { for (key in this._events) { if (key === 'removeListener') continue; this.removeAllListeners(key); } this.removeAllListeners('removeListener'); this._events = {}; return this; } listeners = this._events[type]; if (isFunction(listeners)) { this.removeListener(type, listeners); } else if (listeners) { // LIFO order while (listeners.length) this.removeListener(type, listeners[listeners.length - 1]); } delete this._events[type]; return this; }; EventEmitter.prototype.listeners = function(type) { var ret; if (!this._events || !this._events[type]) ret = []; else if (isFunction(this._events[type])) ret = [this._events[type]]; else ret = this._events[type].slice(); return ret; }; EventEmitter.prototype.listenerCount = function(type) { if (this._events) { var evlistener = this._events[type]; if (isFunction(evlistener)) return 1; else if (evlistener) return evlistener.length; } return 0; }; EventEmitter.listenerCount = function(emitter, type) { return emitter.listenerCount(type); }; function isFunction(arg) { return typeof arg === 'function'; } function isNumber(arg) { return typeof arg === 'number'; } function isObject(arg) { return typeof arg === 'object' && arg !== null; } function isUndefined(arg) { return arg === void 0; } /***/ }), /* 9 */ /***/ (function(module, exports, __webpack_require__) { var Symbol = __webpack_require__(3), getRawTag = __webpack_require__(28), objectToString = __webpack_require__(49); /** `Object#toString` result references. */ var nullTag = '[object Null]', undefinedTag = '[object Undefined]'; /** Built-in value references. */ var symToStringTag = Symbol ? Symbol.toStringTag : undefined; /** * The base implementation of `getTag` without fallbacks for buggy environments. * * @private * @param {*} value The value to query. * @returns {string} Returns the `toStringTag`. */ function baseGetTag(value) { if (value == null) { return value === undefined ? undefinedTag : nullTag; } return (symToStringTag && symToStringTag in Object(value)) ? getRawTag(value) : objectToString(value); } module.exports = baseGetTag; /***/ }), /* 10 */ /***/ (function(module, exports, __webpack_require__) { var baseIsNative = __webpack_require__(23), getValue = __webpack_require__(29); /** * Gets the native function at `key` of `object`. * * @private * @param {Object} object The object to query. * @param {string} key The key of the method to get. * @returns {*} Returns the function if it's native, else `undefined`. */ function getNative(object, key) { var value = getValue(object, key); return baseIsNative(value) ? value : undefined; } module.exports = getNative; /***/ }), /* 11 */ /***/ (function(module, exports, __webpack_require__) { var baseGetTag = __webpack_require__(9), isObject = __webpack_require__(12); /** `Object#toString` result references. */ var asyncTag = '[object AsyncFunction]', funcTag = '[object Function]', genTag = '[object GeneratorFunction]', proxyTag = '[object Proxy]'; /** * Checks if `value` is classified as a `Function` object. * * @static * @memberOf _ * @since 0.1.0 * @category Lang * @param {*} value The value to check. * @returns {boolean} Returns `true` if `value` is a function, else `false`. * @example * * _.isFunction(_); * // => true * * _.isFunction(/abc/); * // => false */ function isFunction(value) { if (!isObject(value)) { return false; } // The use of `Object#toString` avoids issues with the `typeof` operator // in Safari 9 which returns 'object' for typed arrays and other constructors. var tag = baseGetTag(value); return tag == funcTag || tag == genTag || tag == asyncTag || tag == proxyTag; } module.exports = isFunction; /***/ }), /* 12 */ /***/ (function(module, exports) { /** * Checks if `value` is the * [language type](http://www.ecma-international.org/ecma-262/7.0/#sec-ecmascript-language-types) * of `Object`. (e.g. arrays, functions, objects, regexes, `new Number(0)`, and `new String('')`) * * @static * @memberOf _ * @since 0.1.0 * @category Lang * @param {*} value The value to check. * @returns {boolean} Returns `true` if `value` is an object, else `false`. * @example * * _.isObject({}); * // => true * * _.isObject([1, 2, 3]); * // => true * * _.isObject(_.noop); * // => true * * _.isObject(null); * // => false */ function isObject(value) { var type = typeof value; return value != null && (type == 'object' || type == 'function'); } module.exports = isObject; /***/ }), /* 13 */ /***/ (function(module, exports) { // shim for using process in browser var process = module.exports = {}; // cached from whatever global is present so that test runners that stub it // don't break things. But we need to wrap it in a try catch in case it is // wrapped in strict mode code which doesn't define any globals. It's inside a // function because try/catches deoptimize in certain engines. var cachedSetTimeout; var cachedClearTimeout; function defaultSetTimout() { throw new Error('setTimeout has not been defined'); } function defaultClearTimeout () { throw new Error('clearTimeout has not been defined'); } (function () { try { if (typeof setTimeout === 'function') { cachedSetTimeout = setTimeout; } else { cachedSetTimeout = defaultSetTimout; } } catch (e) { cachedSetTimeout = defaultSetTimout; } try { if (typeof clearTimeout === 'function') { cachedClearTimeout = clearTimeout; } else { cachedClearTimeout = defaultClearTimeout; } } catch (e) { cachedClearTimeout = defaultClearTimeout; } } ()) function runTimeout(fun) { if (cachedSetTimeout === setTimeout) { //normal enviroments in sane situations return setTimeout(fun, 0); } // if setTimeout wasn't available but was latter defined if ((cachedSetTimeout === defaultSetTimout || !cachedSetTimeout) && setTimeout) { cachedSetTimeout = setTimeout; return setTimeout(fun, 0); } try { // when when somebody has screwed with setTimeout but no I.E. maddness return cachedSetTimeout(fun, 0); } catch(e){ try { // When we are in I.E. but the script has been evaled so I.E. doesn't trust the global object when called normally return cachedSetTimeout.call(null, fun, 0); } catch(e){ // same as above but when it's a version of I.E. that must have the global object for 'this', hopfully our context correct otherwise it will throw a global error return cachedSetTimeout.call(this, fun, 0); } } } function runClearTimeout(marker) { if (cachedClearTimeout === clearTimeout) { //normal enviroments in sane situations return clearTimeout(marker); } // if clearTimeout wasn't available but was latter defined if ((cachedClearTimeout === defaultClearTimeout || !cachedClearTimeout) && clearTimeout) { cachedClearTimeout = clearTimeout; return clearTimeout(marker); } try { // when when somebody has screwed with setTimeout but no I.E. maddness return cachedClearTimeout(marker); } catch (e){ try { // When we are in I.E. but the script has been evaled so I.E. doesn't trust the global object when called normally return cachedClearTimeout.call(null, marker); } catch (e){ // same as above but when it's a version of I.E. that must have the global object for 'this', hopfully our context correct otherwise it will throw a global error. // Some versions of I.E. have different rules for clearTimeout vs setTimeout return cachedClearTimeout.call(this, marker); } } } var queue = []; var draining = false; var currentQueue; var queueIndex = -1; function cleanUpNextTick() { if (!draining || !currentQueue) { return; } draining = false; if (currentQueue.length) { queue = currentQueue.concat(queue); } else { queueIndex = -1; } if (queue.length) { drainQueue(); } } function drainQueue() { if (draining) { return; } var timeout = runTimeout(cleanUpNextTick); draining = true; var len = queue.length; while(len) { currentQueue = queue; queue = []; while (++queueIndex < len) { if (currentQueue) { currentQueue[queueIndex].run(); } } queueIndex = -1; len = queue.length; } currentQueue = null; draining = false; runClearTimeout(timeout); } process.nextTick = function (fun) { var args = new Array(arguments.length - 1); if (arguments.length > 1) { for (var i = 1; i < arguments.length; i++) { args[i - 1] = arguments[i]; } } queue.push(new Item(fun, args)); if (queue.length === 1 && !draining) { runTimeout(drainQueue); } }; // v8 likes predictible objects function Item(fun, array) { this.fun = fun; this.array = array; } Item.prototype.run = function () { this.fun.apply(null, this.array); }; process.title = 'browser'; process.browser = true; process.env = {}; process.argv = []; process.version = ''; // empty string to avoid regexp issues process.versions = {}; function noop() {} process.on = noop; process.addListener = noop; process.once = noop; process.off = noop; process.removeListener = noop; process.removeAllListeners = noop; process.emit = noop; process.binding = function (name) { throw new Error('process.binding is not supported'); }; process.cwd = function () { return '/' }; process.chdir = function (dir) { throw new Error('process.chdir is not supported'); }; process.umask = function() { return 0; }; /***/ }), /* 14 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; /* WEBPACK VAR INJECTION */(function(process) { Object.defineProperty(exports, "__esModule", { value: true }); var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); var _events = __webpack_require__(8); var _events2 = _interopRequireDefault(_events); var _get = __webpack_require__(54); var _get2 = _interopRequireDefault(_get); var _isFunction = __webpack_require__(11); var _isFunction2 = _interopRequireDefault(_isFunction); var _VisibilityChangeEmitter = __webpack_require__(15); var _VisibilityChangeEmitter2 = _interopRequireDefault(_VisibilityChangeEmitter); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; } function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } /* global window */ var debug = __webpack_require__(7)('latency-monitor:LatencyMonitor'); /** * @typedef {Object} SummaryObject * @property {Number} events How many events were called * @property {Number} minMS What was the min time for a cb to be called * @property {Number} maxMS What was the max time for a cb to be called * @property {Number} avgMs What was the average time for a cb to be called * @property {Number} lengthMs How long this interval was in ms */ /** * A class to monitor latency of any async function which works in a browser or node. This works by periodically calling * the asyncTestFn and timing how long it takes the callback to be called. It can also periodically emit stats about this. * This can be disabled and stats can be pulled via setting dataEmitIntervalMs = 0. * * The default implementation is an event loop latency monitor. This works by firing periodic events into the event loop * and timing how long it takes to get back. * * @example * const monitor = new LatencyMonitor(); * monitor.on('data', (summary) => console.log('Event Loop Latency: %O', summary)); * * @example * const monitor = new LatencyMonitor({latencyCheckIntervalMs: 1000, dataEmitIntervalMs: 60000, asyncTestFn:ping}); * monitor.on('data', (summary) => console.log('Ping Pong Latency: %O', summary)); */ var LatencyMonitor = function (_EventEmitter) { _inherits(LatencyMonitor, _EventEmitter); /** * @param {Number} [latencyCheckIntervalMs=500] How often to add a latency check event (ms) * @param {Number} [dataEmitIntervalMs=5000] How often to summarize latency check events. null or 0 disables event firing * @param {function} [asyncTestFn] What cb-style async function to use * @param {Number} [latencyRandomPercentage=5] What percent (+/-) of latencyCheckIntervalMs should we randomly use? This helps avoid alignment to other events. */ function LatencyMonitor() { var _ref = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}, latencyCheckIntervalMs = _ref.latencyCheckIntervalMs, dataEmitIntervalMs = _ref.dataEmitIntervalMs, asyncTestFn = _ref.asyncTestFn, latencyRandomPercentage = _ref.latencyRandomPercentage; _classCallCheck(this, LatencyMonitor); var _this = _possibleConstructorReturn(this, (LatencyMonitor.__proto__ || Object.getPrototypeOf(LatencyMonitor)).call(this)); var that = _this; // 0 isn't valid here, so its ok to use || that.latencyCheckIntervalMs = latencyCheckIntervalMs || 500; // 0.5s that.latencyRandomPercentage = latencyRandomPercentage || 10; that._latecyCheckMultiply = 2 * (that.latencyRandomPercentage / 100.0) * that.latencyCheckIntervalMs; that._latecyCheckSubtract = that._latecyCheckMultiply / 2; that.dataEmitIntervalMs = dataEmitIntervalMs === null || dataEmitIntervalMs === 0 ? undefined : dataEmitIntervalMs || 5 * 1000; // 5s debug('latencyCheckIntervalMs: %s dataEmitIntervalMs: %s', that.latencyCheckIntervalMs, that.dataEmitIntervalMs); if (that.dataEmitIntervalMs) { debug('Expecting ~%s events per summary', that.latencyCheckIntervalMs / that.dataEmitIntervalMs); } else { debug('Not emitting summaries'); } that.asyncTestFn = asyncTestFn; // If there is no asyncFn, we measure latency // If process: use high resolution timer if (process && process.hrtime) { debug('Using process.hrtime for timing'); that.now = process.hrtime; that.getDeltaMS = function (startTime) { var hrtime = that.now(startTime); return hrtime[0] * 1000 + hrtime[1] / 1000000; }; // Let's try for a timer that only monotonically increases } else if (typeof window !== 'undefined' && (0, _get2.default)(window, 'performance.now')) { debug('Using performance.now for timing'); that.now = window.performance.now.bind(window.performance); that.getDeltaMS = function (startTime) { return Math.round(that.now() - startTime); }; } else { debug('Using Date.now for timing'); that.now = Date.now; that.getDeltaMS = function (startTime) { return that.now() - startTime; }; } that._latencyData = that._initLatencyData(); // We check for isBrowser because of browsers set max rates of timeouts when a page is hidden, // so we fall back to another library // See: http://stackoverflow.com/questions/6032429/chrome-timeouts-interval-suspended-in-background-tabs if (isBrowser()) { that._visibilityChangeEmitter = new _VisibilityChangeEmitter2.default(); that._visibilityChangeEmitter.on('visibilityChange', function (pageInFocus) { if (pageInFocus) { that._startTimers(); } else { that._emitSummary(); that._stopTimers(); } }); } if (!that._visibilityChangeEmitter || that._visibilityChangeEmitter.isVisible()) { that._startTimers(); } return _this; } /** * Start internal timers * @private */ _createClass(LatencyMonitor, [{ key: '_startTimers', value: function _startTimers() { var _this2 = this; // Timer already started, ignore this if (this._checkLatencyID) { return; } this._checkLatency(); if (this.dataEmitIntervalMs) { this._emitIntervalID = setInterval(function () { return _this2._emitSummary(); }, this.dataEmitIntervalMs); if ((0, _isFunction2.default)(this._emitIntervalID.unref)) { this._emitIntervalID.unref(); // Doesn't block exit } } } /** * Stop internal timers * @private */ }, { key: '_stopTimers', value: function _stopTimers() { if (this._checkLatencyID) { clearTimeout(this._checkLatencyID); this._checkLatencyID = undefined; } if (this._emitIntervalID) { clearInterval(this._emitIntervalID); this._emitIntervalID = undefined; } } /** * Emit summary only if there were events. It might not have any events if it was forced via a page hidden/show * @private */ }, { key: '_emitSummary', value: function _emitSummary() { var summary = this.getSummary(); if (summary.events > 0) { this.emit('data', summary); } } /** * Calling this function will end the collection period. If a timing event was already fired and somewhere in the queue, * it will not count for this time period * @returns {SummaryObject} */ }, { key: 'getSummary', value: function getSummary() { // We might want to adjust for the number of expected events // Example: first 1 event it comes back, then such a long blocker that the next emit check comes // Then this fires - looks like no latency!! var latency = { events: this._latencyData.events, minMs: this._latencyData.minMs, maxMs: this._latencyData.maxMs, avgMs: this._latencyData.events ? this._latencyData.totalMs / this._latencyData.events : Number.POSITIVE_INFINITY, lengthMs: this.getDeltaMS(this._latencyData.startTime) }; this._latencyData = this._initLatencyData(); // Clear debug('Summary: %O', latency); return latency; } /** * Randomly calls an async fn every roughly latencyCheckIntervalMs (plus some randomness). If no async fn is found, * it will simply report on event loop latency. * * @private */ }, { key: '_checkLatency', value: function _checkLatency() { var _this3 = this; var that = this; // Randomness is needed to avoid alignment by accident to regular things in the event loop var randomness = Math.random() * that._latecyCheckMultiply - that._latecyCheckSubtract; // We use this to ensure that in case some overlap somehow, we don't take the wrong startTime/offset var localData = { deltaOffset: Math.ceil(that.latencyCheckIntervalMs + randomness), startTime: that.now() }; var cb = function cb() { // We are already stopped, ignore this datapoint if (!_this3._checkLatencyID) { return; } var deltaMS = that.getDeltaMS(localData.startTime) - localData.deltaOffset; that._checkLatency(); // Start again ASAP // Add the data point. If this gets complex, refactor it that._latencyData.events++; that._latencyData.minMs = Math.min(that._latencyData.minMs, deltaMS); that._latencyData.maxMs = Math.max(that._latencyData.maxMs, deltaMS); that._latencyData.totalMs += deltaMS; debug('MS: %s Data: %O', deltaMS, that._latencyData); }; debug('localData: %O', localData); this._checkLatencyID = setTimeout(function () { // This gets rid of including event loop if (that.asyncTestFn) { // Clear timing related things localData.deltaOffset = 0; localData.startTime = that.now(); that.asyncTestFn(cb); } else { // setTimeout is not more accurate than 1ms, so this will ensure positive numbers. Add 1 to emitted data to remove. // This is not the best, but for now it'll be just fine. This isn't meant to be sub ms accurate. localData.deltaOffset -= 1; // If there is no function to test, we mean check latency which is a special case that is really cb => cb() // We avoid that for the few extra function all overheads. Also, we want to keep the timers different cb(); } }, localData.deltaOffset); if ((0, _isFunction2.default)(this._checkLatencyID.unref)) { this._checkLatencyID.unref(); // Doesn't block exit } } }, { key: '_initLatencyData', value: function _initLatencyData() { return { startTime: this.now(), minMs: Number.POSITIVE_INFINITY, maxMs: Number.NEGATIVE_INFINITY, events: 0, totalMs: 0 }; } }]); return LatencyMonitor; }(_events2.default); function isBrowser() { return typeof window !== 'undefined'; } exports.default = LatencyMonitor; /* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(13))) /***/ }), /* 15 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); var _events = __webpack_require__(8); var _events2 = _interopRequireDefault(_events); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; } function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } /* global document */ var debug = __webpack_require__(7)('latency-monitor:VisibilityChangeEmitter'); /** * Listen to page visibility change events (i.e. when the page is focused / blurred) by an event emitter. * * Warning: This does not work on all browsers, but should work on all modern browsers * * @example * * const myVisibilityEmitter = new VisibilityChangeEmitter(); * * myVisibilityEmitter.on('visibilityChange', (pageInFocus) => { * if ( pageInFocus ){ * // Page is in focus * console.log('In focus'); * } * else { * // Page is blurred * console.log('Out of focus'); * } * }); * // To access the visibility state directly, call: * console.log('Am I focused now? ' + myVisibilityEmitter.isVisible()); * * @class VisibilityChangeEmitter */ var VisibilityChangeEmitter = function (_EventEmitter) { _inherits(VisibilityChangeEmitter, _EventEmitter); /** * Creates a VisibilityChangeEmitter */ function VisibilityChangeEmitter() { _classCallCheck(this, VisibilityChangeEmitter); var _this = _possibleConstructorReturn(this, (VisibilityChangeEmitter.__proto__ || Object.getPrototypeOf(VisibilityChangeEmitter)).call(this)); if (typeof document === 'undefined') { debug('This is not a browser, no "document" found. Stopping.'); return _possibleConstructorReturn(_this); } _this._initializeVisibilityVarNames(); _this._addVisibilityChangeListener(); return _this; } /** * document.hidden and document.visibilityChange are the two variables we need to check for; * Since these variables are named differently in different browsers, this function sets * the appropriate name based on the browser being used. Once executed, tha actual names of * document.hidden and document.visibilityChange are found in this._hidden and this._visibilityChange * respectively * @private */ _createClass(VisibilityChangeEmitter, [{ key: '_initializeVisibilityVarNames', value: function _initializeVisibilityVarNames() { var hidden = void 0; var visibilityChange = void 0; if (typeof document.hidden !== 'undefined') { // Opera 12.10 and Firefox 18 and later support hidden = 'hidden'; visibilityChange = 'visibilitychange'; } else if (typeof document.mozHidden !== 'undefined') { hidden = 'mozHidden'; visibilityChange = 'mozvisibilitychange'; } else if (typeof document.msHidden !== 'undefined') { hidden = 'msHidden'; visibilityChange = 'msvisibilitychange'; } else if (typeof document.webkitHidden !== 'undefined') { hidden = 'webkitHidden'; visibilityChange = 'webkitvisibilitychange'; } this._hidden = hidden; this._visibilityChange = visibilityChange; } /** * Adds an event listener on the document that listens to changes in document.visibilityChange * (or whatever name by which the visibilityChange variable is known in the browser) * @private */ }, { key: '_addVisibilityChangeListener', value: function _addVisibilityChangeListener() { if (typeof document.addEventListener === 'undefined' || typeof document[this._hidden] === 'undefined') { debug('Checking page visibility requires a browser that supports the Page Visibility API.'); } else { // Handle page visibility change document.addEventListener(this._visibilityChange, this._handleVisibilityChange.bind(this), false); } } /** * The function returns ```true``` if the page is visible or ```false``` if the page is not visible and * ```undefined``` if the page visibility API is not supported by the browser. * @returns {Boolean|void} whether the page is now visible or not (undefined is unknown) */ }, { key: 'isVisible', value: function isVisible() { if (this._hidden === undefined || document[this._hidden] === undefined) { return undefined; } return !document[this._hidden]; } /** * The function that is called when document.visibilityChange has changed * It emits an event called visibilityChange and sends the value of document.hidden as a * parameter * * @private */ }, { key: '_handleVisibilityChange', value: function _handleVisibilityChange() { var visible = !document[this._hidden]; debug(visible ? 'Page Visible' : 'Page Hidden'); // Emit the event this.emit('visibilityChange', visible); } }]); return VisibilityChangeEmitter; }(_events2.default); exports.default = VisibilityChangeEmitter; /***/ }), /* 16 */ /***/ (function(module, exports, __webpack_require__) { /** * This is the common logic for both the Node.js and web browser * implementations of `debug()`. * * Expose `debug()` as the module. */ exports = module.exports = createDebug.debug = createDebug.default = createDebug; exports.coerce = coerce; exports.disable = disable; exports.enable = enable; exports.enabled = enabled; exports.humanize = __webpack_require__(58); /** * The currently active debug mode names, and names to skip. */ exports.names = []; exports.skips = []; /** * Map of special "%n" handling functions, for the debug "format" argument. * * Valid key names are a single, lower or upper-case letter, i.e. "n" and "N". */ exports.formatters = {}; /** * Previous log timestamp. */ var prevTime; /** * Select a color. * @param {String} namespace * @return {Number} * @api private */ function selectColor(namespace) { var hash = 0, i; for (i in namespace) { hash = ((hash << 5) - hash) + namespace.charCodeAt(i); hash |= 0; // Convert to 32bit integer } return exports.colors[Math.abs(hash) % exports.colors.length]; } /** * Create a debugger with the given `namespace`. * * @param {String} namespace * @return {Function} * @api public */ function createDebug(namespace) { function debug() { // disabled? if (!debug.enabled) return; var self = debug; // set `diff` timestamp var curr = +new Date(); var ms = curr - (prevTime || curr); self.diff = ms; self.prev = prevTime; self.curr = curr; prevTime = curr; // turn the `arguments` into a proper Array var args = new Array(arguments.length); for (var i = 0; i < args.l