Comparing version 2.2.0 to 2.2.1
312
lib/index.js
@@ -6,289 +6,65 @@ 'use strict'; | ||
}); | ||
exports.middleware = exports.timeCallback = exports.callback = exports.timePromise = exports.promise = exports.timeSync = exports.sync = exports.isWrapped = undefined; | ||
exports.createDecorator = createDecorator; | ||
exports.isWrapped = exports.createDecorator = undefined; | ||
var _debug = require('debug'); | ||
var _sync = require('./sync'); | ||
var _debug2 = _interopRequireDefault(_debug); | ||
var _assert = require('assert'); | ||
var _assert2 = _interopRequireDefault(_assert); | ||
var _findLastIndex = require('lodash/findLastIndex'); | ||
var _findLastIndex2 = _interopRequireDefault(_findLastIndex); | ||
var _round = require('lodash/round'); | ||
var _round2 = _interopRequireDefault(_round); | ||
var _onFinished = require('on-finished'); | ||
var _onFinished2 = _interopRequireDefault(_onFinished); | ||
var _mimicFn = require('mimic-fn'); | ||
var _mimicFn2 = _interopRequireDefault(_mimicFn); | ||
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } | ||
var debug = (0, _debug2.default)('derf'); | ||
var DERFED = Symbol('derfed'); | ||
function hrToNano(hr) { | ||
return hr[0] * 1e9 + hr[1]; | ||
} | ||
// the default message to display | ||
function defaultPrinter(print, time, callArgs, retArgs) { | ||
var displayTime = (0, _round2.default)(time / 1e6, 2) + 'ms'; | ||
if (retArgs[0]) { | ||
print('failed in %s', displayTime); | ||
} else { | ||
print('finished in %s', displayTime); | ||
} | ||
} | ||
function createDecorator(type) { | ||
var printer = arguments.length <= 1 || arguments[1] === undefined ? defaultPrinter : arguments[1]; | ||
return function decorate(namespace) { | ||
return function decorator(target, key, descriptor) { | ||
if (typeof target === 'function') { | ||
debug('cannot wrap class, skipping'); | ||
return target; | ||
} | ||
if (typeof target.value !== 'function') { | ||
debug('cannot wrap non-function, skipping'); | ||
return descriptor; | ||
} | ||
descriptor.value = type(namespace, descriptor.value, printer); | ||
return descriptor; | ||
}; | ||
}; | ||
} | ||
// wraps all our handler function to take care of some common patterns | ||
function wrap(handler) { | ||
return function (namespace, fn) { | ||
var printer = arguments.length <= 2 || arguments[2] === undefined ? defaultPrinter : arguments[2]; | ||
// 'cast' namespace to be a debug function | ||
var fnDebug = typeof namespace === 'function' ? namespace : (0, _debug2.default)(namespace); | ||
// noop if debug is not enabled | ||
if (!fnDebug.enabled) { | ||
return fn; | ||
Object.keys(_sync).forEach(function (key) { | ||
if (key === "default") return; | ||
Object.defineProperty(exports, key, { | ||
enumerable: true, | ||
get: function get() { | ||
return _sync[key]; | ||
} | ||
}); | ||
}); | ||
// validate args if enabled, but only warn here if it fails | ||
try { | ||
(0, _assert2.default)(typeof fn === 'function', 'expected a function to wrap'); | ||
(0, _assert2.default)(typeof printer === 'function', 'expected function for printing'); | ||
} catch (e) { | ||
console.warn('derf ' + e.message); // eslint-disable-line no-console | ||
return fn; | ||
} | ||
var _promise = require('./promise'); | ||
// it should be impossible to throw from logging | ||
var print = function print(start, args, retArgs) { | ||
try { | ||
var diff = hrToNano(process.hrtime(start)); | ||
printer(fnDebug, diff, args, retArgs); | ||
} catch (e) { | ||
debug('derf printer threw an error %s', e && e.stack); | ||
/* noop */ | ||
} | ||
}; | ||
// mimic original function because the name and arity might matter | ||
var wrappedFn = handler(fn, print); | ||
(0, _mimicFn2.default)(wrappedFn, fn); | ||
// mark it with a symbol so it's possible to tell the difference | ||
wrappedFn[DERFED] = true; | ||
return wrappedFn; | ||
}; | ||
} | ||
var isWrapped = exports.isWrapped = function isWrapped(fn) { | ||
return !!fn && !!fn[DERFED]; | ||
}; | ||
/** | ||
* Wrap a synchronous function | ||
* @param {String|Function} namespace | ||
* @param {Function} fn - to wrap | ||
* @param {Function} printer - to customize logs | ||
*/ | ||
var sync = exports.sync = wrap(function (fn, print) { | ||
debug('wrapping sync function: %s', fn.name || 'anonymous'); | ||
return function perfWrappedSync() { | ||
var err = undefined; | ||
var val = undefined; | ||
var start = process.hrtime(); | ||
for (var _len = arguments.length, args = Array(_len), _key = 0; _key < _len; _key++) { | ||
args[_key] = arguments[_key]; | ||
Object.keys(_promise).forEach(function (key) { | ||
if (key === "default") return; | ||
Object.defineProperty(exports, key, { | ||
enumerable: true, | ||
get: function get() { | ||
return _promise[key]; | ||
} | ||
try { | ||
val = fn.apply(this, args); | ||
} catch (e) { | ||
err = e; | ||
} finally { | ||
print(start, args, [err, val]); | ||
} | ||
if (err) { | ||
throw err; | ||
} else { | ||
return val; | ||
} | ||
}; | ||
}); | ||
}); | ||
var timeSync = exports.timeSync = createDecorator(sync); | ||
var _callback = require('./callback'); | ||
/** | ||
* Wrap a promise returning function | ||
* @param {String|Function} namespace | ||
* @param {Function} fn - to wrap | ||
* @param {Function} printer - to customize logs | ||
*/ | ||
var promise = exports.promise = wrap(function (fn, print) { | ||
debug('wrapping promise function: %s', fn.name || 'anonymous'); | ||
return function perfWrappedPromise() { | ||
for (var _len2 = arguments.length, args = Array(_len2), _key2 = 0; _key2 < _len2; _key2++) { | ||
args[_key2] = arguments[_key2]; | ||
Object.keys(_callback).forEach(function (key) { | ||
if (key === "default") return; | ||
Object.defineProperty(exports, key, { | ||
enumerable: true, | ||
get: function get() { | ||
return _callback[key]; | ||
} | ||
var start = process.hrtime(); | ||
var ret = fn.apply(this, args); | ||
// common case where a thennable is returned | ||
if (ret && ret.then) { | ||
return ret.then(function (val) { | ||
print(start, args, [undefined, val]); | ||
return val; // return val | ||
}, function (err) { | ||
print(start, args, [err, undefined]); | ||
throw err; // rethrow err | ||
}); | ||
} | ||
// it wasn't a promise. great job. | ||
debug('no promise returned from wrapped promise function. not logging'); | ||
return ret; | ||
}; | ||
}); | ||
}); | ||
var timePromise = exports.timePromise = createDecorator(sync); | ||
var _middleware = require('./middleware'); | ||
/** | ||
* Wrap a node-style callback function | ||
* @param {String|Function} namespace | ||
* @param {Function} fn - to wrap | ||
* @param {Function} printer - to customize logs | ||
*/ | ||
var callback = exports.callback = wrap(function (fn, print) { | ||
debug('wrapping callback function: %s', fn.name || 'anonymous'); | ||
return function perfWrappedCallback() { | ||
for (var _len3 = arguments.length, args = Array(_len3), _key3 = 0; _key3 < _len3; _key3++) { | ||
args[_key3] = arguments[_key3]; | ||
Object.keys(_middleware).forEach(function (key) { | ||
if (key === "default") return; | ||
Object.defineProperty(exports, key, { | ||
enumerable: true, | ||
get: function get() { | ||
return _middleware[key]; | ||
} | ||
// most function have the callback last, but just in case... | ||
var index = (0, _findLastIndex2.default)(args, function (arg) { | ||
return typeof arg === 'function'; | ||
}); | ||
if (index >= 0) { | ||
(function () { | ||
debug('wrapping callback at arguments[%s]', index); | ||
var start = process.hrtime(); | ||
var cb = args[index]; | ||
args[index] = function perfWrappedCb() { | ||
for (var _len4 = arguments.length, retArgs = Array(_len4), _key4 = 0; _key4 < _len4; _key4++) { | ||
retArgs[_key4] = arguments[_key4]; | ||
} | ||
print(start, args, retArgs); | ||
return cb.apply(this, retArgs); | ||
}; | ||
})(); | ||
} else { | ||
// no callback at all. Wow.. | ||
debug('no callback passed to wrapped callback function. not logging'); | ||
} | ||
return fn.apply(this, args); | ||
}; | ||
}); | ||
}); | ||
var timeCallback = exports.timeCallback = createDecorator(sync); | ||
var _utils = require('./utils'); | ||
/** | ||
* Wrap an express middleware function | ||
* @param {String|Function} namespace | ||
* @param {Function} fn - to wrap | ||
* @param {Function} printer - to customize logs | ||
*/ | ||
var middleware = exports.middleware = wrap(function (fn, print) { | ||
debug('wrapping express middleware: %s', fn.name || 'anonymous'); | ||
var arity = fn.length; | ||
// normal middleware? | ||
if (arity <= 3) { | ||
debug('%s args, is normal middleware', arity); | ||
return function perfWrappedMiddleware(req, res, next) { | ||
var start = process.hrtime(); | ||
var finished = false; | ||
function log() { | ||
if (!finished) { | ||
finished = true; | ||
// dont try to guess the retArgs | ||
print(start, [req, res], [undefined, undefined]); | ||
} | ||
} | ||
(0, _onFinished2.default)(res, log); | ||
return fn.call(this, req, res, function wrappedNext() { | ||
log(); | ||
next.apply(this, arguments); // eslint-disable-line prefer-rest-params | ||
}); | ||
}; | ||
Object.defineProperty(exports, 'createDecorator', { | ||
enumerable: true, | ||
get: function get() { | ||
return _utils.createDecorator; | ||
} | ||
}); | ||
// must be error middleware | ||
debug('%s args, is error middleware', arity); | ||
return function perfWrappedErrorMiddleware(err, req, res, next) { | ||
var start = process.hrtime(); | ||
var finished = false; | ||
var _constants = require('./constants'); | ||
function log() { | ||
if (!finished) { | ||
finished = true; | ||
// dont try to guess the retArgs | ||
print(start, [err, req, res], [undefined, undefined]); | ||
} | ||
} | ||
(0, _onFinished2.default)(res, log); | ||
return fn.call(this, err, req, res, function wrappedNext() { | ||
log(); | ||
next.apply(this, arguments); // eslint-disable-line prefer-rest-params | ||
}); | ||
}; | ||
}); | ||
var isWrapped = exports.isWrapped = function isWrapped(fn) { | ||
return !!fn && !!fn[_constants.DERFED]; | ||
}; |
{ | ||
"name": "derf", | ||
"version": "2.2.0", | ||
"version": "2.2.1", | ||
"description": "A javascript performance debugger.", | ||
@@ -5,0 +5,0 @@ "main": "lib/index.js", |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
19373
12
332
1