mingo
Version:
MongoDB query language for in-memory objects
191 lines (190 loc) • 5.29 kB
JavaScript
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
});