UNPKG

iter-tools-es

Version:
151 lines (123 loc) 3.27 kB
const { isIterable } = require('../impls/is-iterable/is-iterable.js'); const { isLoopable } = require('../impls/is-loopable/is-loopable.js'); const { isWrappable } = require('../impls/is-wrappable/is-wrappable.js'); const { nullableWrap: wrap } = require('./wrap.js'); const { variadicCurryWithValidation } = require('./curry.js'); const { _, __iterate } = require('./symbols.js'); exports.wrap = wrap; exports.isIterable = isIterable; exports.isLoopable = isLoopable; exports.isWrappable = isWrappable; function ensureIterable(value) { if (!isWrappable(value)) { if (typeof value.next === 'function') { throw new TypeError('iter-tools received a value that looked like an iterator but was not iterable. Get help fixing this: https://github.com/iter-tools/iter-tools/wiki/Making-iterators-iterable'); } else throw new TypeError('Expected an iterable, null, or undefined'); } else if (isIterable(value)) { return value; } else { return wrap(value); } } exports.ensureIterable = ensureIterable; function callReturn(iterator) { if ('return' in iterator) iterator.return(); } exports.callReturn = callReturn; function BaseIterableIterator(fn, args) { this[_] = { fn, args, staticIterator: null }; } exports.BaseIterableIterator = BaseIterableIterator; Object.assign(BaseIterableIterator.prototype, { constructor: BaseIterableIterator, [__iterate]() { const { fn, args } = this[_]; return fn(...args); }, next() { const this_ = this[_]; this_.staticIterator = this_.staticIterator || this[__iterate](); return this_.staticIterator.next(); }, return(value) { const this_ = this[_]; this_.staticIterator = this_.staticIterator || this[__iterate](); return this_.staticIterator.return(value); }, throw(error) { const this_ = this[_]; this_.staticIterator = this_.staticIterator || this[__iterate](); return this_.staticIterator.throw(error); } }); function IterableIterator(...args) { BaseIterableIterator.apply(this, args); } exports.IterableIterator = IterableIterator; IterableIterator.prototype = Object.assign(Object.create(BaseIterableIterator.prototype), { constructor: IterableIterator, [Symbol.iterator]() { return this[__iterate](); } }); function makeFunctionConfig(fn, fnConfig = {}) { const { validateArgs = _ => {}, variadic = false, reduces = false, growRight = false, minArgs = fn.length - 1, maxArgs = fn.length - 1, applyOnIterableArgs = ensureIterable } = fnConfig; return { fn, validateArgs, variadic, reduces, growRight, minArgs, maxArgs, isIterable: isWrappable, iterableType: 'iterable', applyOnIterableArgs, IterableClass: IterableIterator }; } function cache(it) { return [...it]; } exports.cache = cache; function wrapWithIterableIterator(fn, { validateArgs = _ => _ } = {}) { return (...args) => { validateArgs(args); return new IterableIterator(fn, args); }; } exports.wrapWithIterableIterator = wrapWithIterableIterator; const iterableCurry = (fn, config) => { return variadicCurryWithValidation(makeFunctionConfig(fn, config)); }; exports.iterableCurry = iterableCurry;