mingo
Version:
MongoDB query language for in-memory objects
273 lines (272 loc) • 7.32 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,
compose: () => compose
});
module.exports = __toCommonJS(lazy_exports);
var import_util = require("./util");
function Lazy(source) {
return source instanceof Iterator ? source : new Iterator(source);
}
function compose(...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" && o?.next instanceof Function;
}
function dropItem(array, i) {
const rest = array.slice(i + 1);
array.splice(i);
Array.prototype.push.apply(array, rest);
}
const DONE = new Error();
var Action = /* @__PURE__ */ ((Action2) => {
Action2[Action2["MAP"] = 0] = "MAP";
Action2[Action2["FILTER"] = 1] = "FILTER";
Action2[Action2["TAKE"] = 2] = "TAKE";
Action2[Action2["DROP"] = 3] = "DROP";
return Action2;
})(Action || {});
function createCallback(nextFn, iteratees, buffer) {
let done = false;
let index = -1;
let bufferIndex = 0;
return function(storeResult) {
try {
outer:
while (!done) {
let o = nextFn();
index++;
let i = -1;
const size = iteratees.length;
let innerDone = false;
while (++i < size) {
const r = iteratees[i];
switch (r.action) {
case 0 /* MAP */:
o = r.func(o, index);
break;
case 1 /* FILTER */:
if (!r.func(o, index))
continue outer;
break;
case 2 /* TAKE */:
--r.count;
if (!r.count)
innerDone = true;
break;
case 3 /* DROP */:
--r.count;
if (!r.count)
dropItem(iteratees, i);
continue outer;
default:
break outer;
}
}
done = innerDone;
if (storeResult) {
buffer[bufferIndex++] = o;
} else {
return { value: o, done: false };
}
}
} catch (e) {
if (e !== DONE)
throw e;
}
done = true;
return { done };
};
}
class Iterator {
/**
* @param {*} source An iterable object or function.
* Array - return one element per cycle
* Object{next:Function} - call next() for the next value (this also handles generator functions)
* Function - call to return the next value
* @param {Function} fn An optional transformation function
*/
constructor(source) {
this.iteratees = [];
this.yieldedValues = [];
this.isDone = false;
let nextVal;
if (source instanceof Function) {
source = { next: source };
}
if (isGenerator(source)) {
const src = source;
nextVal = () => {
const o = src.next();
if (o.done)
throw DONE;
return o.value;
};
} else if (source instanceof Array) {
const data = source;
const size = data.length;
let index = 0;
nextVal = () => {
if (index < size)
return data[index++];
throw DONE;
};
} else if (!(source instanceof Function)) {
throw new import_util.MingoError(
`Lazy must be initialized with an array, generator, or function.`
);
}
this.getNext = createCallback(nextVal, this.iteratees, this.yieldedValues);
}
/**
* Add an iteratee to this lazy sequence
*/
push(action, value) {
if (typeof value === "function") {
this.iteratees.push({ action, func: value });
} else if (typeof value === "number") {
this.iteratees.push({ action, count: value });
}
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(0 /* MAP */, f);
}
/**
* Select only items matching the given predicate
* @param {Function} pred
*/
filter(predicate) {
return this.push(1 /* FILTER */, predicate);
}
/**
* Take given numbe for values from sequence
* @param {Number} n A number greater than 0
*/
take(n) {
return n > 0 ? this.push(2 /* TAKE */, n) : 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.push(3 /* DROP */, n) : this;
}
// Transformations
/**
* Returns a new lazy object with results of the transformation
* The entire sequence is realized.
*
* @param {Callback<Source, RawArray>} 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();
});
}
// Terminal methods
/**
* Returns the fully realized values of the iterators.
* The return value will be an array unless `lazy.first()` was used.
* The realized values are cached for subsequent calls.
*/
value() {
if (!this.isDone) {
this.isDone = this.getNext(true).done;
}
return this.yieldedValues;
}
/**
* Execute the funcion for each value. Will stop when an execution returns false.
* @param {Function} f
* @returns {Boolean} false iff `f` return false for AnyVal execution, 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 a reducing function
* @param {*} initialValue
*/
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,
compose
});