Skip to content

Commit

Permalink
Merge 1c9c3d1 into c242d79
Browse files Browse the repository at this point in the history
  • Loading branch information
calebboyd committed Sep 25, 2015
2 parents c242d79 + 1c9c3d1 commit 935a924
Show file tree
Hide file tree
Showing 2 changed files with 76 additions and 21 deletions.
62 changes: 43 additions & 19 deletions index.js
Expand Up @@ -6,6 +6,45 @@

module.exports = compose;

function noop () {
return Promise.resolve()
}

/**
* Try catch middlware invocation
* @api private
* @param fn
* @param ctx
* @param next
* @returns {Promise<any>}
*/

function tryCatch(fn, ctx, next) {
try {
return Promise.resolve(fn(ctx, next))
} catch (err) {
return Promise.reject(err)
}
}


/**
* Reducer for creating storing next reference
* @api private
* @param next
* @param mw
* @returns {Function}
*/

function middlewareReducer(next, mw) {
return function(ctx, nextFn) {
ctx.next = next && function () { return next(ctx, nextFn) }
|| nextFn
|| noop
return tryCatch(mw, ctx, ctx.next)
}
}

/**
* Compose `middleware` returning
* a fully valid middleware comprised
Expand All @@ -21,25 +60,10 @@ function compose(middleware){
for (const fn of middleware) {
if (typeof fn !== 'function') throw new TypeError('Middleware must be composed of functions!')
}

/**
* @param {Object} context
* @return {Promise}
* @api public
*/

return function (context, next) {
return dispatch(0)
function dispatch(i) {
const fn = middleware[i] || next
if (!fn) return Promise.resolve()
try {
return Promise.resolve(fn(context, function next() {
return dispatch(i + 1)
}))
} catch(err) {
return Promise.reject(err);
}
if (!middleware.length) {
return function(ctx, next) {
return tryCatch(next || noop, ctx, noop)
}
}
return middleware.reduceRight(middlewareReducer, undefined)
}
35 changes: 33 additions & 2 deletions test/test.js
Expand Up @@ -174,9 +174,40 @@ describe('Koa Compose', function(){

return compose(stack.map(co.wrap))({}).then(function () {
throw 'promise was not rejected'
})
.catch(function (e) {
}).catch(function (e) {
e.should.be.instanceof(Error)
})
})

it('should return a valid middleware', function () {
var val = 0
compose([
compose([
(ctx, next) => {
val++
return next()
},
(ctx, next) => {
val++
return next()
}
]),
(ctx, next) => {
val++
return next()
}
])({}).then(function () {
val.should.equal(3)
})
})

it('should expose next on the context', function () {
var stack = [];

stack.push(function (context, next) {
context.next.should.equal(next)
})

return compose(stack.map(co.wrap))({})
})
})

0 comments on commit 935a924

Please sign in to comment.