Comparing version 0.11.0 to 0.12.0
224
anylogger.js
@@ -9,131 +9,109 @@ /** | ||
*/ | ||
(function(m,a){ | ||
// stores log modules keyed by name | ||
m = Object.create(null), | ||
/** | ||
* anylogger([name] [, config]) => function logger([level='log'] [, ...args]) | ||
* | ||
* The main `anylogger` function creates a new or returns an existing logger | ||
* with the given `name`. It maintains a registry of all created loggers, | ||
* which it returns when called without a name, or with an empty name. | ||
* | ||
* If anylogger needs to create a new logger, it invokes | ||
* [`anylogger.create`](#anyloggercreate). | ||
* | ||
* @param name {String} The name of the logger to create | ||
* @param config {Object} An optional config object | ||
* | ||
* @returns A logger with the given `name` and `config`. | ||
*/ | ||
a = function(n,c){ | ||
// return the existing logger, or create a new one. if no name was given, return all loggers | ||
return n ? m[n] || (m[n] = a.create(n,c)) : m | ||
} | ||
// stores log modules keyed by name | ||
var m = Object.create(null) | ||
/** | ||
* `anylogger.levels` | ||
* | ||
* An object containing a mapping of level names to level values. | ||
* | ||
* In anylogger, a higher level of logging means more verbose logging: more | ||
* log messages will be generated. The lowest level of logging (none at all) | ||
* has value `0`. Higher levels have higher values. To be compliant with the | ||
* anylogger API, loggers should support at least the default levels, but | ||
* they may define additional levels and they may choose to use different | ||
* numeric values for these levels. | ||
* | ||
* You can replace or change this object to include levels corresponding with | ||
* those available in the framework you are writing an adapter for. Please | ||
* make sure to always include the default levels as well so all code can | ||
* rely on the 6 console methods `error`, `warn`, `info`, `log`, `debug` and | ||
* `trace` to always be there. | ||
*/ | ||
a.levels = {error:1, warn:2, info:3, log:4, debug:5, trace:6} | ||
/** | ||
* anylogger([name] [, config]) => function logger([level='log'] [, ...args]) | ||
* | ||
* The main `anylogger` function creates a new or returns an existing logger | ||
* with the given `name`. It maintains a registry of all created loggers, | ||
* which it returns when called without a name, or with an empty name. | ||
* | ||
* If anylogger needs to create a new logger, it invokes | ||
* [`anylogger.create`](#anyloggercreate). | ||
* | ||
* @param name {String} The name of the logger to create | ||
* @param config {Object} An optional config object | ||
* | ||
* @returns A logger with the given `name` and `config`. | ||
*/ | ||
var a = function(n,c){ | ||
// return the existing logger, or create a new one. if no name was given, return all loggers | ||
return n ? m[n] || (m[n] = a.new(n,c)) : m | ||
} | ||
/** | ||
* `anylogger.create(name, config)` | ||
/** | ||
* `anylogger.levels` | ||
* | ||
* An object containing a mapping of level names to level values. | ||
* | ||
* In anylogger, a higher level of logging means more verbose logging: more | ||
* log messages will be generated. The lowest level of logging (none at all) | ||
* has value `0`. Higher levels have higher values. To be compliant with the | ||
* anylogger API, loggers should support at least the default levels, but | ||
* they may define additional levels and they may choose to use different | ||
* numeric values for these levels. | ||
* | ||
* You can replace or change this object to include levels corresponding with | ||
* those available in the framework you are writing an adapter for. Please | ||
* make sure to always include the default levels as well so all code can | ||
* rely on the 6 console methods `error`, `warn`, `info`, `log`, `debug` and | ||
* `trace` to always be there. | ||
*/ | ||
a.levels = {error:1, warn:2, info:3, log:4, debug:5, trace:6} | ||
* Called when a logger needs to be created. * | ||
* Creates a new logger by calling `anylogger.new`, then extends it by calling | ||
* `anylogger.ext` on the result. | ||
* | ||
* You can replace this method with a custom factory, or leave this one in | ||
* place and instead override `anylogger.ext` and/or `anylogger.new` separately. | ||
* | ||
* @param name {String} The name of the logger to create | ||
* @param config {Object} An optional config object | ||
* | ||
* @returns A new logger with the given `name` and `config`. | ||
*/ | ||
a.create = function(n,c) { | ||
return a.ext(a.new(n,c)) | ||
} | ||
/** | ||
* `anylogger.new(name, config)` | ||
* | ||
* Called when a logger needs to be created. | ||
* Creates a new logger, then extends it by calling `anylogger.ext` on the result. | ||
* | ||
* @param name {String} The name of the logger to create | ||
* @param config {Object} An optional config object | ||
* | ||
* @returns A new logger with the given `name` and `config`. | ||
*/ | ||
a.new = function(n,c,r) { | ||
// use eval to create a named function, this method has best cross-browser | ||
// support and allows us to create functions with names containing symbols | ||
// such as ':', '-' etc which otherwise are not legal in identifiers. | ||
// the created function calls `anylogger.log` to call the actual log method | ||
eval("r={'" + n + "':function(){a.log(n,[].slice.call(arguments))}}[n]") | ||
// IE support: if the function name is not set, add a property manually | ||
// the logging methods will be added by anylogger.ext | ||
return a.ext(r.name ? r : Object.defineProperty(r, 'name', {get:function(){return n}})) | ||
} | ||
/** | ||
* `anylogger.new(name, config) => logger` | ||
* | ||
* Creates and returns a new named function that calls `anylogger.log` | ||
* to perform the log call to the correct logger method based on the | ||
* first argument given to it. | ||
* | ||
* @param name {String} The name of the logger to create | ||
* @param config {Object} An optional config object | ||
* | ||
* @return logger function log([level='log'], args) | ||
*/ | ||
a.new = function(n,c,r) { | ||
// use eval to create a named function, this method has best cross-browser | ||
// support and allows us to create functions with names containing symbols | ||
// such as ':', '-' etc which otherwise are not legal in identifiers. | ||
// the created function calls `anylogger.log` to call the actual log method | ||
eval("r={'" + n + "':function(){a.log(n,[].slice.call(arguments))}}[n]") | ||
// Object.defineProperty(r, 'out', {get:function(){return o}}) | ||
// IE support: if the function name is not set, add a property manually | ||
return r.name ? r : Object.defineProperty(r, 'name', {get:function(){return n}}) | ||
// the logging methods will be added by anylogger.ext | ||
} | ||
/** | ||
* `anylogger.log(name, args)` | ||
* | ||
* The log function used by `anylogger.new`. | ||
* | ||
* You can override this method to change invocation behavior. | ||
* | ||
* @param name {String} The name of the logger to use | ||
* @param args {Array} The log arguments | ||
* | ||
* This method inspects the first argument in `args` to determine the log | ||
* level to log at (defaults to 'log') and then calls the correct method | ||
* on the logger function with the remaining arguments. | ||
*/ | ||
a.log = function(n,x) { | ||
m[n][x.length > 1 && a.levels[x[0]] ? x.shift() : 'log'].apply(m[n], x) | ||
} | ||
/** | ||
* `anylogger.log(name, args)` | ||
* | ||
* The log function used by `anylogger.new`. | ||
* | ||
* You can override this method to change invocation behavior. | ||
* | ||
* @param name {String} The name of the logger to use | ||
* @param args {Array} The log arguments | ||
* | ||
* This method inspects the first argument in `args` to determine the log | ||
* level to log at (defaults to 'log') and then calls the correct method | ||
* on the logger function with the remaining arguments. | ||
*/ | ||
a.log = function(n,x) { | ||
m[n][x.length > 1 && a.levels[x[0]] ? x.shift() : 'log'].apply(m[n], x) | ||
} | ||
/** | ||
* Called when a logger needs to be extended, either because it was newly | ||
* created, or because it's configuration or settings changed in some way. | ||
* | ||
* `anylogger.ext(logger) => logger` | ||
* | ||
* This method must ensure that a log method is available on the logger for | ||
* each level in `anylogger.levels`. | ||
* | ||
* When overriding `anylogger.ext`, please ensure the function can safely | ||
* be called multiple times on the same object | ||
* | ||
* @param logger Function The logger to be (re-)extended | ||
* | ||
* @return The logger that was given, extended | ||
*/ | ||
a.ext = function(l,o) { | ||
o = typeof console != 'undefined' && console | ||
for (v in a.levels) | ||
l[v] = o && (o[v] || o.log) || function(){} | ||
return l; | ||
} | ||
/** | ||
* Called when a logger needs to be extended, either because it was newly | ||
* created, or because it's configuration or settings changed in some way. | ||
* | ||
* `anylogger.ext(logger) => logger` | ||
* | ||
* This method must ensure that a log method is available on the logger for | ||
* each level in `anylogger.levels`. | ||
* | ||
* When overriding `anylogger.ext`, please ensure the function can safely | ||
* be called multiple times on the same object | ||
* | ||
* @param logger Function The logger to be (re-)extended | ||
* | ||
* @return The logger that was given, extended | ||
*/ | ||
a.ext = function(l,o) { | ||
o = typeof console != 'undefined' && console | ||
for (v in a.levels) | ||
l[v] = o && (o[v] || o.log) || function(){} | ||
return l; | ||
} | ||
module.exports = a | ||
})() | ||
module.exports = a |
@@ -1,1 +0,1 @@ | ||
!function(m,a){m=Object.create(null),a=function(n,e){return n?m[n]||(m[n]=a.create(n,e)):m},a.levels={error:1,warn:2,info:3,log:4,debug:5,trace:6},a.create=function(n,e){return a.ext(a.new(n,e))},a.new=function(n,c,r){return eval("r={'"+n+"':function(){a.log(n,[].slice.call(arguments))}}[n]"),r.name?r:Object.defineProperty(r,"name",{get:function(){return n}})},a.log=function(n,e){m[n][1<e.length&&a.levels[e[0]]?e.shift():"log"].apply(m[n],e)},a.ext=function(n,e){for(v in e="undefined"!=typeof console&&console,a.levels)n[v]=e&&(e[v]||e.log)||function(){};return n},window.anylogger=a}(); | ||
!function(){var m=Object.create(null),a=function(n,e){return n?m[n]||(m[n]=a.new(n,e)):m};a.levels={error:1,warn:2,info:3,log:4,debug:5,trace:6},a.new=function(n,c,r){return eval("r={'"+n+"':function(){a.log(n,[].slice.call(arguments))}}[n]"),a.ext(r.name?r:Object.defineProperty(r,"name",{get:function(){return n}}))},a.log=function(n,e){m[n][1<e.length&&a.levels[e[0]]?e.shift():"log"].apply(m[n],e)},a.ext=function(n,e){for(v in e="undefined"!=typeof console&&console,a.levels)n[v]=e&&(e[v]||e.log)||function(){};return n},this.anylogger=a}(); |
@@ -58,10 +58,3 @@ var expect = require('chai').expect | ||
it('calls anylogger.create when a new logger named "test" is created', function(){ | ||
sandbox.spy(anylogger, 'create') | ||
expect(anylogger.create.callCount).to.equal(0) | ||
anylogger('test') | ||
expect(anylogger.create.callCount).to.equal(1) | ||
}) | ||
it('Calls anylogger.new when a new logger named "test" is created', function(){ | ||
it('calls anylogger.new when a new logger named "test" is created', function(){ | ||
sandbox.spy(anylogger, 'new') | ||
@@ -80,12 +73,12 @@ expect(anylogger.new.callCount).to.equal(0) | ||
it('does not call anylogger.create on subsequent calls with the same name', function(){ | ||
sandbox.spy(anylogger, 'create') | ||
expect(anylogger.create.callCount).to.equal(0) | ||
it('does not call anylogger.new on subsequent calls with the same name', function(){ | ||
sandbox.spy(anylogger, 'new') | ||
expect(anylogger.new.callCount).to.equal(0) | ||
anylogger('test') | ||
expect(anylogger.create.callCount).to.equal(1) | ||
expect(anylogger.new.callCount).to.equal(1) | ||
anylogger('test') | ||
expect(anylogger.create.callCount).to.equal(1) | ||
expect(anylogger.new.callCount).to.equal(1) | ||
}) | ||
it('calls anylogger.create when a new logger named "toString" is created', function(){ | ||
it('calls anylogger.new when a new logger named "toString" is created', function(){ | ||
sandbox.spy(anylogger, 'new') | ||
@@ -97,9 +90,9 @@ expect(anylogger.new.callCount).to.equal(0) | ||
it('does not call anylogger.create on subsequent calls with "toString" as argument', function(){ | ||
sandbox.spy(anylogger, 'create') | ||
expect(anylogger.create.callCount).to.equal(0) | ||
it('does not call anylogger.new on subsequent calls with "toString" as argument', function(){ | ||
sandbox.spy(anylogger, 'new') | ||
expect(anylogger.new.callCount).to.equal(0) | ||
anylogger('toString') | ||
expect(anylogger.create.callCount).to.equal(1) | ||
expect(anylogger.new.callCount).to.equal(1) | ||
anylogger('toString') | ||
expect(anylogger.create.callCount).to.equal(1) | ||
expect(anylogger.new.callCount).to.equal(1) | ||
}) | ||
@@ -106,0 +99,0 @@ |
{ | ||
"name": "anylogger", | ||
"version": "0.11.0", | ||
"version": "0.12.0", | ||
"description": "Get a logger. Any logger.", | ||
@@ -5,0 +5,0 @@ "main": "anylogger.js", |
@@ -1,2 +0,2 @@ | ||
# anylogger <sub><sup>0.11.0</sup></sub> | ||
# anylogger <sub><sup>0.12.0</sup></sub> | ||
### Get a logger. Any logger. | ||
@@ -47,3 +47,3 @@ | ||
A tiny ~[360](#gzip-size) bytes logging facade that you can include in your | ||
A tiny ~[346](#gzip-size) bytes logging facade that you can include in your | ||
library to have logging 'just work', while at the same time allowing | ||
@@ -55,3 +55,3 @@ application developers to plug in any logging framework they choose. | ||
or just abandoning logging altogether, choose `anylogger` and for just | ||
~[360](#gzip-size) bytes shared between all libraries doing this, we can | ||
~[346](#gzip-size) bytes shared between all libraries doing this, we can | ||
plug in any framework of our choice and all libraries will automatically | ||
@@ -69,6 +69,6 @@ start to use that framework. Wouldn't it be much better and easier? | ||
* [anylogger.js](https://unpkg.com/anylogger@0.11.0/anylogger.js) | ||
* [anylogger.js](https://unpkg.com/anylogger@0.12.0/anylogger.js) | ||
(fully commented source ~5kB) | ||
* [anylogger.min.js](https://unpkg.com/anylogger@0.11.0/anylogger.min.js) | ||
(minified 592 bytes, gzipped ~[360](#gzip-size) bytes) | ||
* [anylogger.min.js](https://unpkg.com/anylogger@0.12.0/anylogger.min.js) | ||
(minified 546 bytes, gzipped ~[346](#gzip-size) bytes) | ||
@@ -80,3 +80,3 @@ | ||
```html | ||
<script src="https://unpkg.com/anylogger@0.11.0/anylogger.min.js"></script> | ||
<script src="https://unpkg.com/anylogger@0.12.0/anylogger.min.js"></script> | ||
<script>(function(){ // IIFE | ||
@@ -109,3 +109,3 @@ var log = anylogger('index.html') | ||
"peerDependencies": { | ||
"anylogger": "^0.11.0" | ||
"anylogger": "^0.12.0" | ||
} | ||
@@ -376,18 +376,2 @@ } | ||
#### anylogger.create | ||
```js | ||
anylogger.create(name, config) => logger | ||
``` | ||
A method that is called whenever a new logger is created. Calls | ||
[`anylogger.new`](#anyloggernew) and [`anylogger.ext`](#anyloggerext). | ||
You can override this method with your own factory, but it is probably easier | ||
to override just `anylogger.new`, chaining the old method. | ||
##### name | ||
The name of the new logger. String. Required. | ||
##### config | ||
An optional config object. Object. Optional. | ||
#### anylogger.new | ||
@@ -398,2 +382,3 @@ ```js | ||
A method that is called to create the logger function. | ||
Calls `anylogger.ext` on the created log function before returning it. | ||
@@ -460,3 +445,3 @@ ##### name | ||
Please have a look at the | ||
[source](https://unpkg.com/anylogger@0.11.0/anylogger.js) | ||
[source](https://unpkg.com/anylogger@0.12.0/anylogger.js) | ||
it should make it more clear how to write an adapter. Also consider studying | ||
@@ -463,0 +448,0 @@ the [available adapters](https://www.npmjs.com/search?q=keywords:anylogger) |
28124
254
471