doddle
Version:
Tiny yet feature-packed (async) iteration toolkit.
131 lines • 4.91 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.aseq = aseq;
const index_js_1 = require("../doddle/index.js");
const error_js_1 = require("../errors/error.js");
const utils_js_1 = require("../utils.js");
const aseq_class_js_1 = require("./aseq.class.js");
const seq_ctor_js_1 = require("./seq.ctor.js");
function aseq(input) {
function fromFunctionResult(input) {
return (0, aseq_class_js_1.ASeqOperator)(input, async function* aseq(input) {
const pulled = await (0, index_js_1.pull)(input);
if ((0, utils_js_1.isAsyncIterable)(pulled) || (0, utils_js_1.isIterable)(pulled)) {
var iterator = (0, utils_js_1._xiter)(pulled);
}
else 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;
}
else {
iterator = pulled;
}
for (let item = await iterator.next(); !item.done; item = await iterator.next()) {
yield (0, index_js_1.pull)(item.value);
}
await iterator.return?.();
});
}
input = (0, error_js_1.checkASeqInputValue)(input);
if ((0, utils_js_1.isNextable)(input) || (0, utils_js_1.isReadableStream)(input)) {
// readable streams are basically iterators
return fromFunctionResult(input).cache();
}
if ((0, utils_js_1.isAsyncIterable)(input) || (0, utils_js_1.isIterable)(input)) {
return aseq(() => input);
}
return (0, aseq_class_js_1.ASeqOperator)(input, async function* aseq(input) {
const result = typeof input === "function" ? await input() : input;
const pulled = await (0, index_js_1.pull)(result);
if ((0, utils_js_1.isNextable)(pulled) || (0, utils_js_1.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 = (0, error_js_1.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 = (0, error_js_1.chk)(iterate);
c.count(count);
c.projection(projection);
return aseq(async function* () {
for (let i = 0; i < count; i++) {
yield (0, index_js_1.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 = (0, error_js_1.chk)(range);
c.size(size);
c.start(start);
c.end(end);
return aseq(seq_ctor_js_1.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_class_js_1.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 = (0, error_js_1.chk)(throws).thrower(thrower);
return aseq(() => {
throw thrower();
});
}
aseq.throws = throws;
})(aseq || (exports.aseq = aseq = {}));
(0, error_js_1.loadCheckers)(aseq);
//# sourceMappingURL=aseq.ctor.js.map