UNPKG

devextreme

Version:

HTML5 JavaScript Component Suite for Responsive Web Development

568 lines (563 loc) • 18.4 kB
/** * DevExtreme (cjs/__internal/data/m_array_query.js) * Version: 24.2.6 * Build date: Mon Mar 17 2025 * * Copyright (c) 2012 - 2025 Developer Express Inc. ALL RIGHTS RESERVED * Read about DevExtreme licensing here: https://js.devexpress.com/Licensing/ */ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = void 0; var _errors = require("../../common/data/errors"); var _utils = require("../../common/data/utils"); var _class = _interopRequireDefault(require("../../core/class")); var _data = require("../../core/utils/data"); var _deferred = require("../../core/utils/deferred"); var _iterator = require("../../core/utils/iterator"); var _type = require("../../core/utils/type"); function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e } } const Iterator = _class.default.inherit({ toArray() { const result = []; this.reset(); while (this.next()) { result.push(this.current()) } return result }, countable: () => false }); const ArrayIterator = Iterator.inherit({ ctor(array) { this.array = array; this.index = -1 }, next() { if (this.index + 1 < this.array.length) { this.index++; return true } return false }, current() { return this.array[this.index] }, reset() { this.index = -1 }, toArray() { return this.array.slice(0) }, countable: () => true, count() { return this.array.length } }); const WrappedIterator = Iterator.inherit({ ctor(iter) { this.iter = iter }, next() { return this.iter.next() }, current() { return this.iter.current() }, reset() { return this.iter.reset() } }); const MapIterator = WrappedIterator.inherit({ ctor(iter, mapper) { this.callBase(iter); this.index = -1; this.mapper = mapper }, current() { return this.mapper(this.callBase(), this.index) }, next() { const hasNext = this.callBase(); if (hasNext) { this.index++ } return hasNext } }); const defaultCompare = function(xValue, yValue, options) { if ((0, _type.isString)(xValue) && (0, _type.isString)(yValue) && (null !== options && void 0 !== options && options.locale || null !== options && void 0 !== options && options.collatorOptions)) { return new Intl.Collator((null === options || void 0 === options ? void 0 : options.locale) || void 0, (null === options || void 0 === options ? void 0 : options.collatorOptions) || void 0).compare(xValue, yValue) } xValue = (0, _data.toComparable)(xValue, false, options); yValue = (0, _data.toComparable)(yValue, false, options); if (null === xValue && null !== yValue) { return -1 } if (null !== xValue && null === yValue) { return 1 } if (void 0 === xValue && void 0 !== yValue) { return 1 } if (void 0 !== xValue && void 0 === yValue) { return -1 } if (xValue < yValue) { return -1 } if (xValue > yValue) { return 1 } return 0 }; const SortIterator = Iterator.inherit({ ctor(iter, getter, desc, compare) { this.langParams = iter.langParams; if (!(iter instanceof MapIterator)) { iter = new MapIterator(iter, this._wrap); iter.langParams = this.langParams } this.iter = iter; this.rules = [{ getter: getter, desc: desc, compare: compare, langParams: this.langParams }] }, thenBy(getter, desc, compare) { const result = new SortIterator(this.sortedIter || this.iter, getter, desc, compare); if (!this.sortedIter) { result.rules = this.rules.concat(result.rules) } return result }, next() { this._ensureSorted(); return this.sortedIter.next() }, current() { this._ensureSorted(); return this.sortedIter.current() }, reset() { delete this.sortedIter }, countable() { return this.sortedIter || this.iter.countable() }, count() { if (this.sortedIter) { return this.sortedIter.count() } return this.iter.count() }, _ensureSorted() { const that = this; if (that.sortedIter) { return }(0, _iterator.each)(that.rules, (function() { this.getter = (0, _data.compileGetter)(this.getter) })); that.sortedIter = new MapIterator(new ArrayIterator(this.iter.toArray().sort(((x, y) => that._compare(x, y)))), that._unwrap) }, _wrap: (record, index) => ({ index: index, value: record }), _unwrap: wrappedItem => wrappedItem.value, _getDefaultCompare: langParams => (xValue, yValue) => defaultCompare(xValue, yValue, langParams), _compare(x, y) { const xIndex = x.index; const yIndex = y.index; x = x.value; y = y.value; if (x === y) { return xIndex - yIndex } for (let i = 0, rulesCount = this.rules.length; i < rulesCount; i++) { const rule = this.rules[i]; const xValue = rule.getter(x); const yValue = rule.getter(y); const compare = rule.compare || this._getDefaultCompare(rule.langParams); const compareResult = compare(xValue, yValue); if (compareResult) { return rule.desc ? -compareResult : compareResult } } return xIndex - yIndex } }); const compileCriteria = function() { let langParams = {}; const _toComparable = value => (0, _data.toComparable)(value, false, langParams); const compileGroup = function(crit) { if ((0, _utils.isUniformEqualsByOr)(crit)) { return (crit => { const getter = (0, _data.compileGetter)(crit[0][0]); const filterValues = crit.reduce(((acc, item, i) => { if (i % 2 === 0) { acc.push(_toComparable(item[2])) } return acc }), []); return obj => { const value = _toComparable(getter(obj)); return filterValues.some((filterValue => useStrictComparison(filterValue) ? value === filterValue : value == filterValue)) } })(crit) } const ops = []; let isConjunctiveOperator = false; let isConjunctiveNextOperator = false; (0, _iterator.each)(crit, (function() { if (Array.isArray(this) || (0, _type.isFunction)(this)) { if (ops.length > 1 && isConjunctiveOperator !== isConjunctiveNextOperator) { throw _errors.errors.Error("E4019") } ops.push(compileCriteria(this, langParams)); isConjunctiveOperator = isConjunctiveNextOperator; isConjunctiveNextOperator = true } else { isConjunctiveNextOperator = (0, _utils.isConjunctiveOperator)(this) } })); return function(d) { let result = isConjunctiveOperator; for (let i = 0; i < ops.length; i++) { if (ops[i](d) !== isConjunctiveOperator) { result = !isConjunctiveOperator; break } } return result } }; const toString = function(value) { var _langParams; return (0, _type.isDefined)(value) ? null !== (_langParams = langParams) && void 0 !== _langParams && _langParams.locale ? value.toLocaleString(langParams.locale) : value.toString() : "" }; function compileEquals(getter, value, negate) { return function(obj) { obj = _toComparable(getter(obj)); let result = useStrictComparison(value) ? obj === value : obj == value; if (negate) { result = !result } return result } } function useStrictComparison(value) { return "" === value || 0 === value || false === value } return function(crit, options) { langParams = options || {}; if ((0, _type.isFunction)(crit)) { return crit } if ((0, _utils.isGroupCriterion)(crit)) { return compileGroup(crit) } if ((0, _utils.isUnaryOperation)(crit)) { return function(crit) { const op = crit[0]; const criteria = compileCriteria(crit[1], langParams); if ("!" === op) { return function(obj) { return !criteria(obj) } } throw _errors.errors.Error("E4003", op) }(crit) } return function(crit) { crit = (0, _utils.normalizeBinaryCriterion)(crit); const getter = (0, _data.compileGetter)(crit[0]); const op = crit[1]; let value = crit[2]; value = _toComparable(value); const compare = (obj, operatorFn) => { obj = _toComparable(getter(obj)); return (null == value || null == obj) && value !== obj ? false : operatorFn(obj, value) }; switch (op.toLowerCase()) { case "=": return compileEquals(getter, value); case "<>": return compileEquals(getter, value, true); case ">": return obj => compare(obj, ((a, b) => a > b)); case "<": return obj => compare(obj, ((a, b) => a < b)); case ">=": return obj => compare(obj, ((a, b) => a >= b)); case "<=": return obj => compare(obj, ((a, b) => a <= b)); case "startswith": return obj => _toComparable(toString(getter(obj))).startsWith(value); case "endswith": return obj => _toComparable(toString(getter(obj))).endsWith(value); case "contains": return obj => _toComparable(toString(getter(obj))).includes(value); case "notcontains": return obj => !_toComparable(toString(getter(obj))).includes(value) } throw _errors.errors.Error("E4003", op) }(crit) } }(); const FilterIterator = WrappedIterator.inherit({ ctor(iter, criteria) { this.callBase(iter); this.langParams = iter.langParams; this.criteria = compileCriteria(criteria, this.langParams) }, next() { while (this.iter.next()) { if (this.criteria(this.current())) { return true } } return false } }); const GroupIterator = Iterator.inherit({ ctor(iter, getter) { this.iter = iter; this.getter = getter }, next() { this._ensureGrouped(); return this.groupedIter.next() }, current() { this._ensureGrouped(); return this.groupedIter.current() }, reset() { delete this.groupedIter }, countable() { return !!this.groupedIter }, count() { return this.groupedIter.count() }, _ensureGrouped() { if (this.groupedIter) { return } const hash = {}; const keys = []; const { iter: iter } = this; const getter = (0, _data.compileGetter)(this.getter); iter.reset(); while (iter.next()) { const current = iter.current(); const key = getter(current); if (key in hash) { hash[key].push(current) } else { hash[key] = [current]; keys.push(key) } } this.groupedIter = new ArrayIterator((0, _iterator.map)(keys, (key => ({ key: key, items: hash[key] })))) } }); const SelectIterator = WrappedIterator.inherit({ ctor(iter, getter) { this.callBase(iter); this.getter = (0, _data.compileGetter)(getter) }, current() { return this.getter(this.callBase()) }, countable() { return this.iter.countable() }, count() { return this.iter.count() } }); const SliceIterator = WrappedIterator.inherit({ ctor(iter, skip, take) { this.callBase(iter); this.skip = Math.max(0, skip); this.take = Math.max(0, take); this.pos = 0 }, next() { if (this.pos >= this.skip + this.take) { return false } while (this.pos < this.skip && this.iter.next()) { this.pos++ } this.pos++; return this.iter.next() }, reset() { this.callBase(); this.pos = 0 }, countable() { return this.iter.countable() }, count() { return Math.min(this.iter.count() - this.skip, this.take) } }); const arrayQueryImpl = function(iter, queryOptions) { queryOptions = queryOptions || {}; if (!(iter instanceof Iterator)) { iter = new ArrayIterator(iter) } if (queryOptions.langParams) { iter.langParams = queryOptions.langParams } const handleError = function(error) { const handler = queryOptions.errorHandler; if (handler) { handler(error) }(0, _errors.handleError)(error) }; const aggregateCore = function(aggregator) { const d = (new _deferred.Deferred).fail(handleError); let seed; const { step: step } = aggregator; const { finalize: finalize } = aggregator; try { iter.reset(); if ("seed" in aggregator) { seed = aggregator.seed } else { seed = iter.next() ? iter.current() : NaN } let accumulator = seed; while (iter.next()) { accumulator = step(accumulator, iter.current()) } d.resolve(finalize ? finalize(accumulator) : accumulator) } catch (x) { d.reject(x) } return d.promise() }; const standardAggregate = function(name) { return aggregateCore(_utils.aggregators[name]) }; const select = function(getter) { if (!(0, _type.isFunction)(getter) && !Array.isArray(getter)) { getter = [].slice.call(arguments) } return chainQuery(new SelectIterator(iter, getter)) }; const selectProp = function(name) { return select((0, _data.compileGetter)(name)) }; function chainQuery(iter) { return arrayQueryImpl(iter, queryOptions) } return { toArray: () => iter.toArray(), enumerate() { const d = (new _deferred.Deferred).fail(handleError); try { d.resolve(iter.toArray()) } catch (x) { d.reject(x) } return d.promise() }, setLangParams(options) { iter.langParams = options }, sortBy: (getter, desc, compare) => chainQuery(new SortIterator(iter, getter, desc, compare)), thenBy(getter, desc, compare) { if (iter instanceof SortIterator) { return chainQuery(iter.thenBy(getter, desc, compare)) } throw _errors.errors.Error("E4004") }, filter(criteria) { if (!Array.isArray(criteria)) { criteria = [].slice.call(arguments) } return chainQuery(new FilterIterator(iter, criteria)) }, slice(skip, take) { if (void 0 === take) { take = Number.MAX_VALUE } return chainQuery(new SliceIterator(iter, skip, take)) }, select: select, groupBy: getter => chainQuery(new GroupIterator(iter, getter)), aggregate: function(seed, step, finalize) { if (arguments.length < 2) { return aggregateCore({ step: arguments[0] }) } return aggregateCore({ seed: seed, step: step, finalize: finalize }) }, count() { if (iter.countable()) { const d = (new _deferred.Deferred).fail(handleError); try { d.resolve(iter.count()) } catch (x) { d.reject(x) } return d.promise() } return standardAggregate("count") }, sum(getter) { if (getter) { return selectProp(getter).sum() } return standardAggregate("sum") }, min(getter) { if (getter) { return selectProp(getter).min() } return standardAggregate("min") }, max(getter) { if (getter) { return selectProp(getter).max() } return standardAggregate("max") }, avg(getter) { if (getter) { return selectProp(getter).avg() } return standardAggregate("avg") } } }; var _default = exports.default = arrayQueryImpl;