memory-orm
Version:
client side ORM + map reduce
253 lines (252 loc) • 6.12 kB
JavaScript
'use strict'
Object.defineProperty(exports, '__esModule', { value: true })
exports.Query = void 0
const tslib_1 = require('tslib')
const get_1 = tslib_1.__importDefault(require('lodash/get'))
const uniq_1 = tslib_1.__importDefault(require('lodash/uniq'))
const isEqual_1 = tslib_1.__importDefault(require('lodash/isEqual'))
const property_1 = tslib_1.__importDefault(require('lodash/property'))
const cloneDeep_1 = tslib_1.__importDefault(require('lodash/cloneDeep'))
function set_for(list) {
const set = {}
Reflect.setPrototypeOf(set, null)
for (let key of list) {
set[key] = true
}
return set
}
function query_parser(base, req, cb) {
if (!req) {
return base
}
return new Query(base, function () {
this._filters = base._filters.concat()
if (req instanceof Function || req instanceof Array || 'string' === typeof req) {
cb(this, null, req, (o) => o)
} else if (req instanceof Object) {
for (let key in req) {
const val = req[key]
cb(this, key, val, property_1.default(key))
}
} else {
console.log({ req })
}
//throw Error 'unimplemented'
})
}
class Query {
constructor(base, tap) {
this._step = 0
this._copy(base)
tap.call(this)
}
get reduce() {
this.all._finder.calculate(this, this.all.$memory)
return this._reduce
}
get list() {
return this.reduce.list
}
get hash() {
return this.reduce.hash
}
get memory() {
return this.all.$memory
}
get ids() {
return Object.keys(this.hash)
}
static build({ $sort, $memory }) {
const _group = null
const _all_ids = null
const _is_uniq = true
const _filters = []
const $partition = ['set']
return new Query({ _all_ids, _group, _is_uniq, _filters, $sort, $partition }, function () {
this.all = this
this.$memory = $memory
})
}
_copy({ all, _all_ids, _group, _is_uniq, _filters, $sort, $partition, $page_by }) {
this.all = all
this._all_ids = _all_ids
this._group = _group
this._is_uniq = _is_uniq
this._filters = _filters
this.$sort = $sort
this.$partition = $partition
this.$page_by = $page_by
}
in(req) {
return query_parser(this, req, function (q, target, req, path) {
if (req instanceof Array) {
const set = set_for(req)
add(function (o) {
for (let key of path(o)) {
if (set[key]) {
return true
}
}
return false
})
} else if (req instanceof RegExp) {
add(function (o) {
for (let val of path(o)) {
if (req.test(val)) {
return true
}
}
return false
})
} else {
add((o) => {
var _a
return -1 < ((_a = path(o)) === null || _a === void 0 ? void 0 : _a.indexOf(req))
})
}
function add(f) {
q._filters.push(f)
}
})
}
where(req) {
return query_parser(this, req, function (q, target, req, path) {
if (req instanceof Array) {
if ('id' === target) {
q._all_ids = req
} else {
const set = set_for(req)
add((o) => set[path(o)])
}
} else if (req instanceof Function) {
add(req)
} else if (req instanceof RegExp) {
add((o) => req.test(path(o)))
} else {
if ('id' === target) {
q._all_ids = [req]
} else {
add((o) => req === path(o))
}
}
function add(f) {
q._filters.push(f)
}
})
}
partition(...ary) {
return new Query(this, function () {
this.$partition = ary
})
}
distinct(b = true) {
if (b === this._is_uniq) {
return this
}
return new Query(this, function () {
this._is_uniq = b
if (b && this._all_ids) {
this._all_ids = uniq_1.default(this._all_ids)
}
})
}
distance(key, order, point) {
return this.order('list', {
sort: [
(o) => {
let sum = 0
for (let idx = 0; idx < point.length; idx++) {
const xp = point[idx]
const xa = get_1.default(o, key)[idx]
sum += Math.pow(xa - xp, 2)
}
return Math.pow(sum, 0.5)
},
order,
],
})
}
search(text, target = 'q.search_words') {
if (!text) {
return this
}
const list = []
for (let item of text.split(/\s+/)) {
item = item.replace(/[-\/\\^$*+?.()|[\]{}]/g, '\\$&')
if (!item.length) {
continue
}
list.push(`(${item})`)
}
if (!list.length) {
return this
}
const regexp = new RegExp(list.join('|'), 'ig')
return this.where(function (o) {
const s = get_1.default(o, target)
return !s || regexp.test(s)
})
}
shuffle() {
return this.sort(Math.random)
}
order(keys, order) {
if (!keys.length) {
keys = ['list']
}
if ('string' === typeof keys) {
keys = [keys]
}
const path = [`_reduce`, ...keys].join('.')
if (isEqual_1.default(order, this.$sort[path])) {
return this
}
return new Query(this, function () {
this.$sort = cloneDeep_1.default(this.$sort)
this.$sort[path] = order
})
}
sort(...sort) {
return this.order([], { sort })
}
page(page_by) {
return new Query(this, function () {
this.$page_by = page_by
})
}
form(...ids) {
const oo = this.find(...ids)
if (oo) {
const datum = this.all.$memory[oo.id]
const o = datum.form || (datum.form = {})
Reflect.setPrototypeOf(o, oo)
return o
} else {
return null
}
}
find(...ids) {
for (let id of ids) {
const o = this.hash[id]
if (o) {
return o
}
}
return null
}
finds(ids) {
const result = []
for (let id of ids) {
const o = this.hash[id]
if (o) {
result.push(o)
}
}
return result
}
pluck(...keys) {
return this.list.pluck(...arguments)
}
}
exports.Query = Query
//# sourceMappingURL=query.js.map