UNPKG

mingo

Version:

MongoDB query language for in-memory objects

191 lines (190 loc) 5.29 kB
var __defProp = Object.defineProperty; var __getOwnPropDesc = Object.getOwnPropertyDescriptor; var __getOwnPropNames = Object.getOwnPropertyNames; var __hasOwnProp = Object.prototype.hasOwnProperty; var __export = (target, all) => { for (var name in all) __defProp(target, name, { get: all[name], enumerable: true }); }; var __copyProps = (to, from, except, desc) => { if (from && typeof from === "object" || typeof from === "function") { for (let key of __getOwnPropNames(from)) if (!__hasOwnProp.call(to, key) && key !== except) __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable }); } return to; }; var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod); var lazy_exports = {}; __export(lazy_exports, { Iterator: () => Iterator, Lazy: () => Lazy, concat: () => concat }); module.exports = __toCommonJS(lazy_exports); var import_util = require("./util"); function Lazy(source) { return source instanceof Iterator ? source : new Iterator(source); } function concat(...iterators) { let index = 0; return Lazy(() => { while (index < iterators.length) { const o = iterators[index].next(); if (!o.done) return o; index++; } return { done: true }; }); } function isGenerator(o) { return !!o && typeof o === "object" && typeof o?.next === "function"; } function isIterable(o) { return !!o && (typeof o === "object" || typeof o === "function") && typeof o[Symbol.iterator] === "function"; } class Iterator { #iteratees = []; #buffer = []; #getNext; #done = false; constructor(source) { const iter = isIterable(source) ? source[Symbol.iterator]() : isGenerator(source) ? source : typeof source === "function" ? { next: source } : null; (0, import_util.assert)( !!iter, `Iterator must be initialized with an iterable or function.` ); let index = -1; let current = { done: false }; this.#getNext = () => { while (!current.done) { current = iter.next(); if (current.done) break; let value = current.value; index++; const ok = this.#iteratees.every(({ op: action, fn }) => { const res = fn(value, index); return action === "map" ? !!(value = res) || true : res; }); if (ok) return { value, done: false }; } return { done: true }; }; } /** * Add an iteratee to this lazy sequence */ push(op, fn) { this.#iteratees.push({ op, fn }); return this; } next() { return this.#getNext(); } // Iteratees methods /** * Transform each item in the sequence to a new value * @param {Function} f */ map(f) { return this.push("map", f); } /** * Select only items matching the given predicate * @param {Function} f */ filter(f) { return this.push("filter", f); } /** * Take given numbe for values from sequence * @param {Number} n A number greater than 0 */ take(n) { return n > 0 ? this.filter((_) => !(n === 0 || n-- === 0)) : this; } /** * Drop a number of values from the sequence * @param {Number} n Number of items to drop greater than 0 */ drop(n) { return n > 0 ? this.filter((_) => n === 0 || n-- === 0) : this; } // Transformations /** * Returns a new lazy object with results of the transformation * The entire sequence is realized. * * @param {Callback<Source, Any[]>} fn Tranform function of type (Array) => (Any) */ transform(fn) { const self = this; let iter; return Lazy(() => { if (!iter) iter = Lazy(fn(self.value())); return iter.next(); }); } /** * Retrieves all remaining values from the lazy evaluation and returns them as an array. * This method processes the underlying iterator until it is exhausted, storing the results * in an internal buffer to ensure subsequent calls return the same data. */ value() { while (!this.#done) { const { done, value } = this.#getNext(); if (!done) this.#buffer.push(value); this.#done = done; } return this.#buffer; } /** * Execute the callback for each value. * @param f The callback function. * @returns {Boolean} Returns false if the callback returned false to break the loop, otherwise true. */ each(f) { for (; ; ) { const o = this.next(); if (o.done) break; if (f(o.value) === false) return false; } return true; } /** * Returns the reduction of sequence according the reducing function * * @param f The reducing function * @param initialValue The initial value */ reduce(f, initialValue) { let o = this.next(); if (initialValue === void 0 && !o.done) { initialValue = o.value; o = this.next(); } while (!o.done) { initialValue = f(initialValue, o.value); o = this.next(); } return initialValue; } /** * Returns the number of matched items in the sequence */ size() { return this.reduce( ((acc, _) => ++acc), 0 ); } [Symbol.iterator]() { return this; } } // Annotate the CommonJS export names for ESM import in node: 0 && (module.exports = { Iterator, Lazy, concat });