Last active
August 29, 2015 14:07
-
-
Save ysndr/e5fc125b6257e3a10f5f to your computer and use it in GitHub Desktop.
arrowJS ( Minimal Middleware Manager (M3) )
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** ---IMPORTS {{{ */ | |
var E3 = require('E3') | |
/** ---OUT --- */ | |
var Arrow = module.exports = {} | |
Arrow.create = function(options){ | |
options = options || {} | |
var stack = [] | |
, api = {} | |
api.stack = inspectStack | |
api.flush = flushStack | |
Object.freeze(api) | |
stackManager.use = use | |
stackManager.api = api | |
return stackManager | |
function stackManager(){ | |
var context = options.context || {} | |
, layerIndex = 0 | |
, handlerIndex = 0 | |
, args = [].slice.call(arguments) | |
, warnings = [] | |
// calback ( if specified) | |
, final = ('function' === typeof args[args.length -1]) | |
? args.pop() // shortens arguments by 1 | |
: null | |
args.push(next) | |
next() | |
function next( err ){ | |
var layer = stack[layerIndex] | |
/** | |
* next() will llot for handler at handlerIndex | |
* on the current layer which will be applied the arguments | |
* and call next(err). | |
* next() will then look for a handler at handlerIndex++ | |
* If next() does not find any defined handler | |
* it will step over to the next layer | |
* if there is no further layer next() is done | |
* -------------------------------------------------------- | |
* If an error occurs next() tests if err is an object | |
* which can (and will) be thrown | |
* -------------------------------------------------------- | |
* If err is a string it's a warning | |
* thus it will be passed to the warning collection | |
* further the current layer will be aborded | |
* and it will be stepped over to the next layer. | |
*/ | |
if (!layer || ( err && 'object' === typeof err )){ | |
args.pop() | |
args.unshift(err | |
|| (warnings.length > 0) | |
? {warnings : warnings} | |
: null) | |
// handles callback before exiting | |
if (final){ | |
final.apply(context /*proto*/, args/*args*/) | |
return | |
} | |
} | |
if (err && 'string' === typeof err){ | |
warnings.push(err) | |
layerIndex++ | |
handlerIndex = 0 | |
return next() | |
} | |
var handler = layer[handlerIndex] | |
if (!handler){ | |
layerIndex++ | |
handlerIndex = 0 // prepare for next layer | |
return next() | |
} | |
handlerIndex++ | |
return handler.apply(context, args) | |
} | |
} | |
function use(check){ | |
if (!check) return stackManager | |
var args = [].slice.call(arguments) | |
, arg = 0 | |
, layer = [] | |
, err = null | |
// validates every parsed layer | |
for ( ; arg < args.length ; arg++){ | |
if (Array.isArray( args[arg] )){ | |
// v Is null if no error in current layer | |
err = validateLayer( layer ) | |
|| validateLayer( args[arg] ) | |
// ^ Is null if no error in nested layer | |
if (err) break | |
// adds current layer (if defined) | |
if ( layer.length > 0) { stack.push(layer); layer = [] } | |
stack.push(args[arg]) | |
// and nested layer to stack | |
}else { | |
layer.push(args[arg]) | |
} | |
} | |
err = err || (layer.length > 0) | |
? validateLayer(layer) || err //if no error yet, validate open layer | |
: err //if no error in open stack error is null | |
if (err) throw new Error(err) | |
if (layer.length > 0) stack.push(layer) // adds open layer to stack | |
return stackManager | |
function validateLayer(layer){ | |
var index = 0 | |
if ( layer.length < 1 ){ | |
return ('Layer ( ' | |
+ layer | |
+' ) might not be an empty array') | |
} | |
for ( ; index < layer.length ; index++ ){ | |
if( typeof layer[index] !== 'function' ){ | |
return ('Type of Argument ( ' | |
+ layer[index] | |
+ ' ) is [ ' | |
+ (typeof layer[index]) | |
+ ' ] -- Must be [ function ]!') | |
} | |
} | |
return null // if there is no error | |
} | |
} | |
function flushStack(){ | |
stack = [] | |
console.warn('Stack wiped!!!') | |
} | |
function inspectStack(){ | |
return stack | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
{ | |
"name": "ArrowJS", | |
"version": "0.0.1", | |
"description": "Minimal Middleware framework for Node.js", | |
"main": "Arrow.js", | |
"repository": { | |
"type": "git", | |
"url": "https://gist.github.com/yangodev/e5fc125b6257e3a10f5f/" | |
}, | |
"url": "git@gist.github.com:/e5fc125b6257e3a10f5f.git", | |
"keywords": [ | |
"Minimal", | |
"Middleware", | |
"Manager", | |
"Framework", | |
"M3", | |
"express" | |
], | |
"author": { | |
"name": "y4ng0 @ yangodev" | |
}, | |
"license": "MIT", | |
"bugs": { | |
"url": "https://gist.github.com/yangodev/e5fc125b6257e3a10f5f/" | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment