Skip to content

Instantly share code, notes, and snippets.

@serebano
Created October 30, 2016 16:10
Show Gist options
  • Select an option

  • Save serebano/a427675d3cc3f3e879bcc84c4eeb7f70 to your computer and use it in GitHub Desktop.

Select an option

Save serebano/a427675d3cc3f3e879bcc84c4eeb7f70 to your computer and use it in GitHub Desktop.
JS Middleware Fun
/** fun.js
JS Middleware Fun
num = fun((n, next) => 10 + next(n * 1))
.use((n, next) => 20 - next(n - 2))
.use((n, next) => 30 * next(n / 3))
num(1)
*/
export default(...stack) => {
let use = []
let fun = (ctx, next) => try {
fun[Symbol.iterator]()
.next(api, next)
.value
} catch(e) {
throw(e) }
fun.get = (i) => i ? use[i] : use
fun.use = (...stack) => {
for (const fn of stack)
if (typeof fn !== 'function')
throw new TypeError('Middleware must be composed of functions!')
use = [...use, ...stack]
return fun
}
fun[Symbol.iterator] = () => {
const { length } = use
let idx = 0
let ctx
return {
next() {
if (ctx === undefined)
ctx = arguments[0] || {}
let func = use[idx++] || arguments[1]
let done = idx > length
let name = func && func.name ? func.name : `func$${idx-1}`
let value
let called = false
if (!func)
return { value, done }
func.idx = idx-1
return {
value: func(ctx, () => {
if (called)
return new Error('next() called multiple times')
called = true
func.n = (func.n||0) + 1
return this.next().value
}), done
}
}
}
}
return fun.use(...stack)
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment