UNPKG

mingo

Version:

MongoDB query language for in-memory objects

204 lines (203 loc) 7.38 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 cursor_exports = {}; __export(cursor_exports, { Cursor: () => Cursor }); module.exports = __toCommonJS(cursor_exports); var import_core = require("./core"); var import_lazy = require("./lazy"); var import_limit = require("./operators/pipeline/limit"); var import_project = require("./operators/pipeline/project"); var import_skip = require("./operators/pipeline/skip"); var import_sort = require("./operators/pipeline/sort"); var import_util = require("./util"); const OPERATORS = { $sort: import_sort.$sort, $skip: import_skip.$skip, $limit: import_limit.$limit }; class Cursor { #source; #predicate; #projection; #options; #operators = {}; #result = null; #buffer = []; /** * Creates an instance of the Cursor class. * * @param source - The source of data to be iterated over. * @param predicate - A function or condition to filter the data. * @param projection - An object specifying the fields to include or exclude in the result. * @param options - Optional settings to customize the behavior of the cursor. */ constructor(source, predicate, projection, options) { this.#source = source; this.#predicate = predicate; this.#projection = projection; this.#options = options; } /** Returns the iterator from running the query */ fetch() { if (this.#result) return this.#result; this.#result = (0, import_lazy.Lazy)(this.#source).filter(this.#predicate); const mode = this.#options.processingMode; if (mode & import_core.ProcessingMode.CLONE_INPUT) this.#result.map(import_util.cloneDeep); for (const op of ["$sort", "$skip", "$limit"]) { if ((0, import_util.has)(this.#operators, op)) { this.#result = OPERATORS[op]( this.#result, this.#operators[op], this.#options ); } } if (Object.keys(this.#projection).length) { this.#result = (0, import_project.$project)(this.#result, this.#projection, this.#options); } if (mode & import_core.ProcessingMode.CLONE_OUTPUT) this.#result.map(import_util.cloneDeep); return this.#result; } /** Returns an iterator with the buffered data included */ fetchAll() { const buffered = (0, import_lazy.Lazy)([...this.#buffer]); this.#buffer.length = 0; return (0, import_lazy.concat)(buffered, this.fetch()); } /** * Return remaining objects in the cursor as an array. This method exhausts the cursor * @returns {Array} */ all() { return this.fetchAll().value(); } /** * Returns the number of objects return in the cursor. This method exhausts the cursor * @returns {Number} */ count() { return this.all().length; } /** * Returns a cursor that begins returning results only after passing or skipping a number of documents. * @param {Number} n the number of results to skip. * @return {Cursor} Returns the cursor, so you can chain this call. */ skip(n) { this.#operators["$skip"] = n; return this; } /** * Limits the number of items returned by the cursor. * * @param n - The maximum number of items to return. * @returns The current cursor instance for chaining. */ limit(n) { this.#operators["$limit"] = n; return this; } /** * Returns results ordered according to a sort specification. * @param {AnyObject} modifier an object of key and values specifying the sort order. 1 for ascending and -1 for descending * @return {Cursor} Returns the cursor, so you can chain this call. */ sort(modifier) { this.#operators["$sort"] = modifier; return this; } /** * Applies a sort operation to the cursor using the specified sort modifier. * * @param modifier - An object specifying the sort order. The keys represent * the field names, and the values indicate the sort direction (e.g., 1 for * ascending and -1 for descending). * @returns The current cursor instance for method chaining. */ collation(spec) { this.#options = { ...this.#options, collation: spec }; return this; } /** * Retrieves the next item in the cursor. * * If there are items in the internal buffer, the next item is returned from the buffer. * Otherwise, it fetches the next item from the underlying data source. * * @returns The next item of type `T` if available, or `undefined` if there are no more items. */ next() { if (this.#buffer.length > 0) { return this.#buffer.pop(); } const o = this.fetch().next(); if (o.done) return; return o.value; } /** * Determines if there are more elements available in the cursor. * * This method checks if there are any elements left in the internal buffer. * If the buffer is empty, it attempts to fetch the next element from the source. * If a new element is found, it is added to the buffer and the method returns `true`. * Otherwise, it returns `false` indicating no more elements are available. * * @returns {boolean} `true` if there are more elements to iterate over, otherwise `false`. */ hasNext() { if (this.#buffer.length > 0) return true; const o = this.fetch().next(); if (o.done) return false; this.#buffer.push(o.value); return true; } /** * Transforms the elements of the cursor using the provided callback function. * * @template R - The type of the elements in the resulting array. * @template T - The type of the elements in the cursor. * @param fn - A callback function that is invoked for each element in the cursor. * It receives the current element, its index, and the entire array as arguments. * @returns An array of transformed elements of type `R`. */ map(fn) { return this.all().map(fn); } /** * Iterates over all elements in the cursor and executes the provided callback function for each element. * * @param fn - A callback function to execute for each element. The function receives the following arguments: * - `t`: The current element being processed in the cursor. * - `i`: The index of the current element in the array. * - `a`: The array of all elements in the cursor. */ forEach(fn) { this.all().forEach(fn); } /** * Returns an iterator for the cursor, allowing it to be used in `for...of` loops. * The iterator fetches all the results from the cursor. * * @returns {Iterator} An iterator over the fetched results. */ [Symbol.iterator]() { return this.fetchAll(); } } // Annotate the CommonJS export names for ESM import in node: 0 && (module.exports = { Cursor });