@codibre/fluent-iterable
Version:
Provides LINQ-like fluent api operations for iterables and async iterables (ES2018+).
92 lines (91 loc) • 2.92 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.othersFactory = othersFactory;
exports.partIterateFactory = partIterateFactory;
exports.partitionRecipe = partitionRecipe;
const get_partition_comparer_1 = require("./get-partition-comparer");
function othersFactory(resolver) {
return (wrapper) => {
const { iterator, comparer } = wrapper;
return () => {
return resolver(iterator.next(), (next) => {
const previous = wrapper.next.value;
wrapper.next = next;
return wrapper.next.done || !comparer(previous, wrapper.next.value)
? { done: true }
: wrapper.next;
});
};
};
}
function partIterateFactory(symbol, getOthers) {
return (wrapper) => {
let call;
const others = getOthers(wrapper);
function first() {
call = others;
return wrapper.next;
}
call = first;
return {
[symbol]: () => ({
next: () => call(),
}),
};
};
}
function getValueFactory(wrapper, partIterate) {
return () => {
return wrapper.next.done
? { done: true }
: {
value: partIterate(wrapper),
};
};
}
function firstValueFactory(wrapper, callback) {
return (v) => {
wrapper.next = v;
return callback();
};
}
function nextFactory(resolver, wrapper, getValue) {
let first = true;
const { iterator } = wrapper;
return () => {
if (first) {
first = false;
return resolver(iterator.next(), firstValueFactory(wrapper, getValue));
}
return getValue();
};
}
function partitionIterateRecipe(symbol, resolver) {
return (arr, criteria) => {
const iterator = arr[symbol]();
const wrapper = {
iterator,
comparer: (0, get_partition_comparer_1.getPartitionComparer)(criteria),
};
const partIterate = partIterateFactory(symbol, othersFactory(resolver));
const getValue = getValueFactory(wrapper, partIterate);
return {
[symbol]() {
return {
next: nextFactory(resolver, wrapper, getValue),
return: iterator.return ? iterator.return.bind(iterator) : undefined,
throw: iterator.throw ? iterator.throw.bind(iterator) : undefined,
};
},
};
};
}
function partitionRecipe(symbol, resolver) {
const partitioning = partitionIterateRecipe(symbol, resolver);
return function (criteria) {
if (typeof criteria == 'number' && criteria < 1) {
throw new Error(`Validation failed, size (${criteria}) expected to be bigger than 0`);
}
return partitioning(this, criteria);
};
}