Merge pull request #96 from TooTallNate/rewrite/share-node-browser-logic

Rewrite: abstract the common logic between Node.js and the browser
This commit is contained in:
Nathan Rajlich 2014-05-31 10:44:11 -07:00
commit 1fd62b0d86
7 changed files with 253 additions and 234 deletions

3
.jshintrc Normal file
View File

@ -0,0 +1,3 @@
{
"laxbreak": true
}

69
browser.js Normal file
View File

@ -0,0 +1,69 @@
/**
* This is the web browser implementation of `debug()`.
*
* Expose `debug()` as the module.
*/
exports = module.exports = require('./debug');
exports.log = log;
exports.save = save;
exports.load = load;
/**
* Invokes `console.log()` when available.
* No-op when `console.log` is not a "function".
*
* @api public
*/
function log(fmt) {
var curr = new Date();
var ms = curr - (this.prev || curr);
this.prev = curr;
fmt = this.namespace
+ ' '
+ fmt
+ ' +' + exports.humanize(ms);
// This hackery is required for IE8,
// where the `console.log` function doesn't have 'apply'
return 'object' == typeof console
&& 'function' == typeof console.log
&& Function.prototype.apply.call(console.log, console, arguments);
}
/**
* Save `namespaces`.
*
* @param {String} namespaces
* @api private
*/
function save(namespaces) {
try {
localStorage.debug = namespaces;
} catch(e) {}
}
/**
* Load `namespaces`.
*
* @return {String} returns the previously persisted debug modes
* @api private
*/
function load() {
var r;
try {
r = localStorage.debug;
} catch(e) {}
return r;
}
/**
* Enable namespaces listed in `localStorage.debug` initially.
*/
exports.enable(load());

View File

@ -2,9 +2,12 @@
"name": "debug",
"repo": "visionmedia/debug",
"description": "small debugging utility",
"version": "0.7.4",
"version": "0.8.1",
"keywords": ["debug", "log", "debugger"],
"main": "debug.js",
"scripts": ["debug.js"],
"main": "browser.js",
"scripts": [
"browser.js",
"debug.js"
],
"dependencies": {}
}

132
debug.js
View File

@ -1,74 +1,77 @@
/**
* This is the common logic for both the Node.js and web browser
* implementations of `debug()`.
*
* Expose `debug()` as the module.
*/
module.exports = debug;
exports = module.exports = debug;
exports.coerce = coerce;
exports.disable = disable;
exports.enable = enable;
exports.enabled = enabled;
exports.humanize = humanize;
/**
* Create a debugger with the given `name`.
* The currently active debug mode names, and names to skip.
*/
exports.names = [];
exports.skips = [];
/**
* Create a debugger with the given `namespace`.
*
* @param {String} name
* @return {Type}
* @param {String} namespace
* @return {Function}
* @api public
*/
function debug(name) {
if (!debug.enabled(name)) return function(){};
function debug(namespace) {
return function(fmt){
fmt = coerce(fmt);
var curr = new Date;
var ms = curr - (debug[name] || curr);
debug[name] = curr;
fmt = name
+ ' '
+ fmt
+ ' +' + debug.humanize(ms);
// This hackery is required for IE8
// where `console.log` doesn't have 'apply'
window.console
&& console.log
&& Function.prototype.apply.call(console.log, console, arguments);
// define the `disabled` version
function disabled() {
}
disabled.enabled = false;
// define the `enabled` version
function enabled(fmt) {
fmt = exports.coerce(fmt);
exports.log.apply(enabled, arguments);
}
enabled.enabled = true;
var fn = exports.enabled(namespace) ? enabled : disabled;
fn.namespace = namespace;
return fn;
}
/**
* The currently active debug mode names.
*/
debug.names = [];
debug.skips = [];
/**
* Enables a debug mode by name. This can include modes
* Enables a debug mode by namespaces. This can include modes
* separated by a colon and wildcards.
*
* @param {String} name
* @param {String} namespaces
* @api public
*/
debug.enable = function(name) {
try {
localStorage.debug = name;
} catch(e){}
function enable(namespaces) {
exports.save(namespaces);
var split = (name || '').split(/[\s,]+/)
, len = split.length;
var split = (namespaces || '').split(/[\s,]+/);
var len = split.length;
for (var i = 0; i < len; i++) {
name = split[i].replace('*', '.*?');
if (name[0] === '-') {
debug.skips.push(new RegExp('^' + name.substr(1) + '$'));
}
else {
debug.names.push(new RegExp('^' + name + '$'));
namespaces = split[i].replace('*', '.*?');
if (namespaces[0] === '-') {
exports.skips.push(new RegExp('^' + namespaces.substr(1) + '$'));
} else {
exports.names.push(new RegExp('^' + namespaces + '$'));
}
}
};
}
/**
* Disable debug output.
@ -76,9 +79,9 @@ debug.enable = function(name) {
* @api public
*/
debug.disable = function(){
debug.enable('');
};
function disable() {
exports.enable('');
}
/**
* Humanize the given `ms`.
@ -88,16 +91,16 @@ debug.disable = function(){
* @api private
*/
debug.humanize = function(ms) {
var sec = 1000
, min = 60 * 1000
, hour = 60 * min;
function humanize(ms) {
var sec = 1000;
var min = 60 * 1000;
var hour = 60 * min;
if (ms >= hour) return (ms / hour).toFixed(1) + 'h';
if (ms >= min) return (ms / min).toFixed(1) + 'm';
if (ms >= sec) return (ms / sec | 0) + 's';
return ms + 'ms';
};
}
/**
* Returns true if the given mode name is enabled, false otherwise.
@ -107,31 +110,30 @@ debug.humanize = function(ms) {
* @api public
*/
debug.enabled = function(name) {
for (var i = 0, len = debug.skips.length; i < len; i++) {
if (debug.skips[i].test(name)) {
function enabled(name) {
var i, len;
for (i = 0, len = exports.skips.length; i < len; i++) {
if (exports.skips[i].test(name)) {
return false;
}
}
for (var i = 0, len = debug.names.length; i < len; i++) {
if (debug.names[i].test(name)) {
for (i = 0, len = exports.names.length; i < len; i++) {
if (exports.names[i].test(name)) {
return true;
}
}
return false;
};
}
/**
* Coerce `val`.
*
* @param {Mixed} val
* @return {Mixed}
* @api private
*/
function coerce(val) {
if (val instanceof Error) return val.stack || val.message;
return val;
}
// persist
try {
if (window.localStorage) debug.enable(localStorage.debug);
} catch(e){}

View File

@ -1,158 +0,0 @@
/**
* Module dependencies.
*/
var tty = require('tty');
/**
* Expose `debug()` as the module.
*/
module.exports = debug;
/**
* Enabled debuggers.
*/
var names = []
, skips = [];
/**
* Colors.
*/
var colors = [6, 2, 3, 4, 5, 1];
/**
* Previous debug() call.
*/
var prev = {};
/**
* Previously assigned color.
*/
var prevColor = 0;
/**
* Is stdout a TTY? Colored output is disabled when `true`.
*/
var isatty = tty.isatty(1);
/**
* Select a color.
*
* @return {Number}
* @api private
*/
function color() {
return colors[prevColor++ % colors.length];
}
/**
* Humanize the given `ms`.
*
* @param {Number} m
* @return {String}
* @api private
*/
function humanize(ms) {
var sec = 1000
, min = 60 * 1000
, hour = 60 * min;
if (ms >= hour) return (ms / hour).toFixed(1) + 'h';
if (ms >= min) return (ms / min).toFixed(1) + 'm';
if (ms >= sec) return (ms / sec | 0) + 's';
return ms + 'ms';
}
/**
* Create a debugger with the given `name`.
*
* @param {String} name
* @return {Type}
* @api public
*/
function debug(name) {
function disabled(){}
disabled.enabled = false;
var match = skips.some(function(re){
return re.test(name);
});
if (match) return disabled;
match = names.some(function(re){
return re.test(name);
});
if (!match) return disabled;
var c = color();
function colored(fmt) {
fmt = coerce(fmt);
var curr = new Date;
var ms = curr - (prev[name] || curr);
prev[name] = curr;
fmt = ' \u001b[9' + c + 'm' + name + ' '
+ '\u001b[3' + c + 'm\u001b[90m'
+ fmt + '\u001b[3' + c + 'm'
+ ' +' + humanize(ms) + '\u001b[0m';
console.log.apply(this, arguments);
}
function plain(fmt) {
fmt = coerce(fmt);
fmt = new Date().toUTCString()
+ ' ' + name + ' ' + fmt;
console.log.apply(this, arguments);
}
colored.enabled = plain.enabled = true;
return isatty || process.env.DEBUG_COLORS
? colored
: plain;
}
/**
* Coerce `val`.
*/
function coerce(val) {
if (val instanceof Error) return val.stack || val.message;
return val;
}
/**
* Enable specified `namespaces` for debugging.
*/
debug.enable = function(namespaces) {
namespaces.split(/[\s,]+/)
.forEach(function(name){
name = name.replace('*', '.*?');
if (name[0] == '-') {
skips.push(new RegExp('^' + name.substr(1) + '$'));
} else {
names.push(new RegExp('^' + name + '$'));
}
});
};
/**
* Enable namespaces listed in `process.env.DEBUG` initially.
*/
debug.enable(process.env.DEBUG || '');

104
node.js Normal file
View File

@ -0,0 +1,104 @@
/**
* Module dependencies.
*/
var tty = require('tty');
/**
* This is the Node.js implementation of `debug()`.
*
* Expose `debug()` as the module.
*/
exports = module.exports = require('./debug');
exports.log = log;
exports.save = save;
exports.load = load;
/**
* Colors.
*/
var colors = [6, 2, 3, 4, 5, 1];
/**
* Previously assigned color.
*/
var prevColor = 0;
/**
* Is stdout a TTY? Colored output is disabled when `true`.
*/
var useColors = tty.isatty(1) || process.env.DEBUG_COLORS;
/**
* Select a color.
*
* @return {Number}
* @api private
*/
function selectColor() {
return colors[prevColor++ % colors.length];
}
/**
* Invokes `console.log()` with the specified arguments,
* after adding ANSI color escape codes if enabled.
*
* @api public
*/
function log(fmt) {
var name = this.namespace;
if (useColors) {
if (null == this.c) this.c = selectColor();
var c = this.c;
var curr = new Date();
var ms = curr - (this.prev || curr);
this.prev = curr;
fmt = ' \u001b[9' + c + 'm' + name + ' '
+ '\u001b[3' + c + 'm\u001b[90m'
+ fmt + '\u001b[3' + c + 'm'
+ ' +' + exports.humanize(ms) + '\u001b[0m';
} else {
fmt = new Date().toUTCString()
+ ' ' + name + ' ' + fmt;
}
console.log.apply(console, arguments);
}
/**
* Save `namespaces
*
* @param {String} namespaces
* @api private
*/
function save(namespaces) {
process.env.DEBUG = namespaces;
}
/**
* Load `namespaces`.
*
* @return {String} returns the previously persisted debug modes
* @api private
*/
function load() {
return process.env.DEBUG;
}
/**
* Enable namespaces listed in `process.env.DEBUG` initially.
*/
exports.enable(load());

View File

@ -7,16 +7,12 @@
, "author": "TJ Holowaychuk <tj@vision-media.ca>"
, "dependencies": {}
, "devDependencies": { "mocha": "*" }
, "main": "lib/debug.js"
, "browser": "./debug.js"
, "engines": { "node": "*" }
, "files": [
"lib/debug.js",
"debug.js"
]
, "main": "./node.js"
, "browser": "./browser.js"
, "component": {
"scripts": {
"debug/index.js": "debug.js"
"debug/index.js": "browser.js"
, "debug/debug.js": "debug.js"
}
}
}