diff --git a/@vates/compose/USAGE.md b/@vates/compose/USAGE.md index c910d9cb6..06310b7e8 100644 --- a/@vates/compose/USAGE.md +++ b/@vates/compose/USAGE.md @@ -16,3 +16,15 @@ Functions may also be passed in an array: ```js const f = compose([add2, mul3]) ``` + +Options can be passed as first parameters: + +```js +const f = compose( + { + // compose from right to left + right: true, + }, + [add2, mul3] +) +``` diff --git a/@vates/compose/index.js b/@vates/compose/index.js index e7ccb816b..a67de7f04 100644 --- a/@vates/compose/index.js +++ b/@vates/compose/index.js @@ -1,9 +1,21 @@ 'use strict' -exports.compose = function compose(fns) { - if (!Array.isArray(fns)) { +const defaultOpts = { right: false } + +exports.compose = function compose(opts, fns) { + if (Array.isArray(opts)) { + fns = opts + opts = defaultOpts + } else if (typeof opts === 'object') { + opts = Object.assign({}, defaultOpts, opts) + if (!Array.isArray(fns)) { + fns = Array.prototype.slice.call(arguments, 1) + } + } else { fns = Array.from(arguments) + opts = defaultOpts } + const n = fns.length if (n === 0) { throw new TypeError('at least one function must be passed') @@ -11,6 +23,11 @@ exports.compose = function compose(fns) { if (n === 1) { return fns[0] } + + if (opts.right) { + fns.reverse() + } + return function (value) { for (let i = 0; i < n; ++i) { value = fns[i](value) diff --git a/@vates/compose/index.spec.js b/@vates/compose/index.spec.js index 615463e81..0a67c70f7 100644 --- a/@vates/compose/index.spec.js +++ b/@vates/compose/index.spec.js @@ -18,4 +18,12 @@ describe('compose()', () => { it('accepts functions in an array', () => { expect(compose([add2, mul3])(5)).toBe(21) }) + + it('can apply from right to left', () => { + expect(compose({ right: true }, add2, mul3)(5)).toBe(17) + }) + + it('accepts options with functions in an array', () => { + expect(compose({ right: true }, [add2, mul3])(5)).toBe(17) + }) })