UNPKG

doddle

Version:

Tiny yet feature-packed (async) iteration toolkit.

128 lines 4.47 kB
import { pull } from "../doddle/index.js"; import { checkASeqInputValue, chk, loadCheckers } from "../errors/error.js"; import { _xiter, isArrayLike, isAsyncIterable, isInt, isIterable, isNextable, isReadableStream } from "../utils.js"; import { ASeq, ASeqOperator } from "./aseq.class.js"; import { seq } from "./seq.ctor.js"; export function aseq(input) { function fromFunctionResult(input) { return ASeqOperator(input, async function* aseq(input) { const pulled = await pull(input); if (isAsyncIterable(pulled) || isIterable(pulled)) { var iterator = _xiter(pulled); } else if (isArrayLike(pulled)) { for (const key of Object.keys(pulled)) { if (isInt(+key)) { yield pull(pulled[+key]); } } return; } else { iterator = pulled; } for (let item = await iterator.next(); !item.done; item = await iterator.next()) { yield pull(item.value); } await iterator.return?.(); }); } input = checkASeqInputValue(input); if (isNextable(input) || isReadableStream(input)) { // readable streams are basically iterators return fromFunctionResult(input).cache(); } if (isAsyncIterable(input) || isIterable(input)) { return aseq(() => input); } return ASeqOperator(input, async function* aseq(input) { const result = typeof input === "function" ? await input() : input; const pulled = await pull(result); if (isNextable(pulled) || isReadableStream(pulled)) { yield* fromFunctionResult(pulled).cache(); } yield* fromFunctionResult(pulled); }); } /** * Tools for creating {@link ASeq} instances. * * @category Create * @class */ (function (aseq) { /** * Creates a {@link Seq} from the own, enumerable, string key-value pairs of an object. Values * are produced 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 = chk(fromObject); c.source(source); return aseq(() => Object.keys(source)).map(key => [key, source[key]]); } aseq.fromObject = fromObject; /** * Creates an {@link ASeq} 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, * possibly asynchronously. * @returns An {@link ASeq} of the generated items. */ function iterate(count, projection) { const c = chk(iterate); c.count(count); c.projection(projection); return aseq(async function* () { for (let i = 0; i < count; i++) { yield pull(projection(i)); } }); } aseq.iterate = iterate; /** * Creates an {@link ASeq} 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 An {@link ASeq} of numbers in the specified range. */ function range(start, end, size = 1) { const c = chk(range); c.size(size); c.start(start); c.end(end); return aseq(seq.range(start, end, size)); } aseq.range = range; /** * Checks if the provided input is an {@link ASeq}. * * @param input Input to check. * @returns `true` if the input is an {@link ASeq}, otherwise `false`. */ function is(input) { return input instanceof ASeq; } aseq.is = is; /** * Creates an {@link ASeq} that throws an error when iterated. * * @param thrower Function that returns the error to throw. * @returns An {@link ASeq} that throws the specified error when iterated. */ function throws(thrower) { thrower = chk(throws).thrower(thrower); return aseq(() => { throw thrower(); }); } aseq.throws = throws; })(aseq || (aseq = {})); loadCheckers(aseq); //# sourceMappingURL=aseq.ctor.js.map