Permalink
Browse files

Add: make use cases that do not include a core function or incoming d…

…ata possible
  • Loading branch information...
1 parent 69817ee commit 0687042926ef960704e6989cb873a6b6f87bce03 @tmpvar committed Nov 17, 2011
Showing with 181 additions and 4 deletions.
  1. +148 −0 README.md
  2. +16 −4 index.js
  3. +17 −0 test.js
View
148 README.md
@@ -0,0 +1,148 @@
+# filterchain
+
+Perform work before and/or after an operation.
+
+## API Signature
+
+```javascript
+// Create a chain with no layers and no core function
+var chain = require('filterchain').createChain(/* layers */, /* core */);
+```
+
+Where `chain` is a function that accepts an optional `data` and a required `callback` with the arguments `errors` and `data`. The `callback` is called after the filter chain has been executed.
+
+`data` can be any javascript value
+
+```javascript
+// Except to show what the chain callback looks like
+chain('some optional data', function(errors, data) {})
+```
+
+And `layers` is an array of functions
+
+```javascript
+var chain = require('filterchain').createChain([
+ function(data, next, cancel) {
+
+ // just forward the data, this is basically a no-op
+ next(data);
+ }
+], core);
+```
+
+And `core` is the function that will be run after the capture phase but before the bubble phase. The `core` method should accept `data` and `fn`.
+
+```javascript
+var chain = require('filterchain').createChain([], function(data, fn) {
+
+ // send the incoming back the same way it came
+ if (data === true) {
+ fn(null, 'tricked ya!')
+ } else {
+ fn('error!')
+ }
+
+});
+
+chain(true, function(errors, data) {
+ console.log(data); // outputs: 'tricked ya!'
+});
+
+chain(false, function(errors, data) {
+ console.log(errors[0]); // outputs: 'error!'
+ console.log(data); // outputs: undefined
+});
+
+```
+
+## What does it do?
+
+In a sense, filter chains are similar to onions. Passing data into the outer husk causes it to flow down through each layer toward the core. Each function (aka: layer) along the path as a chance to either manipulate or validate the data before forwarding it onto the next layer or canceling it.
+
+```javascript
+var chain = require('filterchain').createChain([
+ function(data, next, cancel) {
+
+ // ignore the incoming data and forward something more
+ // to our liking
+ next('pass this along');
+ }
+]);
+
+chain(function(errors, data) {
+ console.log(data); // outputs 'pass this along'
+});
+```
+
+Cancelling causes the flow of the chain to be reversed immediately.
+
+```javascript
+var chain = require('filterchain').createChain([
+ function(data, next, cancel) {
+
+ // the first argument to cancel is an optional error. The error
+ // will be collected and sent to the final callback for processing
+ cancel('fat chance');
+ }
+], function(data, fn) {
+
+ // this is never called
+ fn('some other thing');
+});
+
+chain(function(errors, data) {
+ console.log(errors[0]); // ouputs 'fat chance'
+});
+
+```
+
+The core of the filter chain is an optional function.
+
+```javascript
+var fc = require('filterchain');
+var chain = fc.createChain([
+
+])
+
+```
+
+## Basic Usage
+
+The basic operation of filterchain goes something like this:
+
+```javascript
+var fc = require('filterchain');
+var chain = fc.createChain([
+ function(data, next, cancel) {
+ next('override');
+ } // you can add more functions here
+]);
+
+chain('initial data', function(data) {
+ console.log(data); // outputs 'override'
+});
+
+```
+
+## More interesting examples
+
+
+```javascript
+var fc = require('filterchain');
+var chain = fc.createChain();
+
+```
+
+
+
+## Install
+
+### Node.js
+
+ npm install filterchain
+
+### Browser
+
+works with just a script tag or an asynchronous module loading system like [require.js](http://requirejs.org/)
+
+
View
@@ -1,9 +1,19 @@
(function() {
module.exports = {
createChain : function(chain, coreFn) {
- chain = chain || [];
+ if (typeof chain === 'function' && !coreFn) {
+ coreFn = chain;
+ chain = [];
+ } else {
+ chain = chain || [];
+ }
var chainInstance = function(data, fn) {
+ if (typeof data === 'function' && !fn) {
+ fn = data;
+ data = null;
+ }
+
var
index = -1,
errors = [],
@@ -46,14 +56,16 @@
bubble(data);
});
} else {
- //errors.push(new Error('user error! A link in the chain was not a function'))
- //bubble(data);
+ errors.push(new Error('user error! A link in the chain was not a function'))
+ bubble(data);
}
}, bubble = function(data) {
if (bubbles.length < 1) {
- fn((errors.length) ? errors : null, data);
+ if (fn) {
+ fn((errors.length) ? errors : null, data);
+ }
} else {
var bubbleFn = bubbles.pop();
var ret = bubbleFn(data, function done(err, data) {
View
17 test.js
@@ -26,6 +26,23 @@ basic({ hello : 'world' }, function(errors, data) {
equal('pre-world-post', data.hello);
});
+// No provided data
+var noData = fc.createChain([], function(data, fn) {
+ fn(null, 'this is some data')
+});
+
+noData(function(errors, data) {
+ equal('this is some data', data);
+});
+
+// No chain provided
+var noChain = fc.createChain(function(data, fn) {
+ fn(null, data + ' world');
+});
+
+noChain('hello', function(errors, data) {
+ equal('hello world', data);
+});
// Return from bubbler function
var bubbleReturn = fc.createChain([

0 comments on commit 0687042

Please sign in to comment.