UNPKG

functional-pipelines

Version:
1,451 lines (1,213 loc) 66 kB
'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':