Comparing version 0.3.0 to 0.4.0
0.4.0 / 2013-03-07 | ||
================== | ||
* readme: update docs | ||
* lib: update comments | ||
* test: change to use .prototype | ||
* lib: constructor no longer auto select prototype on function input | ||
* test: test for handle | ||
* lib: remove emit, add handle to allow for custom emit logic | ||
* pkg: add chai-spies testing dep | ||
0.3.0 / 2012-11-13 | ||
@@ -3,0 +14,0 @@ ================== |
130
lib/facet.js
@@ -0,3 +1,13 @@ | ||
/*! | ||
* Facet | ||
* Copyright(c) 2012-2013 Jake Luer <jake@qualiancy.com> | ||
* MIT Licensed | ||
*/ | ||
/** | ||
* ### facet (object[, property]) | ||
* ## Usage | ||
*/ | ||
/** | ||
* ### facet (object[, options]) | ||
* | ||
@@ -11,4 +21,4 @@ * This mixin provides a way to store arbitray key/value | ||
* ```js | ||
* // on a constructor (prototype) | ||
* facet(MyConstructor); | ||
* // on a constructor | ||
* facet(MyConstructor.prototype); | ||
* | ||
@@ -20,46 +30,71 @@ * // on an object | ||
* | ||
* Facet will default to creating and using the `.settings` | ||
* property on the constructor or object to store the | ||
* **Storage:** Facet will default to creating and using the `.settings` | ||
* object on the constructor or object to store the | ||
* key/value pairs. If you would like to use something else | ||
* you may specify a different property key. | ||
* you may specify a different storage key. | ||
* | ||
* ```js | ||
* facet(MyConstructor, 'options'); | ||
* facet(MyConstructor.prototype, '_options'); | ||
* ``` | ||
* | ||
* Facet can also emit events anytime a setting has changed | ||
* by assuming the constructor that was extended has an `emit` | ||
* method that conforms to node.js standards. The event emitted | ||
* will equal the name of the storage property. This is **disabled** | ||
* by default. | ||
* **Handle:** Facet can also invoke a handle anytime a setting is | ||
* written. This is preferred method of responding to | ||
* writes as opposed to overwriting the `.set` method. | ||
* | ||
* The `this` context in the handle will be the object | ||
* instance. | ||
* | ||
* ```js | ||
* facet(MyConstructor, true); | ||
* // facet(MyConstructor, 'options', true); | ||
* facet(MyEventEmitter.prototype, function (key, value) { | ||
* // emit changes on self | ||
* this.emit('settings', key, value); | ||
* }); | ||
* | ||
* var obj = new MyConstructor(); | ||
* var ee = new MyEventEmitter(); | ||
* | ||
* // obj.on('options', ... | ||
* obj.on('settings', function (key, value) { | ||
* console.log(key + ' was set to: ', value); | ||
* ee.on('settings', function (key, value) { | ||
* console.log('%s was set to: ', key, value); | ||
* }); | ||
* | ||
* obj.set('hello', 'universe'); | ||
* ee.set('hello', 'universe'); | ||
* // "hello was set to: universe" | ||
* ``` | ||
* | ||
* **All Settings:** If you are changing more than one of the | ||
* options than you can use an object as the second argument. | ||
* | ||
* - **@param** _{String}_ `store` | ||
* - **@param** _{Function}_ `handle` | ||
* | ||
* ```js | ||
* facet(MyEventEmitter.prototype, { | ||
* store: '_options' | ||
* , handle: function (key, value) { | ||
* this.emit('options', key, value); | ||
* } | ||
* }); | ||
* ``` | ||
* | ||
* @param {Object} Constructor or Object | ||
* @param {String} Object property to use as storage _(optional)_ | ||
* @param {Boolean} Emit `settings` events. _(optional)_ | ||
* @param {Mixed} Options | ||
* @return {Object} Constructor or Object | ||
* @api public | ||
*/ | ||
module.exports = function (obj, prop, events) { | ||
if ('string' !== typeof prop) events = prop, prop = 'settings'; | ||
var proto = 'function' === typeof obj | ||
? obj.prototype | ||
: obj; | ||
module.exports = function (proto, opts) { | ||
// handle second argument | ||
if ('string' === typeof opts) { | ||
opts = { store: opts }; | ||
} else if ('function' === typeof opts) { | ||
opts = { handle: opts }; | ||
} else { | ||
opts = opts || {}; | ||
} | ||
// fill in the blanks | ||
if (!opts.store) opts.store = 'settings'; | ||
if (!opts.handle) opts.handle = function () {}; | ||
/** | ||
* Once an object is extended, | ||
* you may use any of the following methods. | ||
* ## API | ||
*/ | ||
@@ -74,4 +109,8 @@ | ||
* ```js | ||
* obj.set('hello', 'universe'); | ||
* obj.set({ hello: 'universe', say: 'loudly' }); | ||
* obj | ||
* .set('hello', 'universe') | ||
* .set({ | ||
* hello: 'universe' | ||
* , say: 'loudly' | ||
* }); | ||
* ``` | ||
@@ -81,16 +120,10 @@ * | ||
* @param {Mixed} value | ||
* @name set | ||
* @return {this} for chaining | ||
* @api public | ||
*/ | ||
proto.set = (function (prop, events) { | ||
events = 'boolean' === typeof events ? events: false; | ||
var emit = function () {}; | ||
proto.set = (function (opts) { | ||
var handle = opts.handle | ||
, prop = opts.store; | ||
if (events) { | ||
emit = function (obj, key, value) { | ||
obj.emit(prop, key, value); | ||
}; | ||
} | ||
return function (key, value) { | ||
@@ -104,4 +137,3 @@ var settings = this[prop] || (this[prop] = {}); | ||
for (var name in key) { | ||
settings[name] = key[name]; | ||
emit(this, name, key[name]); | ||
this.set(name, key[name]); | ||
} | ||
@@ -111,3 +143,3 @@ } | ||
settings[key] = value; | ||
emit(this, key, value); | ||
handle.call(this, key, value); | ||
} | ||
@@ -117,3 +149,3 @@ | ||
}; | ||
})(prop, events); | ||
})(opts); | ||
@@ -130,3 +162,2 @@ /** | ||
* @param {String} key | ||
* @name get | ||
* @api public | ||
@@ -149,3 +180,3 @@ */ | ||
* @param {String} key | ||
* @name enable | ||
* @return {this} for chaining | ||
* @api public | ||
@@ -161,3 +192,3 @@ */ | ||
* | ||
* Mark a setting key as "disabled" (false) | ||
* Mark a setting key as "disabled" (false). | ||
* | ||
@@ -169,3 +200,3 @@ * ```js | ||
* @param {String} key | ||
* @name disable | ||
* @return {this} for chaining | ||
* @api public | ||
@@ -219,2 +250,5 @@ */ | ||
}; | ||
// pass it back out | ||
return proto; | ||
}; |
{ | ||
"name": "facet" | ||
, "version": "0.3.0" | ||
, "version": "0.4.0" | ||
, "description": "Configuration mixin for constructors." | ||
@@ -26,2 +26,3 @@ , "author": "Jake Luer <jake@qualiancy.com> (http://qualiancy.com)" | ||
"chai": "*" | ||
, "chai-spies": "*" | ||
, "component": "*" | ||
@@ -28,0 +29,0 @@ , "mocha": "*" |
@@ -21,7 +21,7 @@ # facet [![Build Status](https://secure.travis-ci.org/qualiancy/facet.png?branch=master)](https://travis-ci.org/qualiancy/facet) | ||
### facet (object[, property]) | ||
### facet (object[, options]) | ||
* **@param** _{Object}_ Constructor or Object | ||
* **@param** _{String}_ Object property to use as storage _(optional)_ | ||
* **@param** _{Boolean}_ Emit `settings` events. _(optional)_ | ||
* **@param** _{Mixed}_ Options | ||
* **@return** _{Object}_ Constructor or Object | ||
@@ -35,7 +35,5 @@ This mixin provides a way to store arbitray key/value | ||
```js | ||
var facet = require('facet'); | ||
// on a constructor | ||
facet(MyConstructor.prototype); | ||
// on a constructor (prototype) | ||
facet(MyConstructor); | ||
// on an object | ||
@@ -46,38 +44,54 @@ var obj = {}; | ||
Facet will default to creating and using the `.settings` | ||
property on the constructor or object to store the | ||
**Storage:** Facet will default to creating and using the `.settings` | ||
object on the constructor or object to store the | ||
key/value pairs. If you would like to use something else | ||
you may specify a different property key. | ||
you may specify a different storage key. | ||
```js | ||
facet(MyConstructor, 'options'); | ||
facet(MyConstructor.prototype, '_options'); | ||
``` | ||
Facet can also emit events anytime a setting has changed | ||
by assuming the constructor that was extended has an `emit` | ||
method that conforms to node.js standards. The event emitted | ||
will equal the name of the storage property. This is **disabled** | ||
by default. | ||
**Handle:** Facet can also invoke a handle anytime a setting is | ||
written. This is preferred method of responding to | ||
writes as opposed to overwriting the `.set` method. | ||
The `this` context in the handle will be the object | ||
instance. | ||
```js | ||
facet(MyConstructor, true); | ||
// facet(MyConstructor, 'options', true); | ||
facet(MyEventEmitter.prototype, function (key, value) { | ||
// emit changes on self | ||
this.emit('settings', key, value); | ||
}); | ||
var obj = new MyConstructor(); | ||
var ee = new MyEventEmitter(); | ||
// obj.on('options', ... | ||
obj.on('settings', function (key, value) { | ||
console.log(key + ' was set to: ', value); | ||
ee.on('settings', function (key, value) { | ||
console.log('%s was set to: ', key, value); | ||
}); | ||
obj.set('hello', 'universe'); | ||
ee.set('hello', 'universe'); | ||
// "hello was set to: universe" | ||
``` | ||
**All Settings:** If you are changing more than one of the | ||
options than you can use an object as the second argument. | ||
Once an object is extended, | ||
you may use any of the following methods. | ||
- **@param** _{String}_ `store` | ||
- **@param** _{Function}_ `handle` | ||
```js | ||
facet(MyEventEmitter.prototype, { | ||
store: '_options' | ||
, handle: function (key, value) { | ||
this.emit('options', key, value); | ||
} | ||
}); | ||
``` | ||
## API | ||
#### .set (key[, value]) | ||
@@ -87,2 +101,3 @@ | ||
* **@param** _{Mixed}_ value | ||
* **@return** _{this}_ for chaining | ||
@@ -93,4 +108,8 @@ Modify a key/value pair of settings, or use | ||
```js | ||
obj.set('hello', 'universe'); | ||
obj.set({ hello: 'universe', say: 'loudly' }); | ||
obj | ||
.set('hello', 'universe') | ||
.set({ | ||
hello: 'universe' | ||
, say: 'loudly' | ||
}); | ||
``` | ||
@@ -113,2 +132,3 @@ | ||
* **@param** _{String}_ key | ||
* **@return** _{this}_ for chaining | ||
@@ -125,4 +145,5 @@ Mark a setting key as "enabled" (true). | ||
* **@param** _{String}_ key | ||
* **@return** _{this}_ for chaining | ||
Mark a setting key as "disabled" (false) | ||
Mark a setting key as "disabled" (false). | ||
@@ -129,0 +150,0 @@ ```js |
11359
224
200
5