functional-pipelines
Version:
functional pipelines for Java Script
1,451 lines (1,213 loc) • 66 kB
JavaScript
'use strict';
var _extends3 = require('babel-runtime/helpers/extends');
var _extends4 = _interopRequireDefault(_extends3);
var _slicedToArray2 = require('babel-runtime/helpers/slicedToArray');
var _slicedToArray3 = _interopRequireDefault(_slicedToArray2);
var _defineProperty2 = require('babel-runtime/helpers/defineProperty');
var _defineProperty3 = _interopRequireDefault(_defineProperty2);
var _toConsumableArray2 = require('babel-runtime/helpers/toConsumableArray');
var _toConsumableArray3 = _interopRequireDefault(_toConsumableArray2);
var _asyncToGenerator2 = require('babel-runtime/helpers/asyncToGenerator');
var _asyncToGenerator3 = _interopRequireDefault(_asyncToGenerator2);
var _regenerator = require('babel-runtime/regenerator');
var _regenerator2 = _interopRequireDefault(_regenerator);
var _typeof2 = require('babel-runtime/helpers/typeof');
var _typeof3 = _interopRequireDefault(_typeof2);
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
var _marked = /*#__PURE__*/_regenerator2.default.mark(entries),
_marked2 = /*#__PURE__*/_regenerator2.default.mark(zipWithGen),
_marked3 = /*#__PURE__*/_regenerator2.default.mark(takeGen),
_marked4 = /*#__PURE__*/_regenerator2.default.mark(skipGen),
_marked5 = /*#__PURE__*/_regenerator2.default.mark(partitionBy),
_marked6 = /*#__PURE__*/_regenerator2.default.mark(permute);
/* eslint-disable max-statements-per-line,semi,no-unused-expressions,no-extra-parens */
// functional debugging 101, peek into function names
/**
* debugging decorator that logs function name when the decorated function is invoked
* fn: can be a function defined with the `function` keyword, or `let foo = () => {}; foo = which(foo);`
*/
var which = function which(fn) {
var _ref = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {},
_ref$input = _ref.input,
input = _ref$input === undefined ? true : _ref$input,
_ref$output = _ref.output,
output = _ref$output === undefined ? false : _ref$output,
_ref$stringify = _ref.stringify,
stringify = _ref$stringify === undefined ? true : _ref$stringify;
return function () {
for (var _len = arguments.length, args = Array(_len), _key = 0; _key < _len; _key++) {
args[_key] = arguments[_key];
}
console.log((fn.name || 'function') + '(' + (input ? JSON.stringify(args, null, 0) : '...') + ')');
var result = fn.apply(undefined, args);
if (output) console.log((fn.name || 'function') + ' :: (' + (input ? JSON.stringify(args, null, 0) : '...') + ') -> ' + (stringify ? JSON.stringify(result, null, 0) || result : result));
return result;
};
};
/**
* debugging plug, insert within a pipe or compose pipeline to peek at the cascading argument
* @param x
* @returns {*}
*/
var peek = function peek(x) {
console.log(x);
return x;
};
var __ = { '@@functional/placeholder': true };
var _is__ = function _is__(a) {
return a != null && (typeof a === 'undefined' ? 'undefined' : (0, _typeof3.default)(a)) === 'object' && a['@@functional/placeholder'] === true;
};
var withOneSlot = function withOneSlot(fn) {
return function () {
for (var _len2 = arguments.length, args = Array(_len2), _key2 = 0; _key2 < _len2; _key2++) {
args[_key2] = arguments[_key2];
}
var slots = args.reduce(function (acc, a, index) {
if (_is__(a)) acc['__1'] = index;
return acc;
}, {});
return function (coin) {
args[slots['__1']] = coin;
return fn.apply(undefined, args);
};
};
};
/**
* Functional building blocks with zero dependencies
* identity, pipe, compose, empty, append, map, filter, reduce, transformers, transducers
* NOTE: map, filter, reduce can handle iterator/generator, lodash and ramda currently don't
* mapAsync, filterAsync, reduceAsync can handle async generators, lodash and ramda, transducers-js and transducers.js currently don't
**/
// Combinators: https://gist.github.com/Avaq/1f0636ec5c8d6aed2e45
var I = function I(x) {
return x;
};
var K = function K(x) {
return function (y) {
return x;
};
};
var A = function A(f) {
return function (x) {
return f(x);
};
};
var T = function T(x) {
return function (f) {
return f(x);
};
};
var W = function W(f) {
return function (x) {
return f(x)(x);
};
};
var C = function C(f) {
return function (y) {
return function (x) {
return f(x)(y);
};
};
};
var B = function B(f) {
return function (g) {
return function (x) {
return f(g(x));
};
};
};
var S = function S(f) {
return function (g) {
return function (x) {
return f(x)(g(x));
};
};
};
var P = function P(f) {
return function (g) {
return function (x) {
return function (y) {
return f(g(x))(g(y));
};
};
};
};
var Y = function Y(f) {
return function (g) {
return g(g);
}(function (g) {
return f(function (x) {
return g(g)(x);
});
});
};
var identity = I;
var identityAsync = function identityAsync(x) {
return Promise.resolve(x);
};
var lazy = K;
var empty = /*#__PURE__*/_regenerator2.default.mark(function empty() {
return _regenerator2.default.wrap(function empty$(_context) {
while (1) {
switch (_context.prev = _context.next) {
case 0:
case 'end':
return _context.stop();
}
}
}, empty, this);
});
var yrruc = function yrruc(fn) {
return function () {
for (var _len3 = arguments.length, args = Array(_len3), _key3 = 0; _key3 < _len3; _key3++) {
args[_key3] = arguments[_key3];
}
return function (x) {
return fn.apply(undefined, [x].concat(args));
};
};
}; // reversed `curry`
var pipe = function pipe() {
for (var _len4 = arguments.length, fns = Array(_len4), _key4 = 0; _key4 < _len4; _key4++) {
fns[_key4] = arguments[_key4];
}
return reduceRight(function (f, g) {
return function () {
return f(g.apply(undefined, arguments));
};
}, null, fns);
};
var pipes = function pipes() {
for (var _len5 = arguments.length, fns = Array(_len5), _key5 = 0; _key5 < _len5; _key5++) {
fns[_key5] = arguments[_key5];
}
return pipe(reduceRight(function (f, g) {
return function () {
var result = g.apply(undefined, arguments);
return isReduced(result) ? result['@@transducer/value'] : f(result);
};
}, null, fns), unreduced);
};
// const pipes = (...fns) => reduceRight((f, g) => (...args) => { const result = g(...args); return isReduced(result) ? result : f(result); }, null, fns);
var compose = function compose() {
for (var _len6 = arguments.length, fns = Array(_len6), _key6 = 0; _key6 < _len6; _key6++) {
fns[_key6] = arguments[_key6];
}
return reduce(function (f, g) {
return function () {
return f(g.apply(undefined, arguments));
};
}, null, fns);
};
// reduce/reduceRight now handle early termination protocol `reduced()` and use `unreduced` as a default result function
var composes = function composes() {
for (var _len7 = arguments.length, fns = Array(_len7), _key7 = 0; _key7 < _len7; _key7++) {
fns[_key7] = arguments[_key7];
}
return compose(unreduced, reduce(function (f, g) {
return function () {
var result = g.apply(undefined, arguments);
return isReduced(result) ? result['@@transducer/value'] : f(result);
};
}, null, fns));
};
// const composes = (...fns) => reduce((f, g) => (...args) => { const result = g(...args); return isReduced(result) ? result : f(result); }, null, fns);
var composeAsync = function composeAsync() {
for (var _len8 = arguments.length, fns = Array(_len8), _key8 = 0; _key8 < _len8; _key8++) {
fns[_key8] = arguments[_key8];
}
return reduceAsync(function (fn1, fn2) {
return (0, _asyncToGenerator3.default)( /*#__PURE__*/_regenerator2.default.mark(function _callee() {
var _args2 = arguments;
return _regenerator2.default.wrap(function _callee$(_context2) {
while (1) {
switch (_context2.prev = _context2.next) {
case 0:
_context2.t0 = fn1;
_context2.next = 3;
return fn2.apply(undefined, _args2);
case 3:
_context2.t1 = _context2.sent;
return _context2.abrupt('return', (0, _context2.t0)(_context2.t1));
case 5:
case 'end':
return _context2.stop();
}
}
}, _callee, undefined);
}));
}, undefined, fns);
};
var flip = function flip(fn) {
return function () {
for (var _len9 = arguments.length, args = Array(_len9), _key9 = 0; _key9 < _len9; _key9++) {
args[_key9] = arguments[_key9];
}
return fn.apply(undefined, (0, _toConsumableArray3.default)(args.reverse()));
};
};
/** ----- FUTURE ----- **/
// When the runtime supports async/generator functions without transpiling, we can check if a function is a generator or is async by using foo instanceof AsyncFunctionType for example
var GeneratorFunctionType = /*#__PURE__*/_regenerator2.default.mark(function _callee2() {
return _regenerator2.default.wrap(function _callee2$(_context3) {
while (1) {
switch (_context3.prev = _context3.next) {
case 0:
case 'end':
return _context3.stop();
}
}
}, _callee2, this);
}).constructor;
var AsyncFunctionType = (0, _asyncToGenerator3.default)( /*#__PURE__*/_regenerator2.default.mark(function _callee3() {
return _regenerator2.default.wrap(function _callee3$(_context4) {
while (1) {
switch (_context4.prev = _context4.next) {
case 0:
case 'end':
return _context4.stop();
}
}
}, _callee3, this);
})).constructor;
/** ----- FUTURE ----- **/
var SymbolIterator = Symbol.iterator;
var SymbolAsyncIterator = Symbol.asyncIterator;
var isFunction = function isFunction(f) {
return typeof f === 'function';
};
var isIterable = function isIterable(o) {
return o && isFunction(o[SymbolIterator]);
};
var isIterator = function isIterator(o) {
return o && isFunction(o['next']);
};
var isEnumerable = function isEnumerable(o) {
return isIterable(o) || isIterator(o);
};
var isGenerator = function isGenerator(o) {
return isEnumerable(o) && isFunction(o['return']);
};
var isAsyncGenerator = function isAsyncGenerator(o) {
return o && isFunction(o[SymbolAsyncIterator]);
};
var isNil = function isNil(x) {
return x == null;
}; // `==` works for null || undefined
// const isNumber = x => typeof x === 'number';
var objectTag = function objectTag(o) {
return Object.prototype.toString.call(o);
};
var isDate = function isDate(o) {
return objectTag(o) === '[object Date]';
};
var isRegExp = function isRegExp(o) {
return objectTag(o) === '[object RegExp]';
};
var isError = function isError(o) {
return objectTag(o) === '[object Error]';
};
var isBoolean = function isBoolean(o) {
return objectTag(o) === '[object Boolean]';
};
var isNumber = function isNumber(o) {
return objectTag(o) === '[object Number]' && o == +o;
}; // typeof NaN -> 'number' <WATT?!> `NaN` primitive is the only value that is not equal to itself.
var isString = function isString(o) {
return objectTag(o) === '[object String]';
};
var isArray = Array.isArray || function (o) {
return objectTag(o) === '[object Array]';
};
var isObject = function isObject(o) {
return o && o.constructor === Object;
};
var isEmptyValue = function isEmptyValue(x) {
return isNil(x) || !isNumber(x) && !isFunction(x) && Object.keys(x).length === 0;
}; // works for null, undefined, '', [], {}
// const isObject = o => o && (typeof o === 'object' || !isFunction(o));
// const isArray = o => Array.isArray(o);
var isContainer = function isContainer(o) {
return isObject(o) || isArray(o);
};
var isLiteral = function isLiteral(o) {
return !isContainer(o);
};
/******************* [ Logic ] *******************/
/**
* Creates a function that will process either the `onTrue` or the `onFalse`
* function depending upon the result of the `condition` predicate.
*
* @func
* @category Logic
* @sig (*... -> Boolean) -> (*... -> *) -> (*... -> *) -> (*... -> *)
* @param {Function} condition A predicate function
* @param {Function} onTrue A function to invoke when the `condition` evaluates to a truthy value.
* @param {Function} onFalse A function to invoke when the `condition` evaluates to a falsy value.
* @return {Function} A new unary function that will process either the `onTrue` or the `onFalse`
* function depending upon the result of the `condition` predicate.
* @example
*
* var incCount = ifElse(
* isEven,
* inc,
* dec
* );
* incCount(2); //=> 3
* incCount(3); //=> 1
*/
var ifElse = function ifElse(predicate) {
return function () {
var trueFn = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : identity;
return function () {
var falseFn = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : identity;
return function () {
return predicate.apply(undefined, arguments) ? trueFn.apply(undefined, arguments) : falseFn.apply(undefined, arguments);
};
};
};
};
/******************* [ Generators ] *******************/
/**
* returns entries generator/iterator, with [key, value] pairs similar to Map.entries() or with [value, key] pairs, similar to Ramda.mapObjIndexed
*
* HINT: this is more flexible than https://lodash.com/docs/4.17.4#toPairs, also returns an iterator not a concrete Array, which is wasteful
* @param o: object or object like reference
* @param values: if true, returns a generator of values only, false (default) returns a generator of key-value pairs or value-key pairs
* @param kv: if true, returns an iterator of [key, value] pairs similar to Map.entries()
* if false, returns an iterator [value, key] pairs, similar to Ramda.mapObjIndexed
* @default: true
*/
function entries(o) {
var values = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false;
var kv = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : true;
var entryKeys;
return _regenerator2.default.wrap(function entries$(_context5) {
while (1) {
switch (_context5.prev = _context5.next) {
case 0:
entryKeys = Object.keys(o);
if (!values) {
_context5.next = 5;
break;
}
return _context5.delegateYield(entryKeys.map(function (k) {
return o[k];
}), 't0', 3);
case 3:
_context5.next = 10;
break;
case 5:
if (!kv) {
_context5.next = 9;
break;
}
return _context5.delegateYield(zip(entryKeys, entryKeys.map(function (k) {
return o[k];
})), 't1', 7);
case 7:
_context5.next = 10;
break;
case 9:
return _context5.delegateYield(zip(entryKeys.map(function (k) {
return o[k];
}), entryKeys), 't2', 10);
case 10:
case 'end':
return _context5.stop();
}
}
}, _marked, this);
}
// function* range(...args) {
// switch (args.length) {
// case 1: {
// break;
// }
// case 2: {
// break;
// }
//
// }
// if (!isNumber(take) || !isNumber(start)) return;
// while (take) {
// }
// }
/**
* zip generator that works with iterables, iterators and generators
*
* Lodash and ramda only support concrete arrays!
*
* @param enumerable1: enumerable, i.e. iterable, iterator or generator
* @param enumerable2: enumerable, i.e. iterable, iterator or generator
* @param fn: pair transform function of arity 2
*/
function zipWithGen(enumerable1, enumerable2) {
var fn = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : function (x1, x2) {
return [x1, x2];
};
var count, _iteratorNormalCompletion, _didIteratorError, _iteratorError, _iterator, _step, e1, _enumerable2$next, e2, done;
return _regenerator2.default.wrap(function zipWithGen$(_context6) {
while (1) {
switch (_context6.prev = _context6.next) {
case 0:
count = 0;
enumerable1 = iterator(enumerable1);
enumerable2 = iterator(enumerable2);
_iteratorNormalCompletion = true;
_didIteratorError = false;
_iteratorError = undefined;
_context6.prev = 6;
_iterator = enumerable1[Symbol.iterator]();
case 8:
if (_iteratorNormalCompletion = (_step = _iterator.next()).done) {
_context6.next = 19;
break;
}
e1 = _step.value;
_enumerable2$next = enumerable2.next(), e2 = _enumerable2$next.value, done = _enumerable2$next.done;
if (!done) {
_context6.next = 13;
break;
}
return _context6.abrupt('return', count);
case 13:
_context6.next = 15;
return fn(e1, e2);
case 15:
// cater for mutable and immutable collections
count++;
case 16:
_iteratorNormalCompletion = true;
_context6.next = 8;
break;
case 19:
_context6.next = 25;
break;
case 21:
_context6.prev = 21;
_context6.t0 = _context6['catch'](6);
_didIteratorError = true;
_iteratorError = _context6.t0;
case 25:
_context6.prev = 25;
_context6.prev = 26;
if (!_iteratorNormalCompletion && _iterator.return) {
_iterator.return();
}
case 28:
_context6.prev = 28;
if (!_didIteratorError) {
_context6.next = 31;
break;
}
throw _iteratorError;
case 31:
return _context6.finish(28);
case 32:
return _context6.finish(25);
case 33:
case 'end':
return _context6.stop();
}
}
}, _marked2, this, [[6, 21, 25, 33], [26,, 28, 32]]);
}
var zipWith = function zipWith(enumerable1, enumerable2, fn) {
return iterator(zipWithGen(enumerable1, enumerable2, fn));
};
var zip = function zip(enumerable1, enumerable2) {
return zipWith(enumerable1, enumerable2);
};
function takeGen(n, enumerable) {
var _enumerable$next, value, done, _enumerable$next2;
return _regenerator2.default.wrap(function takeGen$(_context7) {
while (1) {
switch (_context7.prev = _context7.next) {
case 0:
n = isNumber(n) ? n : Number.POSITIVE_INFINITY;
enumerable = iterator(enumerable);
_enumerable$next = enumerable.next(), value = _enumerable$next.value, done = _enumerable$next.done;
case 3:
if (!(!done && n-- > 0)) {
_context7.next = 11;
break;
}
_context7.next = 6;
return value;
case 6:
_enumerable$next2 = enumerable.next();
value = _enumerable$next2.value;
done = _enumerable$next2.done;
_context7.next = 3;
break;
case 11:
case 'end':
return _context7.stop();
}
}
}, _marked3, this);
}
var take = function take(n, enumerable) {
return iterator(takeGen(n, enumerable));
}; // TODO: implement take as a stateful transformer/transducer for composability
function skipGen(n, enumerable) {
var done, _enumerable$next3;
return _regenerator2.default.wrap(function skipGen$(_context8) {
while (1) {
switch (_context8.prev = _context8.next) {
case 0:
n = isNumber(n) ? n : 0;
enumerable = iterator(enumerable);
done = false;
while (!done && n-- > 0) {
_enumerable$next3 = enumerable.next();
done = _enumerable$next3.done;
}
return _context8.delegateYield(enumerable, 't0', 5);
case 5:
case 'end':
return _context8.stop();
}
}
}, _marked4, this);
}
var skip = function skip(n, enumerable) {
return iterator(skipGen(n, enumerable));
}; // TODO: implement take as a stateful transformer/transducer for composability
function partitionBy(fn, enumerable) {
var NONE, iter, buffer, memory, lastResult, newResult, _iteratorNormalCompletion2, _didIteratorError2, _iteratorError2, _iterator2, _step2, value;
return _regenerator2.default.wrap(function partitionBy$(_context9) {
while (1) {
switch (_context9.prev = _context9.next) {
case 0:
NONE = {};
iter = iterator(enumerable);
buffer = [];
memory = NONE;
lastResult = void 0;
newResult = void 0;
_iteratorNormalCompletion2 = true;
_didIteratorError2 = false;
_iteratorError2 = undefined;
_context9.prev = 9;
_iterator2 = iter[Symbol.iterator]();
case 11:
if (_iteratorNormalCompletion2 = (_step2 = _iterator2.next()).done) {
_context9.next = 27;
break;
}
value = _step2.value;
lastResult = memory;
newResult = fn(value);
memory = newResult;
if (!(lastResult === NONE || lastResult === newResult)) {
_context9.next = 20;
break;
}
buffer.push(value);
_context9.next = 24;
break;
case 20:
_context9.next = 22;
return iterator(buffer, { metadata: lazy(lastResult) });
case 22:
buffer = [];
buffer.push(value);
case 24:
_iteratorNormalCompletion2 = true;
_context9.next = 11;
break;
case 27:
_context9.next = 33;
break;
case 29:
_context9.prev = 29;
_context9.t0 = _context9['catch'](9);
_didIteratorError2 = true;
_iteratorError2 = _context9.t0;
case 33:
_context9.prev = 33;
_context9.prev = 34;
if (!_iteratorNormalCompletion2 && _iterator2.return) {
_iterator2.return();
}
case 36:
_context9.prev = 36;
if (!_didIteratorError2) {
_context9.next = 39;
break;
}
throw _iteratorError2;
case 39:
return _context9.finish(36);
case 40:
return _context9.finish(33);
case 41:
if (!(buffer.length > 0)) {
_context9.next = 44;
break;
}
_context9.next = 44;
return iterator(buffer, { metadata: lazy(newResult) });
case 44:
case 'end':
return _context9.stop();
}
}
}, _marked5, this, [[9, 29, 33, 41], [34,, 36, 40]]);
}
// credits: https://stackoverflow.com/a/37580979/8316720
function permute() {
for (var _len10 = arguments.length, args = Array(_len10), _key10 = 0; _key10 < _len10; _key10++) {
args[_key10] = arguments[_key10];
}
var count, c, i, k, p;
return _regenerator2.default.wrap(function permute$(_context10) {
while (1) {
switch (_context10.prev = _context10.next) {
case 0:
count = args.length;
_context10.next = 3;
return args.slice();
case 3:
c = new Array(count).fill(0);
i = 1, k = void 0, p = void 0;
case 5:
if (!(i < count)) {
_context10.next = 21;
break;
}
if (!(c[i] < i)) {
_context10.next = 17;
break;
}
k = i % 2 && c[i];
p = args[i];
args[i] = args[k];
args[k] = p;
++c[i];
i = 1;
_context10.next = 15;
return args.slice();
case 15:
_context10.next = 19;
break;
case 17:
c[i] = 0;
++i;
case 19:
_context10.next = 5;
break;
case 21:
case 'end':
return _context10.stop();
}
}
}, _marked6, this);
}
/******************* [ Iterators ] *******************/
/**
* Generator <-> Iterator compatibility corner case workaround
*
* when a generator (say of 10 values) is partially destructured, it prematurely terminates
* example:
* ```
* const [a, b] = generator; // generator has more than two values
* generator.next(); // {done: true, value: undefined}
*
* // while an iterator resumes as expected
*
* const [a, b] = iterator; // iterator has more than two values
* iterator.next(); // {done: false, value: nextValue}
* ```
* @param generator
* @returns {Iterator}
*/
function toIterator(generator) {
var _ref5;
var _ref4 = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {},
_ref4$indexed = _ref4.indexed,
indexed = _ref4$indexed === undefined ? false : _ref4$indexed,
_ref4$kv = _ref4.kv,
kv = _ref4$kv === undefined ? false : _ref4$kv;
return _ref5 = {}, (0, _defineProperty3.default)(_ref5, Symbol.iterator, function () {
return this;
}), (0, _defineProperty3.default)(_ref5, 'next', function next() {
var _generator$next = generator.next(),
value = _generator$next.value,
done = _generator$next.done;
this.index = done ? this.index : this.index != null ? this.index + 1 : 0;
return indexed ? { value: kv ? [this.index, value] : [value, this.index], done: done } : { value: value, done: done };
}), _ref5;
}
function iterator(o) {
var _ref6 = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {},
_ref6$indexed = _ref6.indexed,
indexed = _ref6$indexed === undefined ? false : _ref6$indexed,
_ref6$kv = _ref6.kv,
kv = _ref6$kv === undefined ? false : _ref6$kv,
_ref6$metadata = _ref6.metadata,
metadata = _ref6$metadata === undefined ? lazy({}) : _ref6$metadata;
var iter = void 0;
if (isNil(o)) {
return empty();
} else if (isGenerator(o)) {
// generator only
iter = toIterator(o, { indexed: indexed, kv: kv });
} else if (isIterator(o)) {
// iterator (generator would have passed)
iter = indexed ? toIterator(o, { indexed: indexed, kv: kv }) : o;
} else if (isIterable(o)) {
// iterable (NOTE: iterator and generator would have passed the test as well)
iter = indexed ? toIterator(o[Symbol.iterator](), { indexed: indexed, kv: kv }) : o[Symbol.iterator]();
} else if (isObject(o)) {
iter = toIterator(entries(o, !indexed, kv));
} else {
iter = empty();
}
iter.metadata = isFunction(o.metadata) ? o.metadata : metadata; // pipe existing metadata() to the new supplied one?
return iter;
}
var pmatch = function pmatch(o) {
// let [[value, key]] = iterator(o, {indexed: true});
// let [[value, key]] = o;
o = isIterable(o) ? o : [];
var _o = o,
_o2 = (0, _slicedToArray3.default)(_o, 2),
value = _o2[0],
key = _o2[1];
return { key: key, value: value, 0: value, 1: key };
};
/**
* stickiness decorator for a partitioning function
*
* Works with partitionBy to have some elements attract n subsequent elements into their same bucket
*
* @example: [cookie, monster, cookie, cookie, monster, cookie, cookie, cookie, monster, monster]
* let n = 1, partitions into: [[cookie, monster], cookie, cookie, [monster, cookie], cookie, cookie, [monster, monster]]
* @param n: number of items to repeat result, when we have a hit
* @param when: (result, memory, context) -> true means we have a hit, context.n can be manipulated to interactively change stickiness
* @param recharge: reboot n every time we have a hit, implies calling fn() for each item, otherwise the function call is skipped while repeating.
*/
var sticky = function sticky(n) {
var _ref7 = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {},
_ref7$when = _ref7.when,
when = _ref7$when === undefined ? identity : _ref7$when,
_ref7$recharge = _ref7.recharge,
recharge = _ref7$recharge === undefined ? false : _ref7$recharge;
return function (fn) {
var count = 0;
var result = void 0;
var memory = void 0;
return function () {
if (!count) {
// not repeating
result = fn.apply(undefined, arguments);
memory = result;
var ctx = { n: n };
count = when(result, memory, ctx) ? ctx.n : count; // currently when answers with a toggle yes/no, x/y
} else {
// repeating
if (recharge) {
result = fn.apply(undefined, arguments);
var _ctx = { n: n };
count = when(result, memory, _ctx) ? _ctx.n + 1 : count; // recharge sticky counter with every new positive hit, (n + this once)
}
result = memory;
count--;
}
return result;
};
};
};
/******************* [ Transducers+ ] *******************/
var wrapped = function wrapped(into) {
return function (x) {
var _ref8;
return x && x['@@transducer/' + into] ? x : (_ref8 = {}, (0, _defineProperty3.default)(_ref8, '@@transducer/value', x), (0, _defineProperty3.default)(_ref8, '@@transducer/' + into, true), _ref8);
};
};
var isWrapped = function isWrapped(into) {
return function (x) {
return x && x['@@transducer/' + into];
};
};
var unwrapped = function unwrapped(into) {
return function (result) {
return isWrapped(into)(result) ? result['@@transducer/value'] : result;
};
};
var reduced = function reduced(x) {
return x && x['@@transducer/reduced'] ? x : {
'@@transducer/value': x,
'@@transducer/reduced': true
};
};
var isReduced = function isReduced(x) {
return x && x['@@transducer/reduced'];
};
var unreduced = function unreduced(result) {
return isReduced(result) ? result['@@transducer/value'] : result;
};
/**
* Implements reduce for iterables
*
* Uses the for-of to reduce an iterable, accepting a reducing function
* @param iterable
* @param reducingFn: function of arity 2, (acc, input) -> new acc
* @param initFn: produces the initial value for the accumulator
* @returns {Accumulator-Collection}
*/
function reduce(reducingFn, initFn, enumerable, resultFn) {
if (isFunction(resultFn)) {
resultFn = pipe(unreduced, resultFn);
} else {
resultFn = unreduced;
}
var result = void 0;
var iter = iterator(enumerable);
if (!initFn) {
var _iter = (0, _slicedToArray3.default)(iter, 1),
initValue = _iter[0];
initFn = lazy(initValue);
}
result = initFn();
var _iteratorNormalCompletion3 = true;
var _didIteratorError3 = false;
var _iteratorError3 = undefined;
try {
for (var _iterator3 = iter[Symbol.iterator](), _step3; !(_iteratorNormalCompletion3 = (_step3 = _iterator3.next()).done); _iteratorNormalCompletion3 = true) {
var value = _step3.value;
if (isReduced(result)) {
break;
}
result = reducingFn(result, value);
}
} catch (err) {
_didIteratorError3 = true;
_iteratorError3 = err;
} finally {
try {
if (!_iteratorNormalCompletion3 && _iterator3.return) {
_iterator3.return();
}
} finally {
if (_didIteratorError3) {
throw _iteratorError3;
}
}
}
return resultFn(result);
}
function reduceRight(reducingFn, initFn, array, resultFn) {
if (isFunction(resultFn)) {
resultFn = pipe(unreduced, resultFn);
} else {
resultFn = unreduced;
}
var result = void 0;
var iter = iterator(array.slice().reverse());
if (!initFn) {
var _iter2 = (0, _slicedToArray3.default)(iter, 1),
initValue = _iter2[0];
initFn = lazy(initValue);
}
result = initFn();
var _iteratorNormalCompletion4 = true;
var _didIteratorError4 = false;
var _iteratorError4 = undefined;
try {
for (var _iterator4 = iter[Symbol.iterator](), _step4; !(_iteratorNormalCompletion4 = (_step4 = _iterator4.next()).done); _iteratorNormalCompletion4 = true) {
var value = _step4.value;
if (isReduced(result)) {
break;
}
result = reducingFn(result, value);
}
} catch (err) {
_didIteratorError4 = true;
_iteratorError4 = err;
} finally {
try {
if (!_iteratorNormalCompletion4 && _iterator4.return) {
_iterator4.return();
}
} finally {
if (_didIteratorError4) {
throw _iteratorError4;
}
}
}
return resultFn(result);
}
var flatten = function flatten(enumerable) {
return reduce(cat(), function () {
return [];
}, enumerable);
};
/**
* Implements reduce for async-generators instead of iterables or reduce for an async reducingFn
*
* Uses the for-await-of to reduce an async-generator, accepting an async reducing function
* @param enumerable: async-generator: async function* asyncGen(), or fall back to iterable/iterator if forAwait = false
* @param reducingFn: async function of arity 2, (acc, input) -> new acc
* @param initFn: produces the initial value for the accumulator
* @param async: if true, iterator is considered to be an async-generator, instructs reduce to use for-await-of, else uses for-of
* HINT: an async reducing function is won't complain if an iterator is passed in place of the enumerable
* HINT: an async reducing function is a candidate trap for async-throttling/rate-limiting/quota-limiting
* @returns {Promise<Accumulator-Collection>}
*/
var reduceAsync = function () {
var _ref9 = (0, _asyncToGenerator3.default)( /*#__PURE__*/_regenerator2.default.mark(function _callee5(reducingFn, initFn, enumerable, resultFn) {
var reducedRejectedPromises = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : true;
var result, isAsync, iter, resolveValue, _iter3, initValue, done, value, _ref11, resolvedValue, _ref12, _iteratorNormalCompletion5, _didIteratorError5, _iteratorError5, _iterator5, _step5, _value, _resolvedValue;
return _regenerator2.default.wrap(function _callee5$(_context12) {
while (1) {
switch (_context12.prev = _context12.next) {
case 0:
if (isFunction(resultFn)) {
resultFn = pipe(unreduced, resultFn);
} else {
resultFn = unreduced;
}
result = void 0;
isAsync = isAsyncGenerator(enumerable) || !isIterable(enumerable) && !SymbolAsyncIterator; // https://github.com/babel/babel/issues/7467
if (!isAsync) {
_context12.next = 9;
break;
}
_context12.next = 6;
return enumerable;
case 6:
_context12.t0 = _context12.sent;
_context12.next = 10;
break;
case 9:
_context12.t0 = iterator(enumerable);
case 10:
iter = _context12.t0;
// treat this argument as an iterable;
resolveValue = function () {
var _ref10 = (0, _asyncToGenerator3.default)( /*#__PURE__*/_regenerator2.default.mark(function _callee4(x, reducedRejectedPromises) {
return _regenerator2.default.wrap(function _callee4$(_context11) {
while (1) {
switch (_context11.prev = _context11.next) {
case 0:
_context11.prev = 0;
_context11.next = 3;
return x;
case 3:
return _context11.abrupt('return', _context11.sent);
case 6:
_context11.prev = 6;
_context11.t0 = _context11['catch'](0);
if (!reducedRejectedPromises) {
_context11.next = 12;
break;
}
return _context11.abrupt('return', reduced(_context11.t0));
case 12:
throw _context11.t0;
case 13:
case 'end':
return _context11.stop();
}
}
}, _callee4, undefined, [[0, 6]]);
}));
return function resolveValue(_x15, _x16) {
return _ref10.apply(this, arguments);
};
}();
if (initFn) {
_context12.next = 25;
break;
}
if (!isAsync) {
_context12.next = 23;
break;
}
_context12.t1 = lazy;
_context12.next = 17;
return iter.next();
case 17:
_context12.next = 19;
return _context12.sent;
case 19:
_context12.t2 = _context12.sent.value;
initFn = (0, _context12.t1)(_context12.t2);
_context12.next = 25;
break;
case 23:
_iter3 = (0, _slicedToArray3.default)(iter, 1), initValue = _iter3[0];
initFn = lazy(initValue);
case 25:
result = initFn();
if (!isAsync) {
_context12.next = 57;
break;
}
done = false;
value = undefined;
_context12.next = 31;
return iter.next();
case 31:
_ref11 = _context12.sent;
value = _ref11.value;
done = _ref11.done;
case 34:
_context12.next = 36;
return resolveValue(result, reducedRejectedPromises);
case 36:
result = _context12.sent;
if (!isReduced(result)) {
_context12.next = 39;
break;
}
return _context12.abrupt('break', 55);
case 39:
_context12.next = 41;
return resolveValue(value, reducedRejectedPromises);
case 41:
resolvedValue = _context12.sent;
if (!isReduced(resolvedValue)) {
_context12.next = 44;
break;
}
return _context12.abrupt('break', 55);
case 44:
_context12.next = 46;
return reducingFn(result, resolvedValue);
case 46:
result = _context12.sent;
_context12.next = 49;
return iter.next();
case 49:
_context12.next = 51;
return _context12.sent;
case 51:
_ref12 = _context12.sent;
value = _ref12.value;
done = _ref12.done;
case 54:
if (!done) {
_context12.next = 34;
break;
}
case 55:
_context12.next = 94;
break;
case 57:
_iteratorNormalCompletion5 = true;
_didIteratorError5 = false;
_iteratorError5 = undefined;
_context12.prev = 60;
_iterator5 = iter[Symbol.iterator]();
case 62:
if (_iteratorNormalCompletion5 = (_step5 = _iterator5.next()).done) {
_context12.next = 80;
break;
}
_value = _step5.value;
_context12.next = 66;
return resolveValue(result, reducedRejectedPromises);
case 66:
result = _context12.sent;
if (!isReduced(result)) {
_context12.next = 69;
break;
}
return _context12.abrupt('break', 80);
case 69:
_context12.next = 71;
return resolveValue(_value, reducedRejectedPromises);
case 71:
_resolvedValue = _context12.sent;
if (!isReduced(_resolvedValue)) {
_context12.next = 74;
break;
}
return _context12.abrupt('break', 80);
case 74:
_context12.next = 76;
return reducingFn(result, _resolvedValue);
case 76:
result = _context12.sent;
case 77:
_iteratorNormalCompletion5 = true;
_context12.next = 62;
break;
case 80:
_context12.next = 86;
break;
case 82:
_context12.prev = 82;
_context12.t3 = _context12['catch'](60);
_didIteratorError5 = true;
_iteratorError5 = _context12.t3;
case 86:
_context12.prev = 86;
_context12.prev = 87;
if (!_iteratorNormalCompletion5 && _iterator5.return) {
_iterator5.return();
}
case 89:
_context12.prev = 89;
if (!_didIteratorError5) {
_context12.next = 92;
break;
}
throw _iteratorError5;
case 92:
return _context12.finish(89);
case 93:
return _context12.finish(86);
case 94:
return _context12.abrupt('return', resultFn(result));
case 95:
case 'end':
return _context12.stop();
}
}
}, _callee5, undefined, [[60, 82, 86, 94], [87,, 89, 93]]);
}));
return function reduceAsync(_x11, _x12, _x13, _x14) {
return _ref9.apply(this, arguments);
};
}();
/**
* append is a transducer fn
* append:: fn -> acc -> x -> acc
*/
var append = function append(reducingFn) {
var _ref13 = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {},
_ref13$factory = _ref13.factory,
factory = _ref13$factory === undefined ? identity : _ref13$factory;
return function (acc, input) {
return factory([].concat((0, _toConsumableArray3.default)(acc), [input]));
};
};
var appendAsync = function appendAsync(reducingFn) {
var _ref14 = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {},
_ref14$factory = _ref14.factory,
factory = _ref14$factory === undefined ? identity : _ref14$factory;
return function () {
var _ref15 = (0, _asyncToGenerator3.default)( /*#__PURE__*/_regenerator2.default.mark(function _callee6(acc, input) {
return _regenerator2.default.wrap(function _callee6$(_context13) {
while (1) {
switch (_context13.prev = _context13.next) {
case 0:
_context13.t0 = factory;
_context13.t1 = [];
_context13.t2 = _toConsumableArray3.default;
_context13.next = 5;
return acc;
case 5:
_context13.t3 = _context13.sent;
_context13.t4 = (0, _context13.t2)(_context13.t3);
_context13.t5 = [input];
_context13.t6 = _context13.t1.concat.call(_context13.t1, _context13.t4, _context13.t5);
return _context13.abrupt('return', (0, _context13.t0)(_context13.t6));
case 10:
case 'end':