doddle
Version:
Tiny yet feature-packed (async) iteration toolkit.
128 lines • 4.54 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.seq = seq;
const index_js_1 = require("../doddle/index.js");
const error_js_1 = require("../errors/error.js");
const utils_js_1 = require("../utils.js");
const seq_class_js_1 = require("./seq.class.js");
function seq(input) {
input = (0, error_js_1.checkSeqInputValue)(input);
if ((0, utils_js_1.isNextable)(input)) {
return seq(() => input).cache();
}
if ((0, utils_js_1.isIterable)(input) || (0, utils_js_1.isArrayLike)(input)) {
return seq(() => input);
}
return (0, seq_class_js_1.SeqOperator)(input, function* seq(input) {
const invoked = typeof input === "function" ? input() : input;
let pulled = (0, index_js_1.pull)(invoked);
if ((0, utils_js_1.isArrayLike)(pulled)) {
for (const key of Object.keys(pulled)) {
if ((0, utils_js_1.isInt)(+key)) {
yield (0, index_js_1.pull)(pulled[+key]);
}
}
return;
}
if ((0, utils_js_1.isIterable)(pulled)) {
pulled = (0, utils_js_1._iter)(pulled);
}
for (let item = pulled.next(); !item.done; item = pulled.next()) {
if ((0, utils_js_1.isThenable)(item)) {
(0, error_js_1.gotAsyncIteratorInSyncContext)();
}
yield (0, index_js_1.pull)(item.value);
}
pulled.return?.();
});
}
/**
* Tools for creating {@link Seq} instances.
*
* @category Create
* @example
* seq.range(0, 10) // { 0 .. 10 }
* seq.iterate(5, i => i * 2) // { 0, 2, 4, 6, 8 }
*/
(function (seq) {
/**
* Creates a {@link Seq} of items by iterating a projection function.
*
* @param count Number of items to iterate
* @param projection Function that receives the index and returns the item for that index.
* @returns A {@link Seq} of the generated items.
*/
function iterate(count, projection) {
const c = (0, error_js_1.chk)(iterate);
c.count(count);
c.projection(projection);
return seq(function* () {
for (let i = 0; i < count; i++) {
yield projection(i);
}
});
}
seq.iterate = iterate;
/**
* Creates a {@link Seq} from the own, enumerable, string key-value pairs of an object, evaluated
* lazily.
*
* @template Object Type of the source object.
* @param source Source object to create the {@link Seq} from.
* @returns A {@link Seq} of key-value pairs from the source object.
*/
function fromObject(source) {
const c = (0, error_js_1.chk)(fromObject);
c.source(source);
return seq(() => Object.keys(source)).map(key => [key, source[key]]);
}
seq.fromObject = fromObject;
/**
* Creates a {@link Seq} of numbers in the specified range.
*
* @param start Starting number of the range.
* @param end Ending number of the range (exclusive).
* @param size Step size for the range. Defaults to 1.
* @returns A {@link Seq} of numbers in the specified range.
*/
function range(start, end, size = 1) {
const c = (0, error_js_1.chk)(range);
c.size(size);
c.start(start);
c.end(end);
const direction = Math.sign(end - start);
return seq(function* range() {
for (let i = start; direction * i < direction * end; i += direction * size) {
yield i;
}
});
}
seq.range = range;
/**
* Checks if the provided input is a {@link Seq}.
*
* @template T Type of items in the {@link Seq}.
* @param input Input to check.
* @returns `true` if the input is a {@link Seq}, otherwise `false`.
*/
function is(input) {
return input instanceof seq_class_js_1.Seq;
}
seq.is = is;
/**
* Creates a {@link Seq} that throws an error when iterated.
*
* @param thrower Function that returns the error to throw.
* @returns A {@link Seq} that throws the specified error when iterated.
*/
function throws(thrower) {
thrower = (0, error_js_1.chk)(throws).thrower(thrower);
return (0, seq_class_js_1.SeqOperator)(thrower, function* throws(input) {
const result = input();
throw result;
});
}
seq.throws = throws;
})(seq || (exports.seq = seq = {}));
(0, error_js_1.loadCheckers)(seq);
//# sourceMappingURL=seq.ctor.js.map