Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

derf

Package Overview
Dependencies
Maintainers
1
Versions
14
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

derf - npm Package Compare versions

Comparing version 2.2.0 to 2.2.1

lib/callback.js

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",

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc