From 4a59a9a02747829ad64bffc08a2680343fdfb777 Mon Sep 17 00:00:00 2001 From: Thomas Wilkerling Date: Wed, 14 May 2025 08:28:38 +0200 Subject: [PATCH] highlighting merged document results --- dist/db/clickhouse/index.cjs | 1 - dist/db/indexeddb/index.cjs | 1 - dist/db/mongodb/index.cjs | 1 - dist/db/postgres/index.cjs | 1 - dist/db/redis/index.cjs | 1 - dist/db/sqlite/index.cjs | 1 - dist/flexsearch.bundle.debug.js | 445 +++++----- dist/flexsearch.bundle.min.js | 126 +-- dist/flexsearch.bundle.module.debug.js | 447 +++++----- dist/flexsearch.bundle.module.min.js | 128 +-- dist/flexsearch.compact.debug.js | 877 +++++++++---------- dist/flexsearch.compact.min.js | 80 +- dist/flexsearch.compact.module.debug.js | 879 ++++++++++---------- dist/flexsearch.compact.module.min.js | 82 +- dist/flexsearch.es5.debug.js | 431 +++++----- dist/flexsearch.es5.min.js | 126 +-- dist/flexsearch.light.debug.js | 2 +- dist/flexsearch.light.min.js | 2 +- dist/flexsearch.light.module.debug.js | 2 +- dist/flexsearch.light.module.min.js | 2 +- dist/module-debug/async.js | 9 +- dist/module-debug/bundle.js | 25 +- dist/module-debug/charset.js | 37 +- dist/module-debug/charset/cjk.js | 8 +- dist/module-debug/charset/exact.js | 4 +- dist/module-debug/charset/latin/advanced.js | 23 +- dist/module-debug/charset/latin/balance.js | 33 +- dist/module-debug/charset/latin/extra.js | 6 +- dist/module-debug/charset/latin/soundex.js | 14 +- dist/module-debug/charset/normalize.js | 8 +- dist/module-debug/charset/polyfill.js | 30 +- dist/module-debug/common.js | 6 +- dist/module-debug/compress.js | 7 +- dist/module-debug/db/clickhouse/index.js | 101 +-- dist/module-debug/db/indexeddb/index.js | 162 +--- dist/module-debug/db/interface.js | 27 +- dist/module-debug/db/mongodb/index.js | 66 +- dist/module-debug/db/postgres/index.js | 402 +-------- dist/module-debug/db/redis/index.js | 112 +-- dist/module-debug/db/sqlite/index.js | 124 +-- dist/module-debug/document.js | 97 +-- dist/module-debug/document/add.js | 39 +- dist/module-debug/document/highlight.js | 777 +++++------------ dist/module-debug/document/search.js | 176 ++-- dist/module-debug/encoder.js | 329 +++----- dist/module-debug/index.js | 40 +- dist/module-debug/index/add.js | 70 +- dist/module-debug/index/remove.js | 62 +- dist/module-debug/index/search.js | 148 +--- dist/module-debug/intersect.js | 438 +--------- dist/module-debug/keystore.js | 231 ++--- dist/module-debug/lang/de.js | 16 +- dist/module-debug/lang/en.js | 70 +- dist/module-debug/preset.js | 3 +- dist/module-debug/resolve/and.js | 2 +- dist/module-debug/resolve/default.js | 32 +- dist/module-debug/resolve/handler.js | 13 +- dist/module-debug/resolve/not.js | 4 - dist/module-debug/resolve/or.js | 9 +- dist/module-debug/resolve/xor.js | 8 +- dist/module-debug/resolver.js | 23 +- dist/module-debug/serialize.js | 25 +- dist/module-debug/type.js | 8 +- dist/module-debug/worker.js | 37 +- dist/module-debug/worker/handler.js | 13 +- dist/module-debug/worker/node.js | 11 +- dist/module-min/common.js | 2 +- dist/module-min/db/clickhouse/index.js | 6 +- dist/module-min/document.js | 2 +- dist/module-min/document/add.js | 2 +- dist/module-min/document/search.js | 2 +- dist/module-min/worker.js | 2 +- dist/module/async.js | 9 +- dist/module/bundle.js | 25 +- dist/module/charset.js | 37 +- dist/module/charset/cjk.js | 8 +- dist/module/charset/exact.js | 4 +- dist/module/charset/latin/advanced.js | 23 +- dist/module/charset/latin/balance.js | 33 +- dist/module/charset/latin/extra.js | 6 +- dist/module/charset/latin/soundex.js | 14 +- dist/module/charset/normalize.js | 8 +- dist/module/charset/polyfill.js | 30 +- dist/module/common.js | 6 +- dist/module/compress.js | 7 +- dist/module/db/clickhouse/index.js | 101 +-- dist/module/db/indexeddb/index.js | 162 +--- dist/module/db/interface.js | 27 +- dist/module/db/mongodb/index.js | 66 +- dist/module/db/postgres/index.js | 402 +-------- dist/module/db/redis/index.js | 112 +-- dist/module/db/sqlite/index.js | 124 +-- dist/module/document.js | 97 +-- dist/module/document/add.js | 39 +- dist/module/document/highlight.js | 777 +++++------------ dist/module/document/search.js | 175 ++-- dist/module/encoder.js | 327 +++----- dist/module/index.js | 40 +- dist/module/index/add.js | 70 +- dist/module/index/remove.js | 62 +- dist/module/index/search.js | 148 +--- dist/module/intersect.js | 438 +--------- dist/module/keystore.js | 231 ++--- dist/module/lang/de.js | 16 +- dist/module/lang/en.js | 70 +- dist/module/preset.js | 3 +- dist/module/resolve/and.js | 2 +- dist/module/resolve/default.js | 32 +- dist/module/resolve/handler.js | 13 +- dist/module/resolve/not.js | 4 - dist/module/resolve/or.js | 9 +- dist/module/resolve/xor.js | 8 +- dist/module/resolver.js | 23 +- dist/module/serialize.js | 25 +- dist/module/type.js | 8 +- dist/module/worker.js | 37 +- dist/module/worker/handler.js | 12 +- dist/module/worker/node.js | 11 +- doc/document-search.md | 29 +- package-lock.json | 4 +- package.json | 2 +- src/common.js | 8 +- src/document.js | 22 - src/document/search.js | 108 +-- src/type.js | 5 +- src/worker.js | 20 +- task/babel.js | 16 + test/highlight.js | 60 ++ 128 files changed, 3601 insertions(+), 8090 deletions(-) diff --git a/dist/db/clickhouse/index.cjs b/dist/db/clickhouse/index.cjs index 7a15ee4..8d16360 100644 --- a/dist/db/clickhouse/index.cjs +++ b/dist/db/clickhouse/index.cjs @@ -9,7 +9,6 @@ var clickhouse = require('clickhouse'); * @return {*} */ - function concat(arrays){ return [].concat.apply([], arrays); } diff --git a/dist/db/indexeddb/index.cjs b/dist/db/indexeddb/index.cjs index f1f0e76..a8c8ab1 100644 --- a/dist/db/indexeddb/index.cjs +++ b/dist/db/indexeddb/index.cjs @@ -7,7 +7,6 @@ * @return {*} */ - function create_object(){ return Object.create(null); } diff --git a/dist/db/mongodb/index.cjs b/dist/db/mongodb/index.cjs index c43acfc..3e22c66 100644 --- a/dist/db/mongodb/index.cjs +++ b/dist/db/mongodb/index.cjs @@ -9,7 +9,6 @@ var mongodb = require('mongodb'); * @return {*} */ - /** * @param {Map|Set} val * @param {boolean=} stringify diff --git a/dist/db/postgres/index.cjs b/dist/db/postgres/index.cjs index 3250400..c6c6253 100644 --- a/dist/db/postgres/index.cjs +++ b/dist/db/postgres/index.cjs @@ -9,7 +9,6 @@ var pg_promise = require('pg-promise'); * @return {*} */ - function concat(arrays){ return [].concat.apply([], arrays); } diff --git a/dist/db/redis/index.cjs b/dist/db/redis/index.cjs index f36353f..0ccac85 100644 --- a/dist/db/redis/index.cjs +++ b/dist/db/redis/index.cjs @@ -9,7 +9,6 @@ var redis = require('redis'); * @return {*} */ - /** * @param {Map|Set} val * @param {boolean=} stringify diff --git a/dist/db/sqlite/index.cjs b/dist/db/sqlite/index.cjs index e408ac3..7c45bb5 100644 --- a/dist/db/sqlite/index.cjs +++ b/dist/db/sqlite/index.cjs @@ -10,7 +10,6 @@ var path = require('path'); * @return {*} */ - function concat(arrays){ return [].concat.apply([], arrays); } diff --git a/dist/flexsearch.bundle.debug.js b/dist/flexsearch.bundle.debug.js index 4680df6..79273cb 100644 --- a/dist/flexsearch.bundle.debug.js +++ b/dist/flexsearch.bundle.debug.js @@ -1,5 +1,5 @@ /**! - * FlexSearch.js v0.8.164 (Bundle/Debug) + * FlexSearch.js v0.8.165 (Bundle/Debug) * Author and Copyright: Thomas Wilkerling * Licence: Apache-2.0 * Hosted by Nextapps GmbH @@ -44,23 +44,26 @@ function E(a, b, c) { } return "undefined" === e ? b : a; } -function H() { +function aa(a, b) { + return "undefined" === typeof a ? b : a; +} +function G() { return Object.create(null); } function M(a) { return "string" === typeof a; } -function aa(a) { +function da(a) { return "object" === typeof a; } -function da(a) { +function ea(a) { const b = []; for (const c of a.keys()) { b.push(c); } return b; } -function ea(a, b) { +function fa(a, b) { if (M(b)) { a = a[b]; } else { @@ -70,17 +73,17 @@ function ea(a, b) { } return a; } -function fa(a) { +function ha(a) { let b = 0; for (let c = 0, d; c < a.length; c++) { (d = a[c]) && b < d.length && (b = d.length); } return b; } -;const ha = /[^\p{L}\p{N}]+/u, ia = /(\d{3})/g, ja = /(\D)(\d{3})/g, ka = /(\d{3})(\D)/g, la = /[\u0300-\u036f]/g; -function ma(a = {}) { - if (!this || this.constructor !== ma) { - return new ma(...arguments); +;const ia = /[^\p{L}\p{N}]+/u, ja = /(\d{3})/g, ka = /(\D)(\d{3})/g, la = /(\d{3})(\D)/g, ma = /[\u0300-\u036f]/g; +function na(a = {}) { + if (!this || this.constructor !== na) { + return new na(...arguments); } if (arguments.length) { for (a = 0; a < arguments.length; a++) { @@ -90,7 +93,7 @@ function ma(a = {}) { this.assign(a); } } -w = ma.prototype; +w = na.prototype; w.assign = function(a) { this.normalize = E(a.normalize, !0, this.normalize); let b = a.include, c = b || a.exclude || a.split, d; @@ -118,7 +121,7 @@ w.assign = function(a) { this.numeric = E(a.numeric, d); } else { try { - this.split = E(this.split, ha); + this.split = E(this.split, ia); } catch (e) { console.warn("This platform does not support unicode regex. It falls back to using simple whitespace splitter instead: /s+/."), this.split = /\s+/; } @@ -213,11 +216,11 @@ w.encode = function(a, b) { this.H = setTimeout(N, 50, this); } } - this.normalize && ("function" === typeof this.normalize ? a = this.normalize(a) : a = la ? a.normalize("NFKD").replace(la, "").toLowerCase() : a.toLowerCase()); + this.normalize && ("function" === typeof this.normalize ? a = this.normalize(a) : a = ma ? a.normalize("NFKD").replace(ma, "").toLowerCase() : a.toLowerCase()); this.prepare && (a = this.prepare(a)); - this.numeric && 3 < a.length && (a = a.replace(ja, "$1 $2").replace(ka, "$1 $2").replace(ia, "$1 ")); + this.numeric && 3 < a.length && (a = a.replace(ka, "$1 $2").replace(la, "$1 $2").replace(ja, "$1 ")); const c = !(this.dedupe || this.mapper || this.filter || this.matcher || this.stemmer || this.replacer); - let d = [], e = H(), f, g, h = this.split || "" === this.split ? a.split(this.split) : [a]; + let d = [], e = G(), f, g, h = this.split || "" === this.split ? a.split(this.split) : [a]; for (let l = 0, m, p; l < h.length; l++) { if ((m = p = h[l]) && !(m.length < this.minlength || m.length > this.maxlength)) { if (b) { @@ -296,8 +299,8 @@ function N(a) { a.B.clear(); a.G.clear(); } -;let pa, O; -async function qa(a) { +;let qa, O; +async function ra(a) { a = a.data; var b = a.task; const c = a.id; @@ -305,7 +308,7 @@ async function qa(a) { switch(b) { case "init": O = a.options || {}; - (b = a.factory) ? (Function("return " + b)()(self), pa = new self.FlexSearch.Index(O), delete self.FlexSearch) : pa = new P(O); + (b = a.factory) ? (Function("return " + b)()(self), qa = new self.FlexSearch.Index(O), delete self.FlexSearch) : qa = new P(O); postMessage({id:c}); break; default: @@ -320,33 +323,33 @@ async function qa(a) { if (!O.import || "function" !== typeof O.import) { throw Error('Either no extern configuration provided for the Worker-Index or no method was defined on the config property "import".'); } - d[0] && (a = await O.import.call(pa, d[0]), pa.import(d[0], a)); + d[0] && (a = await O.import.call(qa, d[0]), qa.import(d[0], a)); } else { - (e = d && pa[b].apply(pa, d)) && e.then && (e = await e); + (e = d && qa[b].apply(qa, d)) && e.then && (e = await e); } postMessage("search" === b ? {id:c, msg:e} : {id:c}); } } -;function ra(a) { - sa.call(a, "add"); - sa.call(a, "append"); - sa.call(a, "search"); - sa.call(a, "update"); - sa.call(a, "remove"); - sa.call(a, "searchCache"); +;function sa(a) { + ta.call(a, "add"); + ta.call(a, "append"); + ta.call(a, "search"); + ta.call(a, "update"); + ta.call(a, "remove"); + ta.call(a, "searchCache"); } -let ta, ua, va; -function ya() { - ta = va = 0; +let ua, va, ya; +function za() { + ua = ya = 0; } -function sa(a) { +function ta(a) { this[a + "Async"] = function() { const b = arguments; var c = b[b.length - 1]; let d; "function" === typeof c && (d = c, delete b[b.length - 1]); - ta ? va || (va = Date.now() - ua >= this.priority * this.priority * 3) : (ta = setTimeout(ya, 0), ua = Date.now()); - if (va) { + ua ? ya || (ya = Date.now() - va >= this.priority * this.priority * 3) : (ua = setTimeout(za, 0), va = Date.now()); + if (ya) { const f = this; return new Promise(g => { setTimeout(function() { @@ -360,8 +363,8 @@ function sa(a) { return c; }; } -;let za = 0; -function Aa(a = {}, b) { +;let Aa = 0; +function Ba(a = {}, b) { function c(h) { function k(l) { l = l.data || l; @@ -369,30 +372,30 @@ function Aa(a = {}, b) { p && (p(l.msg), delete f.h[m]); } this.worker = h; - this.h = H(); + this.h = G(); if (this.worker) { e ? this.worker.on("message", k) : this.worker.onmessage = k; if (a.config) { return new Promise(function(l) { - f.h[++za] = function() { + f.h[++Aa] = function() { l(f); - 1e9 < za && (za = 0); + 1e9 < Aa && (Aa = 0); }; - f.worker.postMessage({id:za, task:"init", factory:d, options:a}); + f.worker.postMessage({id:Aa, task:"init", factory:d, options:a}); }); } - this.worker.postMessage({task:"init", factory:d, options:a}); this.priority = a.priority || 4; - b && (this.encoder = b); + this.encoder = b || null; + this.worker.postMessage({task:"init", factory:d, options:a}); return this; } } - if (!this || this.constructor !== Aa) { - return new Aa(a); + if (!this || this.constructor !== Ba) { + return new Ba(a); } let d = "undefined" !== typeof self ? self._factory : "undefined" !== typeof window ? window._factory : null; d && (d = d.toString()); - const e = "undefined" === typeof window, f = this, g = Ba(d, e, a.worker); + const e = "undefined" === typeof window, f = this, g = Ca(d, e, a.worker); return g.then ? g.then(function(h) { return c.call(f, h); }) : c.call(this, g); @@ -400,31 +403,32 @@ function Aa(a = {}, b) { R("add"); R("append"); R("search"); +R("searchCache"); R("update"); R("remove"); R("clear"); R("export"); R("import"); -ra(Aa.prototype); +sa(Ba.prototype); function R(a) { - Aa.prototype[a] = function() { + Ba.prototype[a] = function() { const b = this, c = [].slice.call(arguments); var d = c[c.length - 1]; let e; "function" === typeof d && (e = d, c.pop()); d = new Promise(function(f) { "export" === a && "function" === typeof c[0] && (c[0] = null); - b.h[++za] = f; - b.worker.postMessage({task:a, id:za, args:c}); + b.h[++Aa] = f; + b.worker.postMessage({task:a, id:Aa, args:c}); }); return e ? (d.then(e), this) : d; }; } -function Ba(a, b, c) { - return b ? "undefined" !== typeof module ? new(require("worker_threads")["Worker"])(__dirname+"/node/node.js") : import("worker_threads").then(function(worker){return new worker["Worker"]((1,eval)("import.meta.dirname")+"/node/node.mjs")}) : a ? new window.Worker(URL.createObjectURL(new Blob(["onmessage=" + qa.toString()], {type:"text/javascript"}))) : new window.Worker("string" === typeof c ? c : (0,eval)("import.meta.url").replace("/worker.js", "/worker/worker.js").replace("flexsearch.bundle.module.min.js", +function Ca(a, b, c) { + return b ? "undefined" !== typeof module ? new(require("worker_threads")["Worker"])(__dirname+"/node/node.js") : import("worker_threads").then(function(worker){return new worker["Worker"]((1,eval)("import.meta.dirname")+"/node/node.mjs")}) : a ? new window.Worker(URL.createObjectURL(new Blob(["onmessage=" + ra.toString()], {type:"text/javascript"}))) : new window.Worker("string" === typeof c ? c : (0,eval)("import.meta.url").replace("/worker.js", "/worker/worker.js").replace("flexsearch.bundle.module.min.js", "module/worker/worker.js"), {type:"module"}); } -;function Ca(a, b = 0) { +;function Da(a, b = 0) { let c = [], d = []; b && (b = 250000 / b * 5000 | 0); for (const e of a.entries()) { @@ -433,30 +437,30 @@ function Ba(a, b, c) { d.length && c.push(d); return c; } -function Da(a, b) { +function Ea(a, b) { b || (b = new Map()); for (let c = 0, d; c < a.length; c++) { d = a[c], b.set(d[0], d[1]); } return b; } -function Ea(a, b = 0) { +function Fa(a, b = 0) { let c = [], d = []; b && (b = 250000 / b * 1000 | 0); for (const e of a.entries()) { - d.push([e[0], Ca(e[1])[0]]), d.length === b && (c.push(d), d = []); + d.push([e[0], Da(e[1])[0]]), d.length === b && (c.push(d), d = []); } d.length && c.push(d); return c; } -function Fa(a, b) { +function Ga(a, b) { b || (b = new Map()); for (let c = 0, d, e; c < a.length; c++) { - d = a[c], e = b.get(d[0]), b.set(d[0], Da(d[1], e)); + d = a[c], e = b.get(d[0]), b.set(d[0], Ea(d[1], e)); } return b; } -function Ga(a) { +function Ha(a) { let b = [], c = []; for (const d of a.keys()) { c.push(d), 250000 === c.length && (b.push(c), c = []); @@ -464,14 +468,14 @@ function Ga(a) { c.length && b.push(c); return b; } -function Ha(a, b) { +function Ia(a, b) { b || (b = new Set()); for (let c = 0; c < a.length; c++) { b.add(a[c]); } return b; } -function Ia(a, b, c, d, e, f, g = 0) { +function Ja(a, b, c, d, e, f, g = 0) { const h = d && d.constructor === Array; var k = h ? d.shift() : d; if (!k) { @@ -480,12 +484,12 @@ function Ia(a, b, c, d, e, f, g = 0) { if ((k = a((b ? b + "." : "") + (g + 1) + "." + c, JSON.stringify(k))) && k.then) { const l = this; return k.then(function() { - return Ia.call(l, a, b, c, h ? d : null, e, f, g + 1); + return Ja.call(l, a, b, c, h ? d : null, e, f, g + 1); }); } - return Ia.call(this, a, b, c, h ? d : null, e, f, g + 1); + return Ja.call(this, a, b, c, h ? d : null, e, f, g + 1); } -function Ja(a, b) { +function Ka(a, b) { let c = ""; for (const d of a.entries()) { a = d[0]; @@ -505,7 +509,7 @@ function Ja(a, b) { } return c; } -;function Ka(a, b, c, d) { +;function La(a, b, c, d) { let e = []; for (let f = 0, g; f < a.index.length; f++) { if (g = a.index[f], b >= g.length) { @@ -571,12 +575,12 @@ function U(a) { } if ("slice" === d) { return function(e, f) { - return Ka(b, e || 0, f || b.length, !1); + return La(b, e || 0, f || b.length, !1); }; } if ("splice" === d) { return function(e, f) { - return Ka(b, e || 0, f || b.length, !0); + return La(b, e || 0, f || b.length, !0); }; } if ("constructor" === d) { @@ -604,10 +608,10 @@ function V(a = 8) { if (!this || this.constructor !== V) { return new V(a); } - this.index = H(); + this.index = G(); this.h = []; this.size = 0; - 32 < a ? (this.B = La, this.A = BigInt(a)) : (this.B = Oa, this.A = a); + 32 < a ? (this.B = Oa, this.A = BigInt(a)) : (this.B = Pa, this.A = a); } V.prototype.get = function(a) { const b = this.index[this.B(a)]; @@ -622,10 +626,10 @@ function W(a = 8) { if (!this || this.constructor !== W) { return new W(a); } - this.index = H(); + this.index = G(); this.h = []; this.size = 0; - 32 < a ? (this.B = La, this.A = BigInt(a)) : (this.B = Oa, this.A = a); + 32 < a ? (this.B = Oa, this.A = BigInt(a)) : (this.B = Pa, this.A = a); } W.prototype.add = function(a) { var b = this.B(a); @@ -642,7 +646,7 @@ w.delete = W.prototype.delete = function(a) { b && b.delete(a) && this.size--; }; w.clear = W.prototype.clear = function() { - this.index = H(); + this.index = G(); this.h = []; this.size = 0; }; @@ -667,7 +671,7 @@ w.entries = W.prototype.entries = function*() { } } }; -function Oa(a) { +function Pa(a) { let b = 2 ** this.A - 1; if ("number" == typeof a) { return a & b; @@ -678,7 +682,7 @@ function Oa(a) { } return 32 === this.A ? c + 2 ** 31 : c; } -function La(a) { +function Oa(a) { let b = BigInt(2) ** this.A - BigInt(1); var c = typeof a; if ("bigint" === c) { @@ -694,8 +698,8 @@ function La(a) { } return c; } -;Pa.prototype.add = function(a, b, c) { - aa(a) && (b = a, a = ea(b, this.key)); +;Qa.prototype.add = function(a, b, c) { + da(a) && (b = a, a = fa(b, this.key)); if (b && (a || 0 === a)) { if (!c && this.reg.has(a)) { return this.update(a, b); @@ -708,7 +712,7 @@ function La(a) { e && d.add(a, e, !1, !0); } else { if (e = k.I, !e || e(b)) { - k.constructor === String ? k = ["" + k] : M(k) && (k = [k]), Qa(b, k, this.J, 0, d, a, k[0], c); + k.constructor === String ? k = ["" + k] : M(k) && (k = [k]), Ra(b, k, this.J, 0, d, a, k[0], c); } } } @@ -716,7 +720,7 @@ function La(a) { for (d = 0; d < this.D.length; d++) { var f = this.D[d], g = this.R[d]; e = this.tag.get(g); - let h = H(); + let h = G(); if ("function" === typeof f) { if (f = f(b), !f) { continue; @@ -727,7 +731,7 @@ function La(a) { continue; } f.constructor === String && (f = "" + f); - f = ea(b, f); + f = fa(b, f); } if (e && f) { M(f) && (f = [f]); @@ -754,7 +758,7 @@ function La(a) { if (this.store && (!c || !this.store.has(a))) { let h; if (this.C) { - h = H(); + h = G(); for (let k = 0, l; k < this.C.length; k++) { l = this.C[k]; if ((c = l.I) && !c(b)) { @@ -771,7 +775,7 @@ function La(a) { h[l] = b[l]; continue; } - Ra(b, h, l, 0, l[0], m); + Sa(b, h, l, 0, l[0], m); } } this.store.set(a, h || b); @@ -780,21 +784,21 @@ function La(a) { } return this; }; -function Ra(a, b, c, d, e, f) { +function Sa(a, b, c, d, e, f) { a = a[e]; if (d === c.length - 1) { b[e] = f || a; } else if (a) { if (a.constructor === Array) { for (b = b[e] = Array(a.length), e = 0; e < a.length; e++) { - Ra(a, b, c, d, e); + Sa(a, b, c, d, e); } } else { - b = b[e] || (b[e] = H()), e = c[++d], Ra(a, b, c, d, e); + b = b[e] || (b[e] = G()), e = c[++d], Sa(a, b, c, d, e); } } } -function Qa(a, b, c, d, e, f, g, h) { +function Ra(a, b, c, d, e, f, g, h) { if (a = a[g]) { if (d === b.length - 1) { if (a.constructor === Array) { @@ -810,17 +814,17 @@ function Qa(a, b, c, d, e, f, g, h) { } else { if (a.constructor === Array) { for (g = 0; g < a.length; g++) { - Qa(a, b, c, d, e, f, g, h); + Ra(a, b, c, d, e, f, g, h); } } else { - g = b[++d], Qa(a, b, c, d, e, f, g, h); + g = b[++d], Ra(a, b, c, d, e, f, g, h); } } } else { e.db && e.remove(f); } } -;function Sa(a, b, c, d) { +;function Ta(a, b, c, d) { if (!a.length) { return a; } @@ -851,7 +855,7 @@ function Qa(a, b, c, d, e, f, g, h) { e = 1 < e.length ? [].concat.apply([], e) : e[0]; return d ? X.call(this, e) : e; } -;function Ta(a, b, c) { +;function Ua(a, b, c) { var d = c[0]; if (d.then) { return Promise.all(c).then(function(q) { @@ -920,10 +924,10 @@ function Qa(a, b, c, d, e, f, g, h) { return {O:d, P:e, limit:f, offset:g, enrich:h, resolve:k, suggest:l, highlight:m, W:p}; } ;Y.prototype.or = function() { - const {O:a, P:b, limit:c, offset:d, enrich:e, resolve:f} = Ta(this, "or", arguments); - return Ua.call(this, a, b, c, d, e, f); + const {O:a, P:b, limit:c, offset:d, enrich:e, resolve:f} = Ua(this, "or", arguments); + return Va.call(this, a, b, c, d, e, f); }; -function Ua(a, b, c, d, e, f) { +function Va(a, b, c, d, e, f) { if (b.length) { const g = this; return Promise.all(b).then(function(h) { @@ -931,10 +935,10 @@ function Ua(a, b, c, d, e, f) { for (let k = 0, l; k < h.length; k++) { (l = h[k]).length && (a[k] = l); } - return Ua.call(g, a, [], c, d, e, f); + return Va.call(g, a, [], c, d, e, f); }); } - a.length && (this.result.length && a.push(this.result), 2 > a.length ? this.result = a[0] : (this.result = Va(a, c, d, !1, this.h), d = 0)); + a.length && (this.result.length && a.push(this.result), 2 > a.length ? this.result = a[0] : (this.result = Wa(a, c, d, !1, this.h), d = 0)); return f ? this.resolve(c, d, e) : this; } ;Y.prototype.and = function() { @@ -944,12 +948,12 @@ function Ua(a, b, c, d, e, f) { f && (a = !!f.suggest, e = f.resolve, b = f.limit, c = f.offset, d = f.enrich && e); } if (a) { - const {O:f, P:g, limit:h, offset:k, enrich:l, resolve:m, suggest:p} = Ta(this, "and", arguments); - return Wa.call(this, f, g, h, k, l, m, p); + const {O:f, P:g, limit:h, offset:k, enrich:l, resolve:m, suggest:p} = Ua(this, "and", arguments); + return Xa.call(this, f, g, h, k, l, m, p); } return e ? this.resolve(b, c, d) : this; }; -function Wa(a, b, c, d, e, f, g) { +function Xa(a, b, c, d, e, f, g) { if (b.length) { const h = this; return Promise.all(b).then(function(k) { @@ -957,15 +961,15 @@ function Wa(a, b, c, d, e, f, g) { for (let l = 0, m; l < k.length; l++) { (m = k[l]).length && (a[l] = m); } - return Wa.call(h, a, [], c, d, e, f, g); + return Xa.call(h, a, [], c, d, e, f, g); }); } if (a.length) { if (this.result.length && a.unshift(this.result), 2 > a.length) { this.result = a[0]; } else { - if (b = fa(a)) { - return this.result = Xa(a, b, c, d, g, this.h, f), f ? e ? X.call(this.index, this.result) : this.result : this; + if (b = ha(a)) { + return this.result = Ya(a, b, c, d, g, this.h, f), f ? e ? X.call(this.index, this.result) : this.result : this; } this.result = []; } @@ -975,10 +979,10 @@ function Wa(a, b, c, d, e, f, g) { return f ? this.resolve(c, d, e) : this; } ;Y.prototype.xor = function() { - const {O:a, P:b, limit:c, offset:d, enrich:e, resolve:f, suggest:g} = Ta(this, "xor", arguments); - return Ya.call(this, a, b, c, d, e, f, g); + const {O:a, P:b, limit:c, offset:d, enrich:e, resolve:f, suggest:g} = Ua(this, "xor", arguments); + return Za.call(this, a, b, c, d, e, f, g); }; -function Ya(a, b, c, d, e, f, g) { +function Za(a, b, c, d, e, f, g) { if (b.length) { const h = this; return Promise.all(b).then(function(k) { @@ -986,22 +990,22 @@ function Ya(a, b, c, d, e, f, g) { for (let l = 0, m; l < k.length; l++) { (m = k[l]).length && (a[l] = m); } - return Ya.call(h, a, [], c, d, e, f, g); + return Za.call(h, a, [], c, d, e, f, g); }); } if (a.length) { if (this.result.length && a.unshift(this.result), 2 > a.length) { this.result = a[0]; } else { - return this.result = Za.call(this, a, c, d, f, this.h), f ? e ? X.call(this.index, this.result) : this.result : this; + return this.result = $a.call(this, a, c, d, f, this.h), f ? e ? X.call(this.index, this.result) : this.result : this; } } else { g || (this.result = a); } return f ? this.resolve(c, d, e) : this; } -function Za(a, b, c, d, e) { - const f = [], g = H(); +function $a(a, b, c, d, e) { + const f = [], g = G(); let h = 0; for (let k = 0, l; k < a.length; k++) { if (l = a[k]) { @@ -1046,10 +1050,10 @@ function Za(a, b, c, d, e) { return f; } ;Y.prototype.not = function() { - const {O:a, P:b, limit:c, offset:d, enrich:e, resolve:f, suggest:g} = Ta(this, "not", arguments); - return $a.call(this, a, b, c, d, e, f, g); + const {O:a, P:b, limit:c, offset:d, enrich:e, resolve:f, suggest:g} = Ua(this, "not", arguments); + return ab.call(this, a, b, c, d, e, f, g); }; -function $a(a, b, c, d, e, f, g) { +function ab(a, b, c, d, e, f, g) { if (b.length) { const h = this; return Promise.all(b).then(function(k) { @@ -1057,17 +1061,17 @@ function $a(a, b, c, d, e, f, g) { for (let l = 0, m; l < k.length; l++) { (m = k[l]).length && (a[l] = m); } - return $a.call(h, a, [], c, d, e, f, g); + return ab.call(h, a, [], c, d, e, f, g); }); } if (a.length && this.result.length) { - this.result = ab.call(this, a, c, d, f); + this.result = bb.call(this, a, c, d, f); } else if (f) { return this.resolve(c, d, e); } return f ? e ? X.call(this.index, this.result) : this.result : this; } -function ab(a, b, c, d) { +function bb(a, b, c, d) { const e = []; a = new Set(a.flat().flat()); for (let f = 0, g, h = 0; f < this.result.length; f++) { @@ -1093,7 +1097,7 @@ function ab(a, b, c, d) { } return e; } -;function bb(a, b, c, d, e) { +;function cb(a, b, c, d, e) { let f, g, h; "string" === typeof e ? (f = e, e = "") : f = e.template; if (!f) { @@ -1119,28 +1123,28 @@ function ab(a, b, c, d) { let q, r; "object" === typeof k && (q = k.before, 0 === q && (q = -1), r = k.after, 0 === r && (r = -1), k = k.total || 9e5); p = new Map(); - for (let Ma = 0, ba, ib, na; Ma < b.length; Ma++) { - let oa; + for (let Ma = 0, ba, ib, oa; Ma < b.length; Ma++) { + let pa; if (d) { - oa = b, na = d; + pa = b, oa = d; } else { var n = b[Ma]; - na = n.field; - if (!na) { + oa = n.field; + if (!oa) { continue; } - oa = n.result; + pa = n.result; } - ib = c.get(na); + ib = c.get(oa); ba = ib.encoder; n = p.get(ba); "string" !== typeof n && (n = ba.encode(a), p.set(ba, n)); - for (let wa = 0; wa < oa.length; wa++) { - var t = oa[wa].doc; + for (let wa = 0; wa < pa.length; wa++) { + var t = pa[wa].doc; if (!t) { continue; } - t = ea(t, na); + t = fa(t, oa); if (!t) { continue; } @@ -1151,7 +1155,7 @@ function ab(a, b, c, d) { t = ""; var y = []; let xa = []; - var D = -1, G = -1, B = 0; + var D = -1, H = -1, B = 0; for (var v = 0; v < x.length; v++) { var A = x[v], I = ba.encode(A); I = 1 < I.length ? I.join(" ") : I[0]; @@ -1166,7 +1170,7 @@ function ab(a, b, c, d) { S && L <= S || (Q = I.indexOf(Q), -1 < Q && (F = (Q ? A.substring(0, Q) : "") + g + A.substring(Q, Q + L) + h + (Q + L < C ? A.substring(Q + L) : ""), S = L, z = !0)); } } - F && (k && (0 > D && (D = t.length + (t ? 1 : 0)), G = t.length + (t ? 1 : 0) + F.length, B += C, xa.push(y.length), y.push({match:F})), t += (t ? " " : "") + F); + F && (k && (0 > D && (D = t.length + (t ? 1 : 0)), H = t.length + (t ? 1 : 0) + F.length, B += C, xa.push(y.length), y.push({match:F})), t += (t ? " " : "") + F); } if (!z) { A = x[v], t += (t ? " " : "") + A, k && y.push({text:A}); @@ -1176,10 +1180,10 @@ function ab(a, b, c, d) { } B = xa.length * (f.length - 2); if (q || r || k && t.length - B > k) { - if (B = k + B - 2 * u, v = G - D, 0 < q && (v += q), 0 < r && (v += r), v <= B) { - x = q ? D - (0 < q ? q : 0) : D - ((B - v) / 2 | 0), y = r ? G + (0 < r ? r : 0) : x + B, l || (0 < x && " " !== t.charAt(x) && " " !== t.charAt(x - 1) && (x = t.indexOf(" ", x), 0 > x && (x = 0)), y < t.length && " " !== t.charAt(y - 1) && " " !== t.charAt(y) && (y = t.lastIndexOf(" ", y), y < G ? y = G : ++y)), t = (x ? e : "") + t.substring(x, y) + (y < t.length ? e : ""); + if (B = k + B - 2 * u, v = H - D, 0 < q && (v += q), 0 < r && (v += r), v <= B) { + x = q ? D - (0 < q ? q : 0) : D - ((B - v) / 2 | 0), y = r ? H + (0 < r ? r : 0) : x + B, l || (0 < x && " " !== t.charAt(x) && " " !== t.charAt(x - 1) && (x = t.indexOf(" ", x), 0 > x && (x = 0)), y < t.length && " " !== t.charAt(y - 1) && " " !== t.charAt(y) && (y = t.lastIndexOf(" ", y), y < H ? y = H : ++y)), t = (x ? e : "") + t.substring(x, y) + (y < t.length ? e : ""); } else { - G = []; + H = []; D = {}; B = {}; v = {}; @@ -1228,9 +1232,9 @@ function ab(a, b, c, d) { } } if (C + t.length + 1 <= k) { - t = " " + t, G[z] += t; + t = " " + t, H[z] += t; } else if (l) { - T = k - C - 1, 0 < T && (t = " " + t.substring(0, T), G[z] += t), v[z + 1] = 1; + T = k - C - 1, 0 < T && (t = " " + t.substring(0, T), H[z] += t), v[z + 1] = 1; } else { v[z + 1] = 1; continue; @@ -1272,9 +1276,9 @@ function ab(a, b, c, d) { } } if (C + t.length + 1 <= k) { - t += " ", G[z] = t + G[z]; + t += " ", H[z] = t + H[z]; } else if (l) { - T = t.length + 1 - (k - C), 0 <= T && T < t.length && (t = t.substring(T) + " ", G[z] = t + G[z]), v[z] = 1; + T = t.length + 1 - (k - C), 0 <= T && T < t.length && (t = t.substring(T) + " ", H[z] = t + H[z]), v[z] = 1; } else { v[z] = 1; continue; @@ -1290,7 +1294,7 @@ function ab(a, b, c, d) { K >= x.length - 1 ? Na = 1 : K < y.length - 1 && y[K + 1].match ? Na = 1 : u && (C += u); C -= f.length - 2; if (!z || C + t.length <= k) { - G[z] = t; + H[z] = t; } else { T = S = ca = B[z] = 0; break; @@ -1311,14 +1315,14 @@ function ab(a, b, c, d) { } } t = ""; - for (let z = 0, K; z < G.length; z++) { - K = (z && B[z] ? " " : (z && !e ? " " : "") + e) + G[z], t += K; + for (let z = 0, K; z < H.length; z++) { + K = (z && B[z] ? " " : (z && !e ? " " : "") + e) + H[z], t += K; } - e && !B[G.length] && (t += e); + e && !B[H.length] && (t += e); } } m && (t = t.replace(m, " ")); - oa[wa].highlight = t; + pa[wa].highlight = t; } if (d) { break; @@ -1376,13 +1380,13 @@ Y.prototype.resolve = function(a, b, c) { const d = this.index; let e = this.result; this.result = this.index = null; - e.length && ("object" === typeof a && (c = a.enrich, b = a.offset, a = a.limit), e = Sa.call(d, e, a || 100, b, c)); + e.length && ("object" === typeof a && (c = a.enrich, b = a.offset, a = a.limit), e = Ta.call(d, e, a || 100, b, c)); return e; }; -function Xa(a, b, c, d, e, f, g) { +function Ya(a, b, c, d, e, f, g) { const h = a.length; let k = [], l, m; - l = H(); + l = G(); for (let p = 0, u, q, r, n; p < b; p++) { for (let t = 0; t < h; t++) { if (r = a[t], p < r.length && (u = r[p])) { @@ -1404,7 +1408,7 @@ function Xa(a, b, c, d, e, f, g) { } if (a = k.length) { if (e) { - k = 1 < k.length ? Va(k, c, d, g, f) : (k = k[0]).length > c || d ? k.slice(d, c + d) : k; + k = 1 < k.length ? Wa(k, c, d, g, f) : (k = k[0]).length > c || d ? k.slice(d, c + d) : k; } else { if (a < h) { return []; @@ -1439,8 +1443,8 @@ function Xa(a, b, c, d, e, f, g) { } return k; } -function Va(a, b, c, d, e) { - const f = [], g = H(); +function Wa(a, b, c, d, e) { + const f = [], g = G(); let h; var k = a.length; let l; @@ -1484,8 +1488,8 @@ function Va(a, b, c, d, e) { } return f; } -function cb(a, b, c) { - const d = H(), e = []; +function db(a, b, c) { + const d = G(), e = []; for (let f = 0, g; f < b.length; f++) { g = b[f]; for (let h = 0; h < g.length; h++) { @@ -1505,9 +1509,9 @@ function cb(a, b, c) { } return e; } -;H(); -Pa.prototype.search = function(a, b, c, d) { - c || (!b && aa(a) ? (c = a, a = "") : aa(b) && (c = b, b = 0)); +;G(); +Qa.prototype.search = function(a, b, c, d) { + c || (!b && da(a) ? (c = a, a = "") : da(b) && (c = b, b = 0)); if (c && c.cache) { c.cache = !1; var e = this.searchCache(a, b, c); @@ -1580,7 +1584,7 @@ Pa.prototype.search = function(a, b, c, d) { } g.push(d = d.db.tag(x[n + 1], b, t, e)); } else { - d = db.call(this, x[n], x[n + 1], b, t, e); + d = eb.call(this, x[n], x[n + 1], b, t, e); } f.push(q ? {field:x[n], tag:x[n + 1], result:d} : [d]); } @@ -1591,10 +1595,10 @@ Pa.prototype.search = function(a, b, c, d) { for (let A = 0; A < v.length; A++) { q ? f[A].result = v[A] : f[A] = v[A]; } - return q ? f : new Y(1 < f.length ? Xa(f, 1, 0, 0, l, m) : f[0], B); + return q ? f : new Y(1 < f.length ? Ya(f, 1, 0, 0, l, m) : f[0], B); }); } - return q ? f : new Y(1 < f.length ? Xa(f, 1, 0, 0, l, m) : f[0], this); + return q ? f : new Y(1 < f.length ? Ya(f, 1, 0, 0, l, m) : f[0], this); } } if (!q && !h) { @@ -1608,7 +1612,7 @@ Pa.prototype.search = function(a, b, c, d) { p && p.constructor !== Array && (p = [p]); } p || (p = this.field); - let G; + let H; x = (this.worker || this.db) && !d && []; for (let B = 0, v, A, I; B < p.length; B++) { A = p[B]; @@ -1616,11 +1620,11 @@ Pa.prototype.search = function(a, b, c, d) { continue; } let C; - M(A) || (C = A, A = C.field, a = C.query || a, b = eb(C.limit, b), t = eb(C.offset, t), l = eb(C.suggest, l), r = q && this.store && eb(C.highlight, r), e = !!r || q && this.store && eb(C.enrich, e)); + M(A) || (C = A, A = C.field, a = C.query || a, b = aa(C.limit, b), t = aa(C.offset, t), l = aa(C.suggest, l), r = q && this.store && aa(C.highlight, r), e = !!r || q && this.store && aa(C.enrich, e)); if (d) { v = d[B]; } else { - if (y = C || c, D = this.index.get(A), n && (this.db && (y.tag = n, G = D.db.support_tag_search, y.field = p), G || (y.enrich = !1)), x) { + if (y = C || c, D = this.index.get(A), n && (this.db && (y.tag = n, H = D.db.support_tag_search, y.field = p), H || (y.enrich = !1)), x) { x[B] = D.search(a, b, y); y && e && (y.enrich = e); continue; @@ -1633,7 +1637,7 @@ Pa.prototype.search = function(a, b, c, d) { y = []; D = 0; if (this.db && d) { - if (!G) { + if (!H) { for (let J = p.length; J < d.length; J++) { let F = d[J]; if (F && F.length) { @@ -1661,7 +1665,7 @@ Pa.prototype.search = function(a, b, c, d) { } } if (D) { - v = cb(v, y, q); + v = db(v, y, q); I = v.length; if (!I && !l) { return q ? v : new Y(v, this); @@ -1676,7 +1680,7 @@ Pa.prototype.search = function(a, b, c, d) { } } if (x) { - if (this.db && n && n.length && !G) { + if (this.db && n && n.length && !H) { for (e = 0; e < n.length; e += 2) { g = this.index.get(n[e]); if (!g) { @@ -1705,7 +1709,7 @@ Pa.prototype.search = function(a, b, c, d) { n = f[t]; e && n.length && "undefined" === typeof n[0].doc && (this.db ? x.push(n = this.index.get(this.field[0]).db.enrich(n)) : n = X.call(this, n)); if (h) { - return q ? r ? bb(a, n, this.index, h, r) : n : new Y(n, this); + return q ? r ? cb(a, n, this.index, h, r) : n : new Y(n, this); } f[t] = {field:g[t], result:n}; } @@ -1715,37 +1719,44 @@ Pa.prototype.search = function(a, b, c, d) { for (let A = 0; A < v.length; A++) { f[A].result = v[A]; } - return k ? fb(f) : r ? bb(a, f, B.index, h, r) : f; + r && (f = cb(a, f, B.index, h, r)); + return k ? fb(f) : f; }); } - return k ? fb(f) : r ? bb(a, f, this.index, h, r) : f; + r && (f = cb(a, f, this.index, h, r)); + return k ? fb(f) : f; }; -function eb(a, b) { - return "undefined" === typeof a ? b : a; -} function fb(a) { - const b = [], c = H(); - for (let d = 0, e, f; d < a.length; d++) { - e = a[d]; - f = e.result; - for (let g = 0, h, k, l; g < f.length; g++) { - k = f[g], "object" !== typeof k && (k = {id:k}), h = k.id, (l = c[h]) ? l.push(e.field) : (k.field = c[h] = [e.field], b.push(k)); + const b = [], c = G(), d = G(); + for (let e = 0, f, g, h, k, l, m, p; e < a.length; e++) { + f = a[e]; + g = f.field; + h = f.result; + for (let u = 0; u < h.length; u++) { + if (l = h[u], "object" !== typeof l ? l = {id:k = l} : k = l.id, (m = c[k]) ? m.push(g) : (l.field = c[k] = [g], b.push(l)), p = l.highlight) { + m = d[k], m || (d[k] = m = {}, l.highlight = m), m[g] = p; + } } } return b; } -function db(a, b, c, d, e) { - let f = this.tag.get(a); - if (!f) { - return console.warn("Tag-Field '" + a + "' was not found"), []; +function eb(a, b, c, d, e) { + a = this.tag.get(a); + if (!a) { + return []; } - if ((a = (f = f && f.get(b)) && f.length - d) && 0 < a) { - if (c && a > c || d) { - f = f.slice(d, d + c); + a = a.get(b); + if (!a) { + return []; + } + b = a.length - d; + if (0 < b) { + if (c && b > c || d) { + a = a.slice(d, d + c); } - e && (f = X.call(this, f)); - return f; + e && (a = X.call(this, a)); } + return a; } function X(a) { if (!this || !this.store) { @@ -1771,9 +1782,9 @@ var nb = {Exact:gb, Default:hb, Normalize:hb, LatinBalance:{mapper:jb}, LatinAdv a[c] = d; } }}, CJK:{split:""}, LatinExact:gb, LatinDefault:hb, LatinSimple:hb}; -function Pa(a) { - if (!this || this.constructor !== Pa) { - return new Pa(a); +function Qa(a) { + if (!this || this.constructor !== Qa) { + return new Qa(a); } const b = a.document || a.doc || a; let c, d; @@ -1831,7 +1842,7 @@ function Pa(a) { a.db && (this.fastupdate = !1, this.mount(a.db)); } } -w = Pa.prototype; +w = Qa.prototype; w.mount = function(a) { if (this.worker) { throw Error("You can't use Worker-Indexes on a persistent model. That would be useless, since each of the persistent model acts like Worker-Index by default (Master/Slave)."); @@ -1885,11 +1896,11 @@ function qb(a, b) { for (let f = 0, g, h; f < d.length; f++) { g = d[f]; M(g) || (h = g, g = g.field); - h = aa(h) ? Object.assign({}, a, h) : a; + h = da(h) ? Object.assign({}, a, h) : a; if (this.worker) { var e = void 0; - e = (e = h.encoder) && e.encode ? e : new ma("string" === typeof e ? nb[e] : e); - e = new Aa(h, e); + e = (e = h.encoder) && e.encode ? e : new na("string" === typeof e ? nb[e] : e); + e = new Ba(h, e); c.set(g, e); } this.worker || c.set(g, new P(h, this.reg)); @@ -1921,7 +1932,7 @@ w.update = function(a, b) { return this.remove(a).add(a, b); }; w.remove = function(a) { - aa(a) && (a = ea(a, this.key)); + da(a) && (a = fa(a, this.key)); for (var b of this.index.values()) { b.remove(a, !0); } @@ -1971,7 +1982,7 @@ w.get = function(a) { }) : this.store.get(a) || null; }; w.set = function(a, b) { - "object" === typeof a && (b = a, a = ea(b, this.key)); + "object" === typeof a && (b = a, a = fa(b, this.key)); this.store.set(a, b); return this; }; @@ -1991,23 +2002,23 @@ w.export = function(a, b, c = 0, d = 0) { switch(d) { case 0: e = "reg"; - f = Ga(this.reg); + f = Ha(this.reg); b = null; break; case 1: e = "tag"; - f = this.tag && Ea(this.tag, this.reg.size); + f = this.tag && Fa(this.tag, this.reg.size); b = null; break; case 2: e = "doc"; - f = this.store && Ca(this.store); + f = this.store && Da(this.store); b = null; break; default: return; } - return Ia.call(this, a, b, e, f, c, d); + return Ja.call(this, a, b, e, f, c, d); }; w.import = function(a, b) { var c = a.split("."); @@ -2025,7 +2036,7 @@ w.import = function(a, b) { switch(c) { case "reg": this.fastupdate = !1; - this.reg = Ha(b, this.reg); + this.reg = Ia(b, this.reg); for (let e = 0, f; e < this.field.length; e++) { f = this.index.get(this.field[e]), f.fastupdate = !1, f.reg = this.reg; } @@ -2038,14 +2049,14 @@ w.import = function(a, b) { } break; case "tag": - this.tag = Fa(b, this.tag); + this.tag = Ga(b, this.tag); break; case "doc": - this.store = Da(b, this.store); + this.store = Ea(b, this.store); } } }; -ra(Pa.prototype); +sa(Qa.prototype); function rb(a, b, c) { const d = (b ? "" + a : "object" === typeof a ? "" + a.query : a).toLowerCase(); this.cache || (this.cache = new pb()); @@ -2147,7 +2158,7 @@ P.prototype.add = function(a, b, c, d) { b = this.encoder.encode(b, !d); const l = b.length; if (l) { - const m = H(), p = H(), u = this.resolution; + const m = G(), p = G(), u = this.resolution; for (let q = 0; q < l; q++) { let r = b[this.rtl ? l - 1 - q : q]; var e = r.length; @@ -2185,7 +2196,7 @@ P.prototype.add = function(a, b, c, d) { } default: if (wb(this, p, r, f, a, c), d && 1 < l && q < l - 1) { - for (e = H(), g = this.U, f = r, h = Math.min(d + 1, this.rtl ? q + 1 : l - q), e[f] = 1, k = 1; k < h; k++) { + for (e = G(), g = this.U, f = r, h = Math.min(d + 1, this.rtl ? q + 1 : l - q), e[f] = 1, k = 1; k < h; k++) { if ((r = b[this.rtl ? l - 1 - q - k : q + k]) && !e[r]) { e[r] = 1; const n = this.score ? this.score(b, f, q, r, k - 1) : vb(g + (l / 2 > g ? 0 : 1), l, q, h - 1, k - 1), t = this.bidirectional && r > f; @@ -2207,7 +2218,7 @@ P.prototype.add = function(a, b, c, d) { function wb(a, b, c, d, e, f, g) { let h = g ? a.ctx : a.map, k; if (!b[c] || g && !(k = b[c])[g]) { - if (g ? (b = k || (b[c] = H()), b[g] = 1, (k = h.get(g)) ? h = k : h.set(g, h = new Map())) : b[c] = 1, (k = h.get(c)) ? h = k : h.set(c, h = k = []), h = h[d] || (h[d] = []), !f || !h.includes(e)) { + if (g ? (b = k || (b[c] = G()), b[g] = 1, (k = h.get(g)) ? h = k : h.set(g, h = new Map())) : b[c] = 1, (k = h.get(c)) ? h = k : h.set(c, h = k = []), h = h[d] || (h[d] = []), !f || !h.includes(e)) { if (h.length === 2 ** 31 - 1) { b = new U(h); if (a.fastupdate) { @@ -2243,7 +2254,7 @@ function vb(a, b, c, d, e) { if (2 === e && f && !g) { return xb.call(this, q[1], q[0], b, h, k, u, l); } - let r = H(), n = 0, t; + let r = G(), n = 0, t; f && (t = q[0], n = 1); p || 0 === p || (p = t ? this.U : this.resolution); if (this.db) { @@ -2262,7 +2273,7 @@ function vb(a, b, c, d, e) { } t && (g && y && d.length || (t = D)); } - g && t && n === e - 1 && !d.length && (p = x.resolution, t = "", n = -1, r = H()); + g && t && n === e - 1 && !d.length && (p = x.resolution, t = "", n = -1, r = G()); } return Ab(d, p, b, h, g, m, k); }(); @@ -2277,16 +2288,16 @@ function vb(a, b, c, d, e) { } t && (g && x && d.length || (t = y)); } - g && t && n === e - 1 && !d.length && (p = this.resolution, t = "", n = -1, r = H()); + g && t && n === e - 1 && !d.length && (p = this.resolution, t = "", n = -1, r = G()); } return Ab(d, p, b, h, g, m, k); }; function Ab(a, b, c, d, e, f, g) { let h = a.length, k = a; if (1 < h) { - k = Xa(a, b, c, d, e, f, g); + k = Ya(a, b, c, d, e, f, g); } else if (1 === h) { - return g ? Sa.call(null, a[0], c, d) : new Y(a[0], this); + return g ? Ta.call(null, a[0], c, d) : new Y(a[0], this); } return g ? k : new Y(k, this); } @@ -2294,7 +2305,7 @@ function xb(a, b, c, d, e, f, g) { a = yb(this, a, b, c, d, e, f, g); return this.db ? a.then(function(h) { return e ? h || [] : new Y(h, this); - }) : a && a.length ? e ? Sa.call(this, a, c, d) : new Y(a, this) : e ? [] : new Y([], this); + }) : a && a.length ? e ? Ta.call(this, a, c, d) : new Y(a, this) : e ? [] : new Y([], this); } function zb(a, b, c, d) { let e = []; @@ -2338,7 +2349,7 @@ function yb(a, b, c, d, e, f, g, h) { } c = a.context; const d = !0 === c ? {depth:1} : c || {}, e = M(a.encoder) ? nb[a.encoder] : a.encode || a.encoder || {}; - this.encoder = e.encode ? e : "object" === typeof e ? new ma(e) : {encode:e}; + this.encoder = e.encode ? e : "object" === typeof e ? new na(e) : {encode:e}; this.resolution = a.resolution || 9; this.tokenize = c = (c = a.tokenize) && "default" !== c && "exact" !== c && c || "strict"; this.depth = "strict" === c && d.depth || 0; @@ -2413,7 +2424,7 @@ w.export = function(a, b, c = 0, d = 0) { switch(d) { case 0: e = "reg"; - f = Ga(this.reg); + f = Ha(this.reg); break; case 1: e = "cfg"; @@ -2421,29 +2432,29 @@ w.export = function(a, b, c = 0, d = 0) { break; case 2: e = "map"; - f = Ca(this.map, this.reg.size); + f = Da(this.map, this.reg.size); break; case 3: e = "ctx"; - f = Ea(this.ctx, this.reg.size); + f = Fa(this.ctx, this.reg.size); break; default: return; } - return Ia.call(this, a, b, e, f, c, d); + return Ja.call(this, a, b, e, f, c, d); }; w.import = function(a, b) { if (b) { switch("string" === typeof b && (b = JSON.parse(b)), a = a.split("."), "json" === a[a.length - 1] && a.pop(), 3 === a.length && a.shift(), a = 1 < a.length ? a[1] : a[0], a) { case "reg": this.fastupdate = !1; - this.reg = Ha(b, this.reg); + this.reg = Ia(b, this.reg); break; case "map": - this.map = Da(b, this.map); + this.map = Ea(b, this.map); break; case "ctx": - this.ctx = Fa(b, this.ctx); + this.ctx = Ga(b, this.ctx); } } }; @@ -2455,11 +2466,11 @@ w.serialize = function(a = !0) { f || (f = typeof e), b += (b ? "," : "") + ("string" === f ? '"' + e + '"' : e); } b = "index.reg=new Set([" + b + "]);"; - c = Ja(this.map, f); + c = Ka(this.map, f); c = "index.map=new Map([" + c + "]);"; for (const g of this.ctx.entries()) { e = g[0]; - let h = Ja(g[1], f); + let h = Ka(g[1], f); h = "new Map([" + h + "])"; h = '["' + e + '",' + h + "]"; d += (d ? "," : "") + h; @@ -2468,8 +2479,8 @@ w.serialize = function(a = !0) { } return a ? "function inject(index){" + b + c + d + "}" : b + c + d; }; -ra(P.prototype); -const Bb = "undefined" !== typeof window && (window.indexedDB || window.mozIndexedDB || window.webkitIndexedDB || window.msIndexedDB), Cb = ["map", "ctx", "tag", "reg", "cfg"], Db = H(); +sa(P.prototype); +const Bb = "undefined" !== typeof window && (window.indexedDB || window.mozIndexedDB || window.webkitIndexedDB || window.msIndexedDB), Cb = ["map", "ctx", "tag", "reg", "cfg"], Db = G(); function Eb(a, b = {}) { if (!this || this.constructor !== Eb) { return new Eb(a, b); @@ -2637,7 +2648,7 @@ w.commit = async function(a, b, c) { d[e] = f.del; } } - b || (c || (d = d.concat(da(a.reg))), d.length && await this.remove(d)); + b || (c || (d = d.concat(ea(a.reg))), d.length && await this.remove(d)); } a.reg.size && (await this.transaction("map", "readwrite", function(d) { for (const e of a.map) { @@ -2772,7 +2783,7 @@ function Z(a, b) { a = null; }); } -;const Gb = {Index:P, Charset:nb, Encoder:ma, Document:Pa, Worker:Aa, Resolver:Y, IndexedDB:Eb, Language:{}}, Hb = "undefined" !== typeof self ? self : "undefined" !== typeof global ? global : self; +;const Gb = {Index:P, Charset:nb, Encoder:na, Document:Qa, Worker:Ba, Resolver:Y, IndexedDB:Eb, Language:{}}, Hb = "undefined" !== typeof self ? self : "undefined" !== typeof global ? global : self; let Ib; (Ib = Hb.define) && Ib.amd ? Ib([], function() { return Gb; diff --git a/dist/flexsearch.bundle.min.js b/dist/flexsearch.bundle.min.js index 5f6574b..3f089a8 100644 --- a/dist/flexsearch.bundle.min.js +++ b/dist/flexsearch.bundle.min.js @@ -1,91 +1,91 @@ /**! - * FlexSearch.js v0.8.164 (Bundle) + * FlexSearch.js v0.8.165 (Bundle) * Author and Copyright: Thomas Wilkerling * Licence: Apache-2.0 * Hosted by Nextapps GmbH * https://github.com/nextapps-de/flexsearch */ -(function _f(self){'use strict';if(typeof module!=='undefined')self=module;else if(typeof process !== 'undefined')self=process;self._factory=_f;var v;function E(a,b,c){const d=typeof c,e=typeof a;if("undefined"!==d){if("undefined"!==e){if(c){if("function"===e&&d===e)return function(h){return a(c(h))};b=a.constructor;if(b===c.constructor){if(b===Array)return c.concat(a);if(b===Map){var f=new Map(c);for(var g of a)f.set(g[0],g[1]);return f}if(b===Set){g=new Set(c);for(f of a.values())g.add(f);return g}}}return a}return c}return"undefined"===e?b:a}function H(){return Object.create(null)}function M(a){return"string"===typeof a} -function ca(a){return"object"===typeof a}function da(a){const b=[];for(const c of a.keys())b.push(c);return b}function ea(a,b){if(M(b))a=a[b];else for(let c=0;a&&c"a1a".split(c).length; -this.numeric=E(a.numeric,d)}else{try{this.split=E(this.split,ha)}catch(e){this.split=/\s+/}this.numeric=E(a.numeric,E(this.numeric,!0))}this.prepare=E(a.prepare,null,this.prepare);this.finalize=E(a.finalize,null,this.finalize);c=a.filter;this.filter="function"===typeof c?c:E(c&&new Set(c),null,this.filter);this.dedupe=E(a.dedupe,!0,this.dedupe);this.matcher=E((c=a.matcher)&&new Map(c),null,this.matcher);this.mapper=E((c=a.mapper)&&new Map(c),null,this.mapper);this.stemmer=E((c=a.stemmer)&&new Map(c), +this.numeric=E(a.numeric,d)}else{try{this.split=E(this.split,ia)}catch(e){this.split=/\s+/}this.numeric=E(a.numeric,E(this.numeric,!0))}this.prepare=E(a.prepare,null,this.prepare);this.finalize=E(a.finalize,null,this.finalize);c=a.filter;this.filter="function"===typeof c?c:E(c&&new Set(c),null,this.filter);this.dedupe=E(a.dedupe,!0,this.dedupe);this.matcher=E((c=a.matcher)&&new Map(c),null,this.matcher);this.mapper=E((c=a.mapper)&&new Map(c),null,this.mapper);this.stemmer=E((c=a.stemmer)&&new Map(c), null,this.stemmer);this.replacer=E(a.replacer,null,this.replacer);this.minlength=E(a.minlength,1,this.minlength);this.maxlength=E(a.maxlength,1024,this.maxlength);this.rtl=E(a.rtl,!1,this.rtl);if(this.cache=c=E(a.cache,!0,this.cache))this.H=null,this.S="number"===typeof c?c:2E5,this.B=new Map,this.G=new Map,this.L=this.K=128;this.h="";this.M=null;this.A="";this.N=null;if(this.matcher)for(const e of this.matcher.keys())this.h+=(this.h?"|":"")+e;if(this.stemmer)for(const e of this.stemmer.keys())this.A+= (this.A?"|":"")+e;return this};v.addStemmer=function(a,b){this.stemmer||(this.stemmer=new Map);this.stemmer.set(a,b);this.A+=(this.A?"|":"")+a;this.N=null;this.cache&&N(this);return this};v.addFilter=function(a){"function"===typeof a?this.filter=a:(this.filter||(this.filter=new Set),this.filter.add(a));this.cache&&N(this);return this}; v.addMapper=function(a,b){if("object"===typeof a)return this.addReplacer(a,b);if(1a.length&&(this.dedupe||this.mapper))return this.addMapper(a,b);this.matcher||(this.matcher=new Map);this.matcher.set(a,b);this.h+=(this.h?"|":"")+a;this.M=null;this.cache&&N(this);return this}; v.addReplacer=function(a,b){if("string"===typeof a)return this.addMatcher(a,b);this.replacer||(this.replacer=[]);this.replacer.push(a,b);this.cache&&N(this);return this}; -v.encode=function(a,b){if(this.cache&&a.length<=this.K)if(this.H){if(this.B.has(a))return this.B.get(a)}else this.H=setTimeout(N,50,this);this.normalize&&("function"===typeof this.normalize?a=this.normalize(a):a=la?a.normalize("NFKD").replace(la,"").toLowerCase():a.toLowerCase());this.prepare&&(a=this.prepare(a));this.numeric&&3this.maxlength)){if(b){if(e[m])continue;e[m]=1}else{if(f===m)continue;f=m}if(c)d.push(m);else if(!this.filter||("function"===typeof this.filter?this.filter(m):!this.filter.has(m))){if(this.cache&&m.length<=this.L)if(this.H){var k=this.G.get(m);if(k||""===k){k&&d.push(k);continue}}else this.H=setTimeout(N,50,this);if(this.stemmer){this.N||(this.N=new RegExp("(?!^)("+ +v.encode=function(a,b){if(this.cache&&a.length<=this.K)if(this.H){if(this.B.has(a))return this.B.get(a)}else this.H=setTimeout(N,50,this);this.normalize&&("function"===typeof this.normalize?a=this.normalize(a):a=ma?a.normalize("NFKD").replace(ma,"").toLowerCase():a.toLowerCase());this.prepare&&(a=this.prepare(a));this.numeric&&3this.maxlength)){if(b){if(e[m])continue;e[m]=1}else{if(f===m)continue;f=m}if(c)d.push(m);else if(!this.filter||("function"===typeof this.filter?this.filter(m):!this.filter.has(m))){if(this.cache&&m.length<=this.L)if(this.H){var k=this.G.get(m);if(k||""===k){k&&d.push(k);continue}}else this.H=setTimeout(N,50,this);if(this.stemmer){this.N||(this.N=new RegExp("(?!^)("+ this.A+")$"));let u;for(;u!==m&&2this.stemmer.get(r))}if(m&&(this.mapper||this.dedupe&&1this.matcher.get(u)));if(m&&this.replacer)for(k=0;m&&kthis.S&&(this.G.clear(),this.L=this.L/1.1|0));if(m){if(m!==n)if(b){if(e[m])continue;e[m]=1}else{if(g===m)continue;g=m}d.push(m)}}}this.finalize&&(d=this.finalize(d)||d);this.cache&&a.length<=this.K&&(this.B.set(a,d),this.B.size>this.S&&(this.B.clear(),this.K=this.K/1.1|0));return d};function N(a){a.H=null;a.B.clear();a.G.clear()};let pa,qa;async function ra(a){a=a.data;var b=a.task;const c=a.id;let d=a.args;switch(b){case "init":qa=a.options||{};(b=a.factory)?(Function("return "+b)()(self),pa=new self.FlexSearch.Index(qa),delete self.FlexSearch):pa=new O(qa);postMessage({id:c});break;default:let e;"export"===b&&(d[1]?(d[0]=qa.export,d[2]=0,d[3]=1):d=null);"import"===b?d[0]&&(a=await qa.import.call(pa,d[0]),pa.import(d[0],a)):(e=d&&pa[b].apply(pa,d))&&e.then&&(e=await e);postMessage("search"===b?{id:c,msg:e}:{id:c})}};function sa(a){ta.call(a,"add");ta.call(a,"append");ta.call(a,"search");ta.call(a,"update");ta.call(a,"remove");ta.call(a,"searchCache")}let ua,va,ya;function za(){ua=ya=0} -function ta(a){this[a+"Async"]=function(){const b=arguments;var c=b[b.length-1];let d;"function"===typeof c&&(d=c,delete b[b.length-1]);ua?ya||(ya=Date.now()-va>=this.priority*this.priority*3):(ua=setTimeout(za,0),va=Date.now());if(ya){const f=this;return new Promise(g=>{setTimeout(function(){g(f[a+"Async"].apply(f,b))},0)})}const e=this[a].apply(this,b);c=e.then?e:new Promise(f=>f(e));d&&c.then(d);return c}};let Aa=0; -function Ba(a={},b){function c(h){function k(l){l=l.data||l;const m=l.id,n=m&&f.h[m];n&&(n(l.msg),delete f.h[m])}this.worker=h;this.h=H();if(this.worker){e?this.worker.on("message",k):this.worker.onmessage=k;if(a.config)return new Promise(function(l){f.h[++Aa]=function(){l(f);1E9=g.length)b-=g.length;else{b=g[d?"splice":"slice"](b,c);const h=b.length;if(h&&(e=e.length?e.concat(b):b,c-=h,d&&(a.length-=h),!c))break;b=0}return e} +this.replacer[k+1]);this.cache&&n.length<=this.L&&(this.G.set(n,m),this.G.size>this.S&&(this.G.clear(),this.L=this.L/1.1|0));if(m){if(m!==n)if(b){if(e[m])continue;e[m]=1}else{if(g===m)continue;g=m}d.push(m)}}}this.finalize&&(d=this.finalize(d)||d);this.cache&&a.length<=this.K&&(this.B.set(a,d),this.B.size>this.S&&(this.B.clear(),this.K=this.K/1.1|0));return d};function N(a){a.H=null;a.B.clear();a.G.clear()};let qa,ra;async function sa(a){a=a.data;var b=a.task;const c=a.id;let d=a.args;switch(b){case "init":ra=a.options||{};(b=a.factory)?(Function("return "+b)()(self),qa=new self.FlexSearch.Index(ra),delete self.FlexSearch):qa=new O(ra);postMessage({id:c});break;default:let e;"export"===b&&(d[1]?(d[0]=ra.export,d[2]=0,d[3]=1):d=null);"import"===b?d[0]&&(a=await ra.import.call(qa,d[0]),qa.import(d[0],a)):(e=d&&qa[b].apply(qa,d))&&e.then&&(e=await e);postMessage("search"===b?{id:c,msg:e}:{id:c})}};function ta(a){ua.call(a,"add");ua.call(a,"append");ua.call(a,"search");ua.call(a,"update");ua.call(a,"remove");ua.call(a,"searchCache")}let va,ya,za;function Aa(){va=za=0} +function ua(a){this[a+"Async"]=function(){const b=arguments;var c=b[b.length-1];let d;"function"===typeof c&&(d=c,delete b[b.length-1]);va?za||(za=Date.now()-ya>=this.priority*this.priority*3):(va=setTimeout(Aa,0),ya=Date.now());if(za){const f=this;return new Promise(g=>{setTimeout(function(){g(f[a+"Async"].apply(f,b))},0)})}const e=this[a].apply(this,b);c=e.then?e:new Promise(f=>f(e));d&&c.then(d);return c}};let Ba=0; +function Ca(a={},b){function c(h){function k(l){l=l.data||l;const m=l.id,n=m&&f.h[m];n&&(n(l.msg),delete f.h[m])}this.worker=h;this.h=G();if(this.worker){e?this.worker.on("message",k):this.worker.onmessage=k;if(a.config)return new Promise(function(l){f.h[++Ba]=function(){l(f);1E9=g.length)b-=g.length;else{b=g[d?"splice":"slice"](b,c);const h=b.length;if(h&&(e=e.length?e.concat(b):b,c-=h,d&&(a.length-=h),!c))break;b=0}return e} function R(a){if(!this||this.constructor!==R)return new R(a);this.index=a?[a]:[];this.length=a?a.length:0;const b=this;return new Proxy([],{get(c,d){if("length"===d)return b.length;if("push"===d)return function(e){b.index[b.index.length-1].push(e);b.length++};if("pop"===d)return function(){if(b.length)return b.length--,b.index[b.index.length-1].pop()};if("indexOf"===d)return function(e){let f=0;for(let g=0,h,k;gb?b?a.slice(c,c+b):a.slice(c):a,d?X.call(this,a):a;let e=[];for(let f=0,g,h;f=h){c-=h;continue}cb&&(g=g.slice(0,b),h=b);if(!e.length&&h>=b)return d?X.call(this,g):g;e.push(g);b-=h;if(!b)break}e=1a.length?this.result=a[0]:(this.result=Va(a,c,d,!1,this.h),d=0));return f?this.resolve(c,d,e):this};Y.prototype.and=function(){let a=this.result.length,b,c,d,e;if(!a){const f=arguments[0];f&&(a=!!f.suggest,e=f.resolve,b=f.limit,c=f.offset,d=f.enrich&&e)}if(a){const {O:f,P:g,limit:h,offset:k,enrich:l,resolve:m,suggest:n}=Ta(this,"and",arguments);return Wa.call(this,f,g,h,k,l,m,n)}return e?this.resolve(b,c,d):this}; -function Wa(a,b,c,d,e,f,g){if(b.length){const h=this;return Promise.all(b).then(function(k){a=[];for(let l=0,m;la.length)this.result=a[0];else{if(b=fa(a))return this.result=Xa(a,b,c,d,g,this.h,f),f?e?X.call(this.index,this.result):this.result:this;this.result=[]}else g||(this.result=a);return f?this.resolve(c,d,e):this};Y.prototype.xor=function(){const {O:a,P:b,limit:c,offset:d,enrich:e,resolve:f,suggest:g}=Ta(this,"xor",arguments);return Ya.call(this,a,b,c,d,e,f,g)}; -function Ya(a,b,c,d,e,f,g){if(b.length){const h=this;return Promise.all(b).then(function(k){a=[];for(let l=0,m;la.length)this.result=a[0];else return this.result=Za.call(this,a,c,d,f,this.h),f?e?X.call(this.index,this.result):this.result:this;else g||(this.result=a);return f?this.resolve(c,d,e):this} -function Za(a,b,c,d,e){const f=[],g=H();let h=0;for(let k=0,l;kD&&(D=t.length+(t?1:0)),G=t.length+(t?1:0)+F.length,B+=C,xa.push(w.length),w.push({match:F})),t+=(t?" ":"")+F)}if(!z)A=y[x],t+=(t?" ":"")+A,k&&w.push({text:A});else if(k&&B>=k)break}B=xa.length*(f.length-2);if(r||p||k&&t.length-B>k)if(B=k+B-2*u,x=G-D, -0y&&(y=0)),w=w.length-1){if(J>= -w.length){x[z+1]=1;J>=y.length&&(B[z+1]=1);continue}C-=u}t=w[J].text;if(K=p&&I[z])if(0K)if(x[z+1]=1,l)t=t.substring(0,K);else continue;(K-=t.length)||(K=-1);I[z]=K}else{x[z+1]=1;continue}if(C+t.length+1<=k)t=" "+t,G[z]+=t;else if(l)T=k-C-1,0=J){if(0>J){x[z]=1;B[z]=1;continue}C-=u}t=w[J].text;if(K=r&&A[z])if(0K)if(x[z]=1,l)t=t.substring(t.length- -K);else continue;(K-=t.length)||(K=-1);A[z]=K}else{x[z]=1;continue}if(C+t.length+1<=k)t+=" ",G[z]=t+G[z];else if(l)T=t.length+1-(k-C),0<=T&&T=y.length-1?Na=1:Jc||d?k.slice(d,c+d):k;else{if(ac||d)k=k.slice(d,c+d)}else{e= +if("includes"===d)return function(e){for(let f=0;fb?b?a.slice(c,c+b):a.slice(c):a,d?X.call(this,a):a;let e=[];for(let f=0,g,h;f=h){c-=h;continue}cb&&(g=g.slice(0,b),h=b);if(!e.length&&h>=b)return d?X.call(this,g):g;e.push(g);b-=h;if(!b)break}e=1a.length?this.result=a[0]:(this.result=Wa(a,c,d,!1,this.h),d=0));return f?this.resolve(c,d,e):this};Y.prototype.and=function(){let a=this.result.length,b,c,d,e;if(!a){const f=arguments[0];f&&(a=!!f.suggest,e=f.resolve,b=f.limit,c=f.offset,d=f.enrich&&e)}if(a){const {O:f,P:g,limit:h,offset:k,enrich:l,resolve:m,suggest:n}=Ua(this,"and",arguments);return Xa.call(this,f,g,h,k,l,m,n)}return e?this.resolve(b,c,d):this}; +function Xa(a,b,c,d,e,f,g){if(b.length){const h=this;return Promise.all(b).then(function(k){a=[];for(let l=0,m;la.length)this.result=a[0];else{if(b=ha(a))return this.result=Ya(a,b,c,d,g,this.h,f),f?e?X.call(this.index,this.result):this.result:this;this.result=[]}else g||(this.result=a);return f?this.resolve(c,d,e):this};Y.prototype.xor=function(){const {O:a,P:b,limit:c,offset:d,enrich:e,resolve:f,suggest:g}=Ua(this,"xor",arguments);return Za.call(this,a,b,c,d,e,f,g)}; +function Za(a,b,c,d,e,f,g){if(b.length){const h=this;return Promise.all(b).then(function(k){a=[];for(let l=0,m;la.length)this.result=a[0];else return this.result=$a.call(this,a,c,d,f,this.h),f?e?X.call(this.index,this.result):this.result:this;else g||(this.result=a);return f?this.resolve(c,d,e):this} +function $a(a,b,c,d,e){const f=[],g=G();let h=0;for(let k=0,l;kD&&(D=t.length+(t?1:0)),H=t.length+(t?1:0)+F.length,B+=C,xa.push(w.length),w.push({match:F})),t+=(t?" ":"")+F)}if(!z)A=y[x],t+=(t?" ":"")+A,k&&w.push({text:A});else if(k&&B>=k)break}B=xa.length*(f.length-2);if(r||p||k&&t.length-B>k)if(B=k+B-2*u,x=H-D, +0y&&(y=0)),w=w.length-1){if(J>= +w.length){x[z+1]=1;J>=y.length&&(B[z+1]=1);continue}C-=u}t=w[J].text;if(K=p&&I[z])if(0K)if(x[z+1]=1,l)t=t.substring(0,K);else continue;(K-=t.length)||(K=-1);I[z]=K}else{x[z+1]=1;continue}if(C+t.length+1<=k)t=" "+t,H[z]+=t;else if(l)T=k-C-1,0=J){if(0>J){x[z]=1;B[z]=1;continue}C-=u}t=w[J].text;if(K=r&&A[z])if(0K)if(x[z]=1,l)t=t.substring(t.length- +K);else continue;(K-=t.length)||(K=-1);A[z]=K}else{x[z]=1;continue}if(C+t.length+1<=k)t+=" ",H[z]=t+H[z];else if(l)T=t.length+1-(k-C),0<=T&&T=y.length-1?Na=1:Jc||d?k.slice(d,c+d):k;else{if(ac||d)k=k.slice(d,c+d)}else{e= [];for(let n=0,u;nd)d-=u.length;else{if(c&&u.length>c||d)u=u.slice(d,c+d),c-=u.length,d&&(d-=u.length);e.push(u);if(!c)break}k=e}}return k} -function Va(a,b,c,d,e){const f=[],g=H();let h;var k=a.length;let l;if(d)for(e=k-1;0<=e;e--){if(l=(d=a[e])&&d.length)for(k=0;kc||d)a=a.slice(d,d+c);e&&(a=X.call(this,a));return a}} +function Wa(a,b,c,d,e){const f=[],g=G();let h;var k=a.length;let l;if(d)for(e=k-1;0<=e;e--){if(l=(d=a[e])&&d.length)for(k=0;kc||d)a=a.slice(d,d+c);e&&(a=X.call(this,a))}return a} function X(a){if(!this||!this.store)return a;const b=Array(a.length);for(let c=0,d;cthis.limit&&this.cache.delete(this.cache.keys().next().value)}; +v.get=function(a){return this.db?this.index.get(this.field[0]).db.enrich(a).then(function(b){return b[0]&&b[0].doc||null}):this.store.get(a)||null};v.set=function(a,b){"object"===typeof a&&(b=a,a=fa(b,this.key));this.store.set(a,b);return this};v.searchCache=rb; +v.export=function(a,b,c=0,d=0){if(cthis.limit&&this.cache.delete(this.cache.keys().next().value)}; pb.prototype.get=function(a){const b=this.cache.get(a);b&&this.h!==a&&(this.cache.delete(a),this.cache.set(this.h=a,b));return b};pb.prototype.remove=function(a){for(const b of this.cache){const c=b[0];b[1].includes(a)&&this.cache.delete(c)}};pb.prototype.clear=function(){this.cache.clear();this.h=""};O.prototype.remove=function(a,b){const c=this.reg.size&&(this.fastupdate?this.reg.get(a):this.reg.has(a));if(c){if(this.fastupdate)for(let d=0,e;de.length)e.pop();else{const f=e.indexOf(a);f===c.length-1?e.pop():e.splice(f,1)}}else sb(this.map,a),this.depth&&sb(this.ctx,a);b||this.reg.delete(a)}this.db&&(this.commit_task.push({del:a}),this.T&&tb(this));this.cache&&this.cache.remove(a);return this}; -function sb(a,b){let c=0;var d="undefined"===typeof b;if(a.constructor===Array)for(let e=0,f,g;eq;f--){g=p.substring(q,f);t=this.rtl?e-1-q:q;var h=this.score?this.score(b,p,r,g,t):vb(u, -l,r,e,t);wb(this,n,g,h,a,c)}break}case "bidirectional":case "reverse":if(1q;f--){g=p.substring(q,f);t=this.rtl?e-1-q:q;var h=this.score?this.score(b,p,r,g,t):vb(u, +l,r,e,t);wb(this,n,g,h,a,c)}break}case "bidirectional":case "reverse":if(1g?0:1),l,r,h-1,k-1),t=this.bidirectional&&p>f;wb(this,m,t?f:p,q,a,c,t?p:f)}}}}this.fastupdate||this.reg.add(a)}else b=""}this.db&&(b||this.commit_task.push({del:a}),this.T&&tb(this));return this}; -function wb(a,b,c,d,e,f,g){let h=g?a.ctx:a.map,k;if(!b[c]||g&&!(k=b[c])[g])if(g?(b=k||(b[c]=H()),b[g]=1,(k=h.get(g))?h=k:h.set(g,h=new Map)):b[c]=1,(k=h.get(c))?h=k:h.set(c,h=k=[]),h=h[d]||(h[d]=[]),!f||!h.includes(e)){if(h.length===2**31-1){b=new R(h);if(a.fastupdate)for(let l of a.reg.values())l.includes(h)&&(l[l.indexOf(h)]=b);k[d]=h=b}h.push(e);a.fastupdate&&((d=a.reg.get(e))?d.push(h):a.reg.set(e,[h]))}} +function wb(a,b,c,d,e,f,g){let h=g?a.ctx:a.map,k;if(!b[c]||g&&!(k=b[c])[g])if(g?(b=k||(b[c]=G()),b[g]=1,(k=h.get(g))?h=k:h.set(g,h=new Map)):b[c]=1,(k=h.get(c))?h=k:h.set(c,h=k=[]),h=h[d]||(h[d]=[]),!f||!h.includes(e)){if(h.length===2**31-1){b=new R(h);if(a.fastupdate)for(let l of a.reg.values())l.includes(h)&&(l[l.indexOf(h)]=b);k[d]=h=b}h.push(e);a.fastupdate&&((d=a.reg.get(e))?d.push(h):a.reg.set(e,[h]))}} function vb(a,b,c,d,e){return c&&1c)&&(k=c,c=b,b=k);if(a.db)return a.db.get(b,c,d,e,f,g,h);a=c?(a=a.ctx.get(c))&&a.get(b):a.map.get(b);return a};function O(a,b){if(!this||this.constructor!==O)return new O(a);if(a){var c=M(a)?a:a.preset;c&&(a=Object.assign({},ub[c],a))}else a={};c=a.context;const d=!0===c?{depth:1}:c||{},e=M(a.encoder)?nb[a.encoder]:a.encode||a.encoder||{};this.encoder=e.encode?e:"object"===typeof e?new ma(e):{encode:e};this.resolution=a.resolution||9;this.tokenize=c=(c=a.tokenize)&&"default"!==c&&"exact"!==c&&c||"strict";this.depth="strict"===c&&d.depth||0;this.bidirectional=!1!==d.bidirectional;this.fastupdate=!!a.fastupdate; +h,k,u,l);if(2===e&&f&&!g)return xb.call(this,r[1],r[0],b,h,k,u,l);let p=G(),q=0,t;f&&(t=r[0],q=1);n||0===n||(n=t?this.U:this.resolution);if(this.db){if(this.db.search&&(c=this.db.search(this,r,b,h,g,k,u,l),!1!==c))return c;const y=this;return async function(){for(let w,D;qc)&&(k=c,c=b,b=k);if(a.db)return a.db.get(b,c,d,e,f,g,h);a=c?(a=a.ctx.get(c))&&a.get(b):a.map.get(b);return a};function O(a,b){if(!this||this.constructor!==O)return new O(a);if(a){var c=M(a)?a:a.preset;c&&(a=Object.assign({},ub[c],a))}else a={};c=a.context;const d=!0===c?{depth:1}:c||{},e=M(a.encoder)?nb[a.encoder]:a.encode||a.encoder||{};this.encoder=e.encode?e:"object"===typeof e?new na(e):{encode:e};this.resolution=a.resolution||9;this.tokenize=c=(c=a.tokenize)&&"default"!==c&&"exact"!==c&&c||"strict";this.depth="strict"===c&&d.depth||0;this.bidirectional=!1!==d.bidirectional;this.fastupdate=!!a.fastupdate; this.score=a.score||null;(c=a.keystore||0)&&(this.keystore=c);this.map=c?new U(c):new Map;this.ctx=c?new U(c):new Map;this.reg=b||(this.fastupdate?c?new U(c):new Map:c?new V(c):new Set);this.U=d.resolution||3;this.rtl=e.rtl||a.rtl||!1;this.cache=(c=a.cache||null)&&new pb(c);this.resolve=!1!==a.resolve;if(c=a.db)this.db=this.mount(c);this.T=!1!==a.commit;this.commit_task=[];this.commit_timer=null;this.priority=a.priority||4}v=O.prototype; v.mount=function(a){this.commit_timer&&(clearTimeout(this.commit_timer),this.commit_timer=null);return a.mount(this)};v.commit=function(a,b){this.commit_timer&&(clearTimeout(this.commit_timer),this.commit_timer=null);return this.db.commit(this,a,b)};v.destroy=function(){this.commit_timer&&(clearTimeout(this.commit_timer),this.commit_timer=null);return this.db.destroy()};function tb(a){a.commit_timer||(a.commit_timer=setTimeout(function(){a.commit_timer=null;a.db.commit(a,void 0,void 0)},1))} v.clear=function(){this.map.clear();this.ctx.clear();this.reg.clear();this.cache&&this.cache.clear();this.db&&(this.commit_timer&&clearTimeout(this.commit_timer),this.commit_timer=null,this.commit_task=[{clear:!0}]);return this};v.append=function(a,b){return this.add(a,b,!0)};v.contain=function(a){return this.db?this.db.has(a):this.reg.has(a)};v.update=function(a,b){const c=this,d=this.remove(a);return d&&d.then?d.then(()=>c.add(a,b)):this.add(a,b)}; -v.cleanup=function(){if(!this.fastupdate)return this;sb(this.map);this.depth&&sb(this.ctx);return this};v.searchCache=rb;v.export=function(a,b,c=0,d=0){let e,f;switch(d){case 0:e="reg";f=Ha(this.reg);break;case 1:e="cfg";f=null;break;case 2:e="map";f=Da(this.map,this.reg.size);break;case 3:e="ctx";f=Fa(this.ctx,this.reg.size);break;default:return}return Ja.call(this,a,b,e,f,c,d)}; -v.import=function(a,b){if(b)switch("string"===typeof b&&(b=JSON.parse(b)),a=a.split("."),"json"===a[a.length-1]&&a.pop(),3===a.length&&a.shift(),a=1=f.length)return[];if(!b&&!c)return f;f=f.slice(c,c+b);return d?e.enrich(f):f})}; v.enrich=function(a){"object"!==typeof a&&(a=[a]);const b=this.db.transaction("reg","readonly").objectStore("reg"),c=[];for(let d=0;d{a.onsuccess=a.oncomplete=function(){b&&b(this.result);b=null;c(this.result)};a.onerror=a.onblocked=d;a=null})};const Gb={Index:O,Charset:nb,Encoder:ma,Document:W,Worker:Ba,Resolver:Y,IndexedDB:Eb,Language:{}},Hb="undefined"!==typeof self?self:"undefined"!==typeof global?global:self;let Ib;(Ib=Hb.define)&&Ib.amd?Ib([],function(){return Gb}):"object"===typeof Hb.exports?Hb.exports=Gb:Hb.FlexSearch=Gb;}(this||self)); +function Z(a,b){return new Promise((c,d)=>{a.onsuccess=a.oncomplete=function(){b&&b(this.result);b=null;c(this.result)};a.onerror=a.onblocked=d;a=null})};const Gb={Index:O,Charset:nb,Encoder:na,Document:W,Worker:Ca,Resolver:Y,IndexedDB:Eb,Language:{}},Hb="undefined"!==typeof self?self:"undefined"!==typeof global?global:self;let Ib;(Ib=Hb.define)&&Ib.amd?Ib([],function(){return Gb}):"object"===typeof Hb.exports?Hb.exports=Gb:Hb.FlexSearch=Gb;}(this||self)); diff --git a/dist/flexsearch.bundle.module.debug.js b/dist/flexsearch.bundle.module.debug.js index 6b53055..658de7f 100644 --- a/dist/flexsearch.bundle.module.debug.js +++ b/dist/flexsearch.bundle.module.debug.js @@ -1,5 +1,5 @@ /**! - * FlexSearch.js v0.8.164 (Bundle/Module/Debug) + * FlexSearch.js v0.8.165 (Bundle/Module/Debug) * Author and Copyright: Thomas Wilkerling * Licence: Apache-2.0 * Hosted by Nextapps GmbH @@ -43,23 +43,26 @@ function E(a, b, c) { } return "undefined" === e ? b : a; } -function H() { +function aa(a, b) { + return "undefined" === typeof a ? b : a; +} +function G() { return Object.create(null); } function M(a) { return "string" === typeof a; } -function aa(a) { +function da(a) { return "object" === typeof a; } -function da(a) { +function ea(a) { const b = []; for (const c of a.keys()) { b.push(c); } return b; } -function ea(a, b) { +function fa(a, b) { if (M(b)) { a = a[b]; } else { @@ -69,17 +72,17 @@ function ea(a, b) { } return a; } -function fa(a) { +function ha(a) { let b = 0; for (let c = 0, d; c < a.length; c++) { (d = a[c]) && b < d.length && (b = d.length); } return b; } -;const ha = /[^\p{L}\p{N}]+/u, ia = /(\d{3})/g, ja = /(\D)(\d{3})/g, ka = /(\d{3})(\D)/g, la = /[\u0300-\u036f]/g; -function ma(a = {}) { - if (!this || this.constructor !== ma) { - return new ma(...arguments); +;const ia = /[^\p{L}\p{N}]+/u, ja = /(\d{3})/g, ka = /(\D)(\d{3})/g, la = /(\d{3})(\D)/g, ma = /[\u0300-\u036f]/g; +function na(a = {}) { + if (!this || this.constructor !== na) { + return new na(...arguments); } if (arguments.length) { for (a = 0; a < arguments.length; a++) { @@ -89,7 +92,7 @@ function ma(a = {}) { this.assign(a); } } -w = ma.prototype; +w = na.prototype; w.assign = function(a) { this.normalize = E(a.normalize, !0, this.normalize); let b = a.include, c = b || a.exclude || a.split, d; @@ -117,7 +120,7 @@ w.assign = function(a) { this.numeric = E(a.numeric, d); } else { try { - this.split = E(this.split, ha); + this.split = E(this.split, ia); } catch (e) { console.warn("This platform does not support unicode regex. It falls back to using simple whitespace splitter instead: /s+/."), this.split = /\s+/; } @@ -212,11 +215,11 @@ w.encode = function(a, b) { this.H = setTimeout(N, 50, this); } } - this.normalize && ("function" === typeof this.normalize ? a = this.normalize(a) : a = la ? a.normalize("NFKD").replace(la, "").toLowerCase() : a.toLowerCase()); + this.normalize && ("function" === typeof this.normalize ? a = this.normalize(a) : a = ma ? a.normalize("NFKD").replace(ma, "").toLowerCase() : a.toLowerCase()); this.prepare && (a = this.prepare(a)); - this.numeric && 3 < a.length && (a = a.replace(ja, "$1 $2").replace(ka, "$1 $2").replace(ia, "$1 ")); + this.numeric && 3 < a.length && (a = a.replace(ka, "$1 $2").replace(la, "$1 $2").replace(ja, "$1 ")); const c = !(this.dedupe || this.mapper || this.filter || this.matcher || this.stemmer || this.replacer); - let d = [], e = H(), f, g, h = this.split || "" === this.split ? a.split(this.split) : [a]; + let d = [], e = G(), f, g, h = this.split || "" === this.split ? a.split(this.split) : [a]; for (let l = 0, m, p; l < h.length; l++) { if ((m = p = h[l]) && !(m.length < this.minlength || m.length > this.maxlength)) { if (b) { @@ -295,8 +298,8 @@ function N(a) { a.B.clear(); a.G.clear(); } -;let pa, O; -async function qa(a) { +;let qa, O; +async function ra(a) { a = a.data; var b = a.task; const c = a.id; @@ -304,7 +307,7 @@ async function qa(a) { switch(b) { case "init": O = a.options || {}; - (b = a.factory) ? (Function("return " + b)()(self), pa = new self.FlexSearch.Index(O), delete self.FlexSearch) : pa = new P(O); + (b = a.factory) ? (Function("return " + b)()(self), qa = new self.FlexSearch.Index(O), delete self.FlexSearch) : qa = new P(O); postMessage({id:c}); break; default: @@ -319,33 +322,33 @@ async function qa(a) { if (!O.import || "function" !== typeof O.import) { throw Error('Either no extern configuration provided for the Worker-Index or no method was defined on the config property "import".'); } - d[0] && (a = await O.import.call(pa, d[0]), pa.import(d[0], a)); + d[0] && (a = await O.import.call(qa, d[0]), qa.import(d[0], a)); } else { - (e = d && pa[b].apply(pa, d)) && e.then && (e = await e); + (e = d && qa[b].apply(qa, d)) && e.then && (e = await e); } postMessage("search" === b ? {id:c, msg:e} : {id:c}); } } -;function ra(a) { - sa.call(a, "add"); - sa.call(a, "append"); - sa.call(a, "search"); - sa.call(a, "update"); - sa.call(a, "remove"); - sa.call(a, "searchCache"); +;function sa(a) { + ta.call(a, "add"); + ta.call(a, "append"); + ta.call(a, "search"); + ta.call(a, "update"); + ta.call(a, "remove"); + ta.call(a, "searchCache"); } -let ta, ua, va; -function ya() { - ta = va = 0; +let ua, va, ya; +function za() { + ua = ya = 0; } -function sa(a) { +function ta(a) { this[a + "Async"] = function() { const b = arguments; var c = b[b.length - 1]; let d; "function" === typeof c && (d = c, delete b[b.length - 1]); - ta ? va || (va = Date.now() - ua >= this.priority * this.priority * 3) : (ta = setTimeout(ya, 0), ua = Date.now()); - if (va) { + ua ? ya || (ya = Date.now() - va >= this.priority * this.priority * 3) : (ua = setTimeout(za, 0), va = Date.now()); + if (ya) { const f = this; return new Promise(g => { setTimeout(function() { @@ -359,8 +362,8 @@ function sa(a) { return c; }; } -;let za = 0; -function Aa(a = {}, b) { +;let Aa = 0; +function Ba(a = {}, b) { function c(h) { function k(l) { l = l.data || l; @@ -368,30 +371,30 @@ function Aa(a = {}, b) { p && (p(l.msg), delete f.h[m]); } this.worker = h; - this.h = H(); + this.h = G(); if (this.worker) { e ? this.worker.on("message", k) : this.worker.onmessage = k; if (a.config) { return new Promise(function(l) { - f.h[++za] = function() { + f.h[++Aa] = function() { l(f); - 1e9 < za && (za = 0); + 1e9 < Aa && (Aa = 0); }; - f.worker.postMessage({id:za, task:"init", factory:d, options:a}); + f.worker.postMessage({id:Aa, task:"init", factory:d, options:a}); }); } - this.worker.postMessage({task:"init", factory:d, options:a}); this.priority = a.priority || 4; - b && (this.encoder = b); + this.encoder = b || null; + this.worker.postMessage({task:"init", factory:d, options:a}); return this; } } - if (!this || this.constructor !== Aa) { - return new Aa(a); + if (!this || this.constructor !== Ba) { + return new Ba(a); } let d = "undefined" !== typeof self ? self._factory : "undefined" !== typeof window ? window._factory : null; d && (d = d.toString()); - const e = "undefined" === typeof window, f = this, g = Ba(d, e, a.worker); + const e = "undefined" === typeof window, f = this, g = Ca(d, e, a.worker); return g.then ? g.then(function(h) { return c.call(f, h); }) : c.call(this, g); @@ -399,31 +402,32 @@ function Aa(a = {}, b) { R("add"); R("append"); R("search"); +R("searchCache"); R("update"); R("remove"); R("clear"); R("export"); R("import"); -ra(Aa.prototype); +sa(Ba.prototype); function R(a) { - Aa.prototype[a] = function() { + Ba.prototype[a] = function() { const b = this, c = [].slice.call(arguments); var d = c[c.length - 1]; let e; "function" === typeof d && (e = d, c.pop()); d = new Promise(function(f) { "export" === a && "function" === typeof c[0] && (c[0] = null); - b.h[++za] = f; - b.worker.postMessage({task:a, id:za, args:c}); + b.h[++Aa] = f; + b.worker.postMessage({task:a, id:Aa, args:c}); }); return e ? (d.then(e), this) : d; }; } -function Ba(a, b, c) { - return b ? "undefined" !== typeof module ? new(require("worker_threads")["Worker"])(__dirname+"/worker/node.js") : import("worker_threads").then(function(worker){return new worker["Worker"](import.meta.dirname+"/node/node.mjs")}) : a ? new window.Worker(URL.createObjectURL(new Blob(["onmessage=" + qa.toString()], {type:"text/javascript"}))) : new window.Worker("string" === typeof c ? c : import.meta.url.replace("/worker.js", "/worker/worker.js").replace("flexsearch.bundle.module.min.js", +function Ca(a, b, c) { + return b ? "undefined" !== typeof module ? new(require("worker_threads")["Worker"])(__dirname+"/worker/node.js") : import("worker_threads").then(function(worker){return new worker["Worker"](import.meta.dirname+"/node/node.mjs")}) : a ? new window.Worker(URL.createObjectURL(new Blob(["onmessage=" + ra.toString()], {type:"text/javascript"}))) : new window.Worker("string" === typeof c ? c : import.meta.url.replace("/worker.js", "/worker/worker.js").replace("flexsearch.bundle.module.min.js", "module/worker/worker.js"), {type:"module"}); } -;function Ca(a, b = 0) { +;function Da(a, b = 0) { let c = [], d = []; b && (b = 250000 / b * 5000 | 0); for (const e of a.entries()) { @@ -432,30 +436,30 @@ function Ba(a, b, c) { d.length && c.push(d); return c; } -function Da(a, b) { +function Ea(a, b) { b || (b = new Map()); for (let c = 0, d; c < a.length; c++) { d = a[c], b.set(d[0], d[1]); } return b; } -function Ea(a, b = 0) { +function Fa(a, b = 0) { let c = [], d = []; b && (b = 250000 / b * 1000 | 0); for (const e of a.entries()) { - d.push([e[0], Ca(e[1])[0]]), d.length === b && (c.push(d), d = []); + d.push([e[0], Da(e[1])[0]]), d.length === b && (c.push(d), d = []); } d.length && c.push(d); return c; } -function Fa(a, b) { +function Ga(a, b) { b || (b = new Map()); for (let c = 0, d, e; c < a.length; c++) { - d = a[c], e = b.get(d[0]), b.set(d[0], Da(d[1], e)); + d = a[c], e = b.get(d[0]), b.set(d[0], Ea(d[1], e)); } return b; } -function Ga(a) { +function Ha(a) { let b = [], c = []; for (const d of a.keys()) { c.push(d), 250000 === c.length && (b.push(c), c = []); @@ -463,14 +467,14 @@ function Ga(a) { c.length && b.push(c); return b; } -function Ha(a, b) { +function Ia(a, b) { b || (b = new Set()); for (let c = 0; c < a.length; c++) { b.add(a[c]); } return b; } -function Ia(a, b, c, d, e, f, g = 0) { +function Ja(a, b, c, d, e, f, g = 0) { const h = d && d.constructor === Array; var k = h ? d.shift() : d; if (!k) { @@ -479,12 +483,12 @@ function Ia(a, b, c, d, e, f, g = 0) { if ((k = a((b ? b + "." : "") + (g + 1) + "." + c, JSON.stringify(k))) && k.then) { const l = this; return k.then(function() { - return Ia.call(l, a, b, c, h ? d : null, e, f, g + 1); + return Ja.call(l, a, b, c, h ? d : null, e, f, g + 1); }); } - return Ia.call(this, a, b, c, h ? d : null, e, f, g + 1); + return Ja.call(this, a, b, c, h ? d : null, e, f, g + 1); } -function Ja(a, b) { +function Ka(a, b) { let c = ""; for (const d of a.entries()) { a = d[0]; @@ -504,7 +508,7 @@ function Ja(a, b) { } return c; } -;function Ka(a, b, c, d) { +;function Na(a, b, c, d) { let e = []; for (let f = 0, g; f < a.index.length; f++) { if (g = a.index[f], b >= g.length) { @@ -570,12 +574,12 @@ function U(a) { } if ("slice" === d) { return function(e, f) { - return Ka(b, e || 0, f || b.length, !1); + return Na(b, e || 0, f || b.length, !1); }; } if ("splice" === d) { return function(e, f) { - return Ka(b, e || 0, f || b.length, !0); + return Na(b, e || 0, f || b.length, !0); }; } if ("constructor" === d) { @@ -603,10 +607,10 @@ function V(a = 8) { if (!this || this.constructor !== V) { return new V(a); } - this.index = H(); + this.index = G(); this.h = []; this.size = 0; - 32 < a ? (this.B = Na, this.A = BigInt(a)) : (this.B = Oa, this.A = a); + 32 < a ? (this.B = Oa, this.A = BigInt(a)) : (this.B = Pa, this.A = a); } V.prototype.get = function(a) { const b = this.index[this.B(a)]; @@ -621,10 +625,10 @@ function W(a = 8) { if (!this || this.constructor !== W) { return new W(a); } - this.index = H(); + this.index = G(); this.h = []; this.size = 0; - 32 < a ? (this.B = Na, this.A = BigInt(a)) : (this.B = Oa, this.A = a); + 32 < a ? (this.B = Oa, this.A = BigInt(a)) : (this.B = Pa, this.A = a); } W.prototype.add = function(a) { var b = this.B(a); @@ -641,7 +645,7 @@ w.delete = W.prototype.delete = function(a) { b && b.delete(a) && this.size--; }; w.clear = W.prototype.clear = function() { - this.index = H(); + this.index = G(); this.h = []; this.size = 0; }; @@ -666,7 +670,7 @@ w.entries = W.prototype.entries = function*() { } } }; -function Oa(a) { +function Pa(a) { let b = 2 ** this.A - 1; if ("number" == typeof a) { return a & b; @@ -677,7 +681,7 @@ function Oa(a) { } return 32 === this.A ? c + 2 ** 31 : c; } -function Na(a) { +function Oa(a) { let b = BigInt(2) ** this.A - BigInt(1); var c = typeof a; if ("bigint" === c) { @@ -693,8 +697,8 @@ function Na(a) { } return c; } -;Pa.prototype.add = function(a, b, c) { - aa(a) && (b = a, a = ea(b, this.key)); +;Qa.prototype.add = function(a, b, c) { + da(a) && (b = a, a = fa(b, this.key)); if (b && (a || 0 === a)) { if (!c && this.reg.has(a)) { return this.update(a, b); @@ -707,7 +711,7 @@ function Na(a) { e && d.add(a, e, !1, !0); } else { if (e = k.I, !e || e(b)) { - k.constructor === String ? k = ["" + k] : M(k) && (k = [k]), Qa(b, k, this.J, 0, d, a, k[0], c); + k.constructor === String ? k = ["" + k] : M(k) && (k = [k]), Ra(b, k, this.J, 0, d, a, k[0], c); } } } @@ -715,7 +719,7 @@ function Na(a) { for (d = 0; d < this.D.length; d++) { var f = this.D[d], g = this.R[d]; e = this.tag.get(g); - let h = H(); + let h = G(); if ("function" === typeof f) { if (f = f(b), !f) { continue; @@ -726,7 +730,7 @@ function Na(a) { continue; } f.constructor === String && (f = "" + f); - f = ea(b, f); + f = fa(b, f); } if (e && f) { M(f) && (f = [f]); @@ -753,7 +757,7 @@ function Na(a) { if (this.store && (!c || !this.store.has(a))) { let h; if (this.C) { - h = H(); + h = G(); for (let k = 0, l; k < this.C.length; k++) { l = this.C[k]; if ((c = l.I) && !c(b)) { @@ -770,7 +774,7 @@ function Na(a) { h[l] = b[l]; continue; } - Ra(b, h, l, 0, l[0], m); + Sa(b, h, l, 0, l[0], m); } } this.store.set(a, h || b); @@ -779,21 +783,21 @@ function Na(a) { } return this; }; -function Ra(a, b, c, d, e, f) { +function Sa(a, b, c, d, e, f) { a = a[e]; if (d === c.length - 1) { b[e] = f || a; } else if (a) { if (a.constructor === Array) { for (b = b[e] = Array(a.length), e = 0; e < a.length; e++) { - Ra(a, b, c, d, e); + Sa(a, b, c, d, e); } } else { - b = b[e] || (b[e] = H()), e = c[++d], Ra(a, b, c, d, e); + b = b[e] || (b[e] = G()), e = c[++d], Sa(a, b, c, d, e); } } } -function Qa(a, b, c, d, e, f, g, h) { +function Ra(a, b, c, d, e, f, g, h) { if (a = a[g]) { if (d === b.length - 1) { if (a.constructor === Array) { @@ -809,17 +813,17 @@ function Qa(a, b, c, d, e, f, g, h) { } else { if (a.constructor === Array) { for (g = 0; g < a.length; g++) { - Qa(a, b, c, d, e, f, g, h); + Ra(a, b, c, d, e, f, g, h); } } else { - g = b[++d], Qa(a, b, c, d, e, f, g, h); + g = b[++d], Ra(a, b, c, d, e, f, g, h); } } } else { e.db && e.remove(f); } } -;function Sa(a, b, c, d) { +;function Ta(a, b, c, d) { if (!a.length) { return a; } @@ -850,7 +854,7 @@ function Qa(a, b, c, d, e, f, g, h) { e = 1 < e.length ? [].concat.apply([], e) : e[0]; return d ? X.call(this, e) : e; } -;function Ta(a, b, c) { +;function Ua(a, b, c) { var d = c[0]; if (d.then) { return Promise.all(c).then(function(q) { @@ -919,10 +923,10 @@ function Qa(a, b, c, d, e, f, g, h) { return {O:d, P:e, limit:f, offset:g, enrich:h, resolve:k, suggest:l, highlight:m, W:p}; } ;Y.prototype.or = function() { - const {O:a, P:b, limit:c, offset:d, enrich:e, resolve:f} = Ta(this, "or", arguments); - return Ua.call(this, a, b, c, d, e, f); + const {O:a, P:b, limit:c, offset:d, enrich:e, resolve:f} = Ua(this, "or", arguments); + return Va.call(this, a, b, c, d, e, f); }; -function Ua(a, b, c, d, e, f) { +function Va(a, b, c, d, e, f) { if (b.length) { const g = this; return Promise.all(b).then(function(h) { @@ -930,10 +934,10 @@ function Ua(a, b, c, d, e, f) { for (let k = 0, l; k < h.length; k++) { (l = h[k]).length && (a[k] = l); } - return Ua.call(g, a, [], c, d, e, f); + return Va.call(g, a, [], c, d, e, f); }); } - a.length && (this.result.length && a.push(this.result), 2 > a.length ? this.result = a[0] : (this.result = Va(a, c, d, !1, this.h), d = 0)); + a.length && (this.result.length && a.push(this.result), 2 > a.length ? this.result = a[0] : (this.result = Wa(a, c, d, !1, this.h), d = 0)); return f ? this.resolve(c, d, e) : this; } ;Y.prototype.and = function() { @@ -943,12 +947,12 @@ function Ua(a, b, c, d, e, f) { f && (a = !!f.suggest, e = f.resolve, b = f.limit, c = f.offset, d = f.enrich && e); } if (a) { - const {O:f, P:g, limit:h, offset:k, enrich:l, resolve:m, suggest:p} = Ta(this, "and", arguments); - return Wa.call(this, f, g, h, k, l, m, p); + const {O:f, P:g, limit:h, offset:k, enrich:l, resolve:m, suggest:p} = Ua(this, "and", arguments); + return Xa.call(this, f, g, h, k, l, m, p); } return e ? this.resolve(b, c, d) : this; }; -function Wa(a, b, c, d, e, f, g) { +function Xa(a, b, c, d, e, f, g) { if (b.length) { const h = this; return Promise.all(b).then(function(k) { @@ -956,15 +960,15 @@ function Wa(a, b, c, d, e, f, g) { for (let l = 0, m; l < k.length; l++) { (m = k[l]).length && (a[l] = m); } - return Wa.call(h, a, [], c, d, e, f, g); + return Xa.call(h, a, [], c, d, e, f, g); }); } if (a.length) { if (this.result.length && a.unshift(this.result), 2 > a.length) { this.result = a[0]; } else { - if (b = fa(a)) { - return this.result = Xa(a, b, c, d, g, this.h, f), f ? e ? X.call(this.index, this.result) : this.result : this; + if (b = ha(a)) { + return this.result = Ya(a, b, c, d, g, this.h, f), f ? e ? X.call(this.index, this.result) : this.result : this; } this.result = []; } @@ -974,10 +978,10 @@ function Wa(a, b, c, d, e, f, g) { return f ? this.resolve(c, d, e) : this; } ;Y.prototype.xor = function() { - const {O:a, P:b, limit:c, offset:d, enrich:e, resolve:f, suggest:g} = Ta(this, "xor", arguments); - return Ya.call(this, a, b, c, d, e, f, g); + const {O:a, P:b, limit:c, offset:d, enrich:e, resolve:f, suggest:g} = Ua(this, "xor", arguments); + return Za.call(this, a, b, c, d, e, f, g); }; -function Ya(a, b, c, d, e, f, g) { +function Za(a, b, c, d, e, f, g) { if (b.length) { const h = this; return Promise.all(b).then(function(k) { @@ -985,22 +989,22 @@ function Ya(a, b, c, d, e, f, g) { for (let l = 0, m; l < k.length; l++) { (m = k[l]).length && (a[l] = m); } - return Ya.call(h, a, [], c, d, e, f, g); + return Za.call(h, a, [], c, d, e, f, g); }); } if (a.length) { if (this.result.length && a.unshift(this.result), 2 > a.length) { this.result = a[0]; } else { - return this.result = Za.call(this, a, c, d, f, this.h), f ? e ? X.call(this.index, this.result) : this.result : this; + return this.result = $a.call(this, a, c, d, f, this.h), f ? e ? X.call(this.index, this.result) : this.result : this; } } else { g || (this.result = a); } return f ? this.resolve(c, d, e) : this; } -function Za(a, b, c, d, e) { - const f = [], g = H(); +function $a(a, b, c, d, e) { + const f = [], g = G(); let h = 0; for (let k = 0, l; k < a.length; k++) { if (l = a[k]) { @@ -1045,10 +1049,10 @@ function Za(a, b, c, d, e) { return f; } ;Y.prototype.not = function() { - const {O:a, P:b, limit:c, offset:d, enrich:e, resolve:f, suggest:g} = Ta(this, "not", arguments); - return $a.call(this, a, b, c, d, e, f, g); + const {O:a, P:b, limit:c, offset:d, enrich:e, resolve:f, suggest:g} = Ua(this, "not", arguments); + return ab.call(this, a, b, c, d, e, f, g); }; -function $a(a, b, c, d, e, f, g) { +function ab(a, b, c, d, e, f, g) { if (b.length) { const h = this; return Promise.all(b).then(function(k) { @@ -1056,17 +1060,17 @@ function $a(a, b, c, d, e, f, g) { for (let l = 0, m; l < k.length; l++) { (m = k[l]).length && (a[l] = m); } - return $a.call(h, a, [], c, d, e, f, g); + return ab.call(h, a, [], c, d, e, f, g); }); } if (a.length && this.result.length) { - this.result = ab.call(this, a, c, d, f); + this.result = bb.call(this, a, c, d, f); } else if (f) { return this.resolve(c, d, e); } return f ? e ? X.call(this.index, this.result) : this.result : this; } -function ab(a, b, c, d) { +function bb(a, b, c, d) { const e = []; a = new Set(a.flat().flat()); for (let f = 0, g, h = 0; f < this.result.length; f++) { @@ -1092,7 +1096,7 @@ function ab(a, b, c, d) { } return e; } -;function bb(a, b, c, d, e) { +;function cb(a, b, c, d, e) { let f, g, h; "string" === typeof e ? (f = e, e = "") : f = e.template; if (!f) { @@ -1118,28 +1122,28 @@ function ab(a, b, c, d) { let q, r; "object" === typeof k && (q = k.before, 0 === q && (q = -1), r = k.after, 0 === r && (r = -1), k = k.total || 9e5); p = new Map(); - for (let La = 0, ba, fb, na; La < b.length; La++) { - let oa; + for (let La = 0, ba, fb, oa; La < b.length; La++) { + let pa; if (d) { - oa = b, na = d; + pa = b, oa = d; } else { var n = b[La]; - na = n.field; - if (!na) { + oa = n.field; + if (!oa) { continue; } - oa = n.result; + pa = n.result; } - fb = c.get(na); + fb = c.get(oa); ba = fb.encoder; n = p.get(ba); "string" !== typeof n && (n = ba.encode(a), p.set(ba, n)); - for (let wa = 0; wa < oa.length; wa++) { - var t = oa[wa].doc; + for (let wa = 0; wa < pa.length; wa++) { + var t = pa[wa].doc; if (!t) { continue; } - t = ea(t, na); + t = fa(t, oa); if (!t) { continue; } @@ -1150,7 +1154,7 @@ function ab(a, b, c, d) { t = ""; var y = []; let xa = []; - var D = -1, G = -1, B = 0; + var D = -1, H = -1, B = 0; for (var v = 0; v < x.length; v++) { var A = x[v], I = ba.encode(A); I = 1 < I.length ? I.join(" ") : I[0]; @@ -1165,7 +1169,7 @@ function ab(a, b, c, d) { S && L <= S || (Q = I.indexOf(Q), -1 < Q && (F = (Q ? A.substring(0, Q) : "") + g + A.substring(Q, Q + L) + h + (Q + L < C ? A.substring(Q + L) : ""), S = L, z = !0)); } } - F && (k && (0 > D && (D = t.length + (t ? 1 : 0)), G = t.length + (t ? 1 : 0) + F.length, B += C, xa.push(y.length), y.push({match:F})), t += (t ? " " : "") + F); + F && (k && (0 > D && (D = t.length + (t ? 1 : 0)), H = t.length + (t ? 1 : 0) + F.length, B += C, xa.push(y.length), y.push({match:F})), t += (t ? " " : "") + F); } if (!z) { A = x[v], t += (t ? " " : "") + A, k && y.push({text:A}); @@ -1175,10 +1179,10 @@ function ab(a, b, c, d) { } B = xa.length * (f.length - 2); if (q || r || k && t.length - B > k) { - if (B = k + B - 2 * u, v = G - D, 0 < q && (v += q), 0 < r && (v += r), v <= B) { - x = q ? D - (0 < q ? q : 0) : D - ((B - v) / 2 | 0), y = r ? G + (0 < r ? r : 0) : x + B, l || (0 < x && " " !== t.charAt(x) && " " !== t.charAt(x - 1) && (x = t.indexOf(" ", x), 0 > x && (x = 0)), y < t.length && " " !== t.charAt(y - 1) && " " !== t.charAt(y) && (y = t.lastIndexOf(" ", y), y < G ? y = G : ++y)), t = (x ? e : "") + t.substring(x, y) + (y < t.length ? e : ""); + if (B = k + B - 2 * u, v = H - D, 0 < q && (v += q), 0 < r && (v += r), v <= B) { + x = q ? D - (0 < q ? q : 0) : D - ((B - v) / 2 | 0), y = r ? H + (0 < r ? r : 0) : x + B, l || (0 < x && " " !== t.charAt(x) && " " !== t.charAt(x - 1) && (x = t.indexOf(" ", x), 0 > x && (x = 0)), y < t.length && " " !== t.charAt(y - 1) && " " !== t.charAt(y) && (y = t.lastIndexOf(" ", y), y < H ? y = H : ++y)), t = (x ? e : "") + t.substring(x, y) + (y < t.length ? e : ""); } else { - G = []; + H = []; D = {}; B = {}; v = {}; @@ -1227,9 +1231,9 @@ function ab(a, b, c, d) { } } if (C + t.length + 1 <= k) { - t = " " + t, G[z] += t; + t = " " + t, H[z] += t; } else if (l) { - T = k - C - 1, 0 < T && (t = " " + t.substring(0, T), G[z] += t), v[z + 1] = 1; + T = k - C - 1, 0 < T && (t = " " + t.substring(0, T), H[z] += t), v[z + 1] = 1; } else { v[z + 1] = 1; continue; @@ -1271,9 +1275,9 @@ function ab(a, b, c, d) { } } if (C + t.length + 1 <= k) { - t += " ", G[z] = t + G[z]; + t += " ", H[z] = t + H[z]; } else if (l) { - T = t.length + 1 - (k - C), 0 <= T && T < t.length && (t = t.substring(T) + " ", G[z] = t + G[z]), v[z] = 1; + T = t.length + 1 - (k - C), 0 <= T && T < t.length && (t = t.substring(T) + " ", H[z] = t + H[z]), v[z] = 1; } else { v[z] = 1; continue; @@ -1289,7 +1293,7 @@ function ab(a, b, c, d) { K >= x.length - 1 ? Ma = 1 : K < y.length - 1 && y[K + 1].match ? Ma = 1 : u && (C += u); C -= f.length - 2; if (!z || C + t.length <= k) { - G[z] = t; + H[z] = t; } else { T = S = ca = B[z] = 0; break; @@ -1310,14 +1314,14 @@ function ab(a, b, c, d) { } } t = ""; - for (let z = 0, K; z < G.length; z++) { - K = (z && B[z] ? " " : (z && !e ? " " : "") + e) + G[z], t += K; + for (let z = 0, K; z < H.length; z++) { + K = (z && B[z] ? " " : (z && !e ? " " : "") + e) + H[z], t += K; } - e && !B[G.length] && (t += e); + e && !B[H.length] && (t += e); } } m && (t = t.replace(m, " ")); - oa[wa].highlight = t; + pa[wa].highlight = t; } if (d) { break; @@ -1375,13 +1379,13 @@ Y.prototype.resolve = function(a, b, c) { const d = this.index; let e = this.result; this.result = this.index = null; - e.length && ("object" === typeof a && (c = a.enrich, b = a.offset, a = a.limit), e = Sa.call(d, e, a || 100, b, c)); + e.length && ("object" === typeof a && (c = a.enrich, b = a.offset, a = a.limit), e = Ta.call(d, e, a || 100, b, c)); return e; }; -function Xa(a, b, c, d, e, f, g) { +function Ya(a, b, c, d, e, f, g) { const h = a.length; let k = [], l, m; - l = H(); + l = G(); for (let p = 0, u, q, r, n; p < b; p++) { for (let t = 0; t < h; t++) { if (r = a[t], p < r.length && (u = r[p])) { @@ -1403,7 +1407,7 @@ function Xa(a, b, c, d, e, f, g) { } if (a = k.length) { if (e) { - k = 1 < k.length ? Va(k, c, d, g, f) : (k = k[0]).length > c || d ? k.slice(d, c + d) : k; + k = 1 < k.length ? Wa(k, c, d, g, f) : (k = k[0]).length > c || d ? k.slice(d, c + d) : k; } else { if (a < h) { return []; @@ -1438,8 +1442,8 @@ function Xa(a, b, c, d, e, f, g) { } return k; } -function Va(a, b, c, d, e) { - const f = [], g = H(); +function Wa(a, b, c, d, e) { + const f = [], g = G(); let h; var k = a.length; let l; @@ -1483,8 +1487,8 @@ function Va(a, b, c, d, e) { } return f; } -function cb(a, b, c) { - const d = H(), e = []; +function db(a, b, c) { + const d = G(), e = []; for (let f = 0, g; f < b.length; f++) { g = b[f]; for (let h = 0; h < g.length; h++) { @@ -1504,9 +1508,9 @@ function cb(a, b, c) { } return e; } -;H(); -Pa.prototype.search = function(a, b, c, d) { - c || (!b && aa(a) ? (c = a, a = "") : aa(b) && (c = b, b = 0)); +;G(); +Qa.prototype.search = function(a, b, c, d) { + c || (!b && da(a) ? (c = a, a = "") : da(b) && (c = b, b = 0)); if (c && c.cache) { c.cache = !1; var e = this.searchCache(a, b, c); @@ -1579,7 +1583,7 @@ Pa.prototype.search = function(a, b, c, d) { } g.push(d = d.db.tag(x[n + 1], b, t, e)); } else { - d = db.call(this, x[n], x[n + 1], b, t, e); + d = eb.call(this, x[n], x[n + 1], b, t, e); } f.push(q ? {field:x[n], tag:x[n + 1], result:d} : [d]); } @@ -1590,10 +1594,10 @@ Pa.prototype.search = function(a, b, c, d) { for (let A = 0; A < v.length; A++) { q ? f[A].result = v[A] : f[A] = v[A]; } - return q ? f : new Y(1 < f.length ? Xa(f, 1, 0, 0, l, m) : f[0], B); + return q ? f : new Y(1 < f.length ? Ya(f, 1, 0, 0, l, m) : f[0], B); }); } - return q ? f : new Y(1 < f.length ? Xa(f, 1, 0, 0, l, m) : f[0], this); + return q ? f : new Y(1 < f.length ? Ya(f, 1, 0, 0, l, m) : f[0], this); } } if (!q && !h) { @@ -1607,7 +1611,7 @@ Pa.prototype.search = function(a, b, c, d) { p && p.constructor !== Array && (p = [p]); } p || (p = this.field); - let G; + let H; x = (this.worker || this.db) && !d && []; for (let B = 0, v, A, I; B < p.length; B++) { A = p[B]; @@ -1615,11 +1619,11 @@ Pa.prototype.search = function(a, b, c, d) { continue; } let C; - M(A) || (C = A, A = C.field, a = C.query || a, b = eb(C.limit, b), t = eb(C.offset, t), l = eb(C.suggest, l), r = q && this.store && eb(C.highlight, r), e = !!r || q && this.store && eb(C.enrich, e)); + M(A) || (C = A, A = C.field, a = C.query || a, b = aa(C.limit, b), t = aa(C.offset, t), l = aa(C.suggest, l), r = q && this.store && aa(C.highlight, r), e = !!r || q && this.store && aa(C.enrich, e)); if (d) { v = d[B]; } else { - if (y = C || c, D = this.index.get(A), n && (this.db && (y.tag = n, G = D.db.support_tag_search, y.field = p), G || (y.enrich = !1)), x) { + if (y = C || c, D = this.index.get(A), n && (this.db && (y.tag = n, H = D.db.support_tag_search, y.field = p), H || (y.enrich = !1)), x) { x[B] = D.search(a, b, y); y && e && (y.enrich = e); continue; @@ -1632,7 +1636,7 @@ Pa.prototype.search = function(a, b, c, d) { y = []; D = 0; if (this.db && d) { - if (!G) { + if (!H) { for (let J = p.length; J < d.length; J++) { let F = d[J]; if (F && F.length) { @@ -1660,7 +1664,7 @@ Pa.prototype.search = function(a, b, c, d) { } } if (D) { - v = cb(v, y, q); + v = db(v, y, q); I = v.length; if (!I && !l) { return q ? v : new Y(v, this); @@ -1675,7 +1679,7 @@ Pa.prototype.search = function(a, b, c, d) { } } if (x) { - if (this.db && n && n.length && !G) { + if (this.db && n && n.length && !H) { for (e = 0; e < n.length; e += 2) { g = this.index.get(n[e]); if (!g) { @@ -1704,7 +1708,7 @@ Pa.prototype.search = function(a, b, c, d) { n = f[t]; e && n.length && "undefined" === typeof n[0].doc && (this.db ? x.push(n = this.index.get(this.field[0]).db.enrich(n)) : n = X.call(this, n)); if (h) { - return q ? r ? bb(a, n, this.index, h, r) : n : new Y(n, this); + return q ? r ? cb(a, n, this.index, h, r) : n : new Y(n, this); } f[t] = {field:g[t], result:n}; } @@ -1714,37 +1718,44 @@ Pa.prototype.search = function(a, b, c, d) { for (let A = 0; A < v.length; A++) { f[A].result = v[A]; } - return k ? gb(f) : r ? bb(a, f, B.index, h, r) : f; + r && (f = cb(a, f, B.index, h, r)); + return k ? gb(f) : f; }); } - return k ? gb(f) : r ? bb(a, f, this.index, h, r) : f; + r && (f = cb(a, f, this.index, h, r)); + return k ? gb(f) : f; }; -function eb(a, b) { - return "undefined" === typeof a ? b : a; -} function gb(a) { - const b = [], c = H(); - for (let d = 0, e, f; d < a.length; d++) { - e = a[d]; - f = e.result; - for (let g = 0, h, k, l; g < f.length; g++) { - k = f[g], "object" !== typeof k && (k = {id:k}), h = k.id, (l = c[h]) ? l.push(e.field) : (k.field = c[h] = [e.field], b.push(k)); + const b = [], c = G(), d = G(); + for (let e = 0, f, g, h, k, l, m, p; e < a.length; e++) { + f = a[e]; + g = f.field; + h = f.result; + for (let u = 0; u < h.length; u++) { + if (l = h[u], "object" !== typeof l ? l = {id:k = l} : k = l.id, (m = c[k]) ? m.push(g) : (l.field = c[k] = [g], b.push(l)), p = l.highlight) { + m = d[k], m || (d[k] = m = {}, l.highlight = m), m[g] = p; + } } } return b; } -function db(a, b, c, d, e) { - let f = this.tag.get(a); - if (!f) { - return console.warn("Tag-Field '" + a + "' was not found"), []; +function eb(a, b, c, d, e) { + a = this.tag.get(a); + if (!a) { + return []; } - if ((a = (f = f && f.get(b)) && f.length - d) && 0 < a) { - if (c && a > c || d) { - f = f.slice(d, d + c); + a = a.get(b); + if (!a) { + return []; + } + b = a.length - d; + if (0 < b) { + if (c && b > c || d) { + a = a.slice(d, d + c); } - e && (f = X.call(this, f)); - return f; + e && (a = X.call(this, a)); } + return a; } function X(a) { if (!this || !this.store) { @@ -1770,9 +1781,9 @@ var nb = {Exact:hb, Default:ib, Normalize:ib, LatinBalance:{mapper:jb}, LatinAdv a[c] = d; } }}, CJK:{split:""}, LatinExact:hb, LatinDefault:ib, LatinSimple:ib}; -function Pa(a) { - if (!this || this.constructor !== Pa) { - return new Pa(a); +function Qa(a) { + if (!this || this.constructor !== Qa) { + return new Qa(a); } const b = a.document || a.doc || a; let c, d; @@ -1830,7 +1841,7 @@ function Pa(a) { a.db && (this.fastupdate = !1, this.mount(a.db)); } } -w = Pa.prototype; +w = Qa.prototype; w.mount = function(a) { if (this.worker) { throw Error("You can't use Worker-Indexes on a persistent model. That would be useless, since each of the persistent model acts like Worker-Index by default (Master/Slave)."); @@ -1884,11 +1895,11 @@ function qb(a, b) { for (let f = 0, g, h; f < d.length; f++) { g = d[f]; M(g) || (h = g, g = g.field); - h = aa(h) ? Object.assign({}, a, h) : a; + h = da(h) ? Object.assign({}, a, h) : a; if (this.worker) { var e = void 0; - e = (e = h.encoder) && e.encode ? e : new ma("string" === typeof e ? nb[e] : e); - e = new Aa(h, e); + e = (e = h.encoder) && e.encode ? e : new na("string" === typeof e ? nb[e] : e); + e = new Ba(h, e); c.set(g, e); } this.worker || c.set(g, new P(h, this.reg)); @@ -1920,7 +1931,7 @@ w.update = function(a, b) { return this.remove(a).add(a, b); }; w.remove = function(a) { - aa(a) && (a = ea(a, this.key)); + da(a) && (a = fa(a, this.key)); for (var b of this.index.values()) { b.remove(a, !0); } @@ -1970,7 +1981,7 @@ w.get = function(a) { }) : this.store.get(a) || null; }; w.set = function(a, b) { - "object" === typeof a && (b = a, a = ea(b, this.key)); + "object" === typeof a && (b = a, a = fa(b, this.key)); this.store.set(a, b); return this; }; @@ -1990,23 +2001,23 @@ w.export = function(a, b, c = 0, d = 0) { switch(d) { case 0: e = "reg"; - f = Ga(this.reg); + f = Ha(this.reg); b = null; break; case 1: e = "tag"; - f = this.tag && Ea(this.tag, this.reg.size); + f = this.tag && Fa(this.tag, this.reg.size); b = null; break; case 2: e = "doc"; - f = this.store && Ca(this.store); + f = this.store && Da(this.store); b = null; break; default: return; } - return Ia.call(this, a, b, e, f, c, d); + return Ja.call(this, a, b, e, f, c, d); }; w.import = function(a, b) { var c = a.split("."); @@ -2024,7 +2035,7 @@ w.import = function(a, b) { switch(c) { case "reg": this.fastupdate = !1; - this.reg = Ha(b, this.reg); + this.reg = Ia(b, this.reg); for (let e = 0, f; e < this.field.length; e++) { f = this.index.get(this.field[e]), f.fastupdate = !1, f.reg = this.reg; } @@ -2037,14 +2048,14 @@ w.import = function(a, b) { } break; case "tag": - this.tag = Fa(b, this.tag); + this.tag = Ga(b, this.tag); break; case "doc": - this.store = Da(b, this.store); + this.store = Ea(b, this.store); } } }; -ra(Pa.prototype); +sa(Qa.prototype); function rb(a, b, c) { const d = (b ? "" + a : "object" === typeof a ? "" + a.query : a).toLowerCase(); this.cache || (this.cache = new pb()); @@ -2146,7 +2157,7 @@ P.prototype.add = function(a, b, c, d) { b = this.encoder.encode(b, !d); const l = b.length; if (l) { - const m = H(), p = H(), u = this.resolution; + const m = G(), p = G(), u = this.resolution; for (let q = 0; q < l; q++) { let r = b[this.rtl ? l - 1 - q : q]; var e = r.length; @@ -2184,7 +2195,7 @@ P.prototype.add = function(a, b, c, d) { } default: if (wb(this, p, r, f, a, c), d && 1 < l && q < l - 1) { - for (e = H(), g = this.U, f = r, h = Math.min(d + 1, this.rtl ? q + 1 : l - q), e[f] = 1, k = 1; k < h; k++) { + for (e = G(), g = this.U, f = r, h = Math.min(d + 1, this.rtl ? q + 1 : l - q), e[f] = 1, k = 1; k < h; k++) { if ((r = b[this.rtl ? l - 1 - q - k : q + k]) && !e[r]) { e[r] = 1; const n = this.score ? this.score(b, f, q, r, k - 1) : vb(g + (l / 2 > g ? 0 : 1), l, q, h - 1, k - 1), t = this.bidirectional && r > f; @@ -2206,7 +2217,7 @@ P.prototype.add = function(a, b, c, d) { function wb(a, b, c, d, e, f, g) { let h = g ? a.ctx : a.map, k; if (!b[c] || g && !(k = b[c])[g]) { - if (g ? (b = k || (b[c] = H()), b[g] = 1, (k = h.get(g)) ? h = k : h.set(g, h = new Map())) : b[c] = 1, (k = h.get(c)) ? h = k : h.set(c, h = k = []), h = h[d] || (h[d] = []), !f || !h.includes(e)) { + if (g ? (b = k || (b[c] = G()), b[g] = 1, (k = h.get(g)) ? h = k : h.set(g, h = new Map())) : b[c] = 1, (k = h.get(c)) ? h = k : h.set(c, h = k = []), h = h[d] || (h[d] = []), !f || !h.includes(e)) { if (h.length === 2 ** 31 - 1) { b = new U(h); if (a.fastupdate) { @@ -2242,7 +2253,7 @@ function vb(a, b, c, d, e) { if (2 === e && f && !g) { return xb.call(this, q[1], q[0], b, h, k, u, l); } - let r = H(), n = 0, t; + let r = G(), n = 0, t; f && (t = q[0], n = 1); p || 0 === p || (p = t ? this.U : this.resolution); if (this.db) { @@ -2261,7 +2272,7 @@ function vb(a, b, c, d, e) { } t && (g && y && d.length || (t = D)); } - g && t && n === e - 1 && !d.length && (p = x.resolution, t = "", n = -1, r = H()); + g && t && n === e - 1 && !d.length && (p = x.resolution, t = "", n = -1, r = G()); } return Ab(d, p, b, h, g, m, k); }(); @@ -2276,16 +2287,16 @@ function vb(a, b, c, d, e) { } t && (g && x && d.length || (t = y)); } - g && t && n === e - 1 && !d.length && (p = this.resolution, t = "", n = -1, r = H()); + g && t && n === e - 1 && !d.length && (p = this.resolution, t = "", n = -1, r = G()); } return Ab(d, p, b, h, g, m, k); }; function Ab(a, b, c, d, e, f, g) { let h = a.length, k = a; if (1 < h) { - k = Xa(a, b, c, d, e, f, g); + k = Ya(a, b, c, d, e, f, g); } else if (1 === h) { - return g ? Sa.call(null, a[0], c, d) : new Y(a[0], this); + return g ? Ta.call(null, a[0], c, d) : new Y(a[0], this); } return g ? k : new Y(k, this); } @@ -2293,7 +2304,7 @@ function xb(a, b, c, d, e, f, g) { a = yb(this, a, b, c, d, e, f, g); return this.db ? a.then(function(h) { return e ? h || [] : new Y(h, this); - }) : a && a.length ? e ? Sa.call(this, a, c, d) : new Y(a, this) : e ? [] : new Y([], this); + }) : a && a.length ? e ? Ta.call(this, a, c, d) : new Y(a, this) : e ? [] : new Y([], this); } function zb(a, b, c, d) { let e = []; @@ -2337,7 +2348,7 @@ function yb(a, b, c, d, e, f, g, h) { } c = a.context; const d = !0 === c ? {depth:1} : c || {}, e = M(a.encoder) ? nb[a.encoder] : a.encode || a.encoder || {}; - this.encoder = e.encode ? e : "object" === typeof e ? new ma(e) : {encode:e}; + this.encoder = e.encode ? e : "object" === typeof e ? new na(e) : {encode:e}; this.resolution = a.resolution || 9; this.tokenize = c = (c = a.tokenize) && "default" !== c && "exact" !== c && c || "strict"; this.depth = "strict" === c && d.depth || 0; @@ -2412,7 +2423,7 @@ w.export = function(a, b, c = 0, d = 0) { switch(d) { case 0: e = "reg"; - f = Ga(this.reg); + f = Ha(this.reg); break; case 1: e = "cfg"; @@ -2420,29 +2431,29 @@ w.export = function(a, b, c = 0, d = 0) { break; case 2: e = "map"; - f = Ca(this.map, this.reg.size); + f = Da(this.map, this.reg.size); break; case 3: e = "ctx"; - f = Ea(this.ctx, this.reg.size); + f = Fa(this.ctx, this.reg.size); break; default: return; } - return Ia.call(this, a, b, e, f, c, d); + return Ja.call(this, a, b, e, f, c, d); }; w.import = function(a, b) { if (b) { switch("string" === typeof b && (b = JSON.parse(b)), a = a.split("."), "json" === a[a.length - 1] && a.pop(), 3 === a.length && a.shift(), a = 1 < a.length ? a[1] : a[0], a) { case "reg": this.fastupdate = !1; - this.reg = Ha(b, this.reg); + this.reg = Ia(b, this.reg); break; case "map": - this.map = Da(b, this.map); + this.map = Ea(b, this.map); break; case "ctx": - this.ctx = Fa(b, this.ctx); + this.ctx = Ga(b, this.ctx); } } }; @@ -2454,11 +2465,11 @@ w.serialize = function(a = !0) { f || (f = typeof e), b += (b ? "," : "") + ("string" === f ? '"' + e + '"' : e); } b = "index.reg=new Set([" + b + "]);"; - c = Ja(this.map, f); + c = Ka(this.map, f); c = "index.map=new Map([" + c + "]);"; for (const g of this.ctx.entries()) { e = g[0]; - let h = Ja(g[1], f); + let h = Ka(g[1], f); h = "new Map([" + h + "])"; h = '["' + e + '",' + h + "]"; d += (d ? "," : "") + h; @@ -2467,8 +2478,8 @@ w.serialize = function(a = !0) { } return a ? "function inject(index){" + b + c + d + "}" : b + c + d; }; -ra(P.prototype); -const Bb = "undefined" !== typeof window && (window.indexedDB || window.mozIndexedDB || window.webkitIndexedDB || window.msIndexedDB), Cb = ["map", "ctx", "tag", "reg", "cfg"], Db = H(); +sa(P.prototype); +const Bb = "undefined" !== typeof window && (window.indexedDB || window.mozIndexedDB || window.webkitIndexedDB || window.msIndexedDB), Cb = ["map", "ctx", "tag", "reg", "cfg"], Db = G(); function Eb(a, b = {}) { if (!this || this.constructor !== Eb) { return new Eb(a, b); @@ -2636,7 +2647,7 @@ w.commit = async function(a, b, c) { d[e] = f.del; } } - b || (c || (d = d.concat(da(a.reg))), d.length && await this.remove(d)); + b || (c || (d = d.concat(ea(a.reg))), d.length && await this.remove(d)); } a.reg.size && (await this.transaction("map", "readwrite", function(d) { for (const e of a.map) { @@ -2771,6 +2782,6 @@ function Z(a, b) { a = null; }); } -;export default {Index:P, Charset:nb, Encoder:ma, Document:Pa, Worker:Aa, Resolver:Y, IndexedDB:Eb, Language:{}}; +;export default {Index:P, Charset:nb, Encoder:na, Document:Qa, Worker:Ba, Resolver:Y, IndexedDB:Eb, Language:{}}; -export const Index=P;export const Charset=nb;export const Encoder=ma;export const Document=Pa;export const Worker=Aa;export const Resolver=Y;export const IndexedDB=Eb;export const Language={}; \ No newline at end of file +export const Index=P;export const Charset=nb;export const Encoder=na;export const Document=Qa;export const Worker=Ba;export const Resolver=Y;export const IndexedDB=Eb;export const Language={}; \ No newline at end of file diff --git a/dist/flexsearch.bundle.module.min.js b/dist/flexsearch.bundle.module.min.js index 8c78ef0..7f34743 100644 --- a/dist/flexsearch.bundle.module.min.js +++ b/dist/flexsearch.bundle.module.min.js @@ -1,91 +1,91 @@ /**! - * FlexSearch.js v0.8.164 (Bundle/Module) + * FlexSearch.js v0.8.165 (Bundle/Module) * Author and Copyright: Thomas Wilkerling * Licence: Apache-2.0 * Hosted by Nextapps GmbH * https://github.com/nextapps-de/flexsearch */ -var v;function E(a,b,c){const d=typeof c,e=typeof a;if("undefined"!==d){if("undefined"!==e){if(c){if("function"===e&&d===e)return function(h){return a(c(h))};b=a.constructor;if(b===c.constructor){if(b===Array)return c.concat(a);if(b===Map){var f=new Map(c);for(var g of a)f.set(g[0],g[1]);return f}if(b===Set){g=new Set(c);for(f of a.values())g.add(f);return g}}}return a}return c}return"undefined"===e?b:a}function H(){return Object.create(null)}function M(a){return"string"===typeof a} -function ca(a){return"object"===typeof a}function da(a){const b=[];for(const c of a.keys())b.push(c);return b}function ea(a,b){if(M(b))a=a[b];else for(let c=0;a&&c"a1a".split(c).length; -this.numeric=E(a.numeric,d)}else{try{this.split=E(this.split,ha)}catch(e){this.split=/\s+/}this.numeric=E(a.numeric,E(this.numeric,!0))}this.prepare=E(a.prepare,null,this.prepare);this.finalize=E(a.finalize,null,this.finalize);c=a.filter;this.filter="function"===typeof c?c:E(c&&new Set(c),null,this.filter);this.dedupe=E(a.dedupe,!0,this.dedupe);this.matcher=E((c=a.matcher)&&new Map(c),null,this.matcher);this.mapper=E((c=a.mapper)&&new Map(c),null,this.mapper);this.stemmer=E((c=a.stemmer)&&new Map(c), +this.numeric=E(a.numeric,d)}else{try{this.split=E(this.split,ia)}catch(e){this.split=/\s+/}this.numeric=E(a.numeric,E(this.numeric,!0))}this.prepare=E(a.prepare,null,this.prepare);this.finalize=E(a.finalize,null,this.finalize);c=a.filter;this.filter="function"===typeof c?c:E(c&&new Set(c),null,this.filter);this.dedupe=E(a.dedupe,!0,this.dedupe);this.matcher=E((c=a.matcher)&&new Map(c),null,this.matcher);this.mapper=E((c=a.mapper)&&new Map(c),null,this.mapper);this.stemmer=E((c=a.stemmer)&&new Map(c), null,this.stemmer);this.replacer=E(a.replacer,null,this.replacer);this.minlength=E(a.minlength,1,this.minlength);this.maxlength=E(a.maxlength,1024,this.maxlength);this.rtl=E(a.rtl,!1,this.rtl);if(this.cache=c=E(a.cache,!0,this.cache))this.H=null,this.S="number"===typeof c?c:2E5,this.B=new Map,this.G=new Map,this.L=this.K=128;this.h="";this.M=null;this.A="";this.N=null;if(this.matcher)for(const e of this.matcher.keys())this.h+=(this.h?"|":"")+e;if(this.stemmer)for(const e of this.stemmer.keys())this.A+= (this.A?"|":"")+e;return this};v.addStemmer=function(a,b){this.stemmer||(this.stemmer=new Map);this.stemmer.set(a,b);this.A+=(this.A?"|":"")+a;this.N=null;this.cache&&N(this);return this};v.addFilter=function(a){"function"===typeof a?this.filter=a:(this.filter||(this.filter=new Set),this.filter.add(a));this.cache&&N(this);return this}; v.addMapper=function(a,b){if("object"===typeof a)return this.addReplacer(a,b);if(1a.length&&(this.dedupe||this.mapper))return this.addMapper(a,b);this.matcher||(this.matcher=new Map);this.matcher.set(a,b);this.h+=(this.h?"|":"")+a;this.M=null;this.cache&&N(this);return this}; v.addReplacer=function(a,b){if("string"===typeof a)return this.addMatcher(a,b);this.replacer||(this.replacer=[]);this.replacer.push(a,b);this.cache&&N(this);return this}; -v.encode=function(a,b){if(this.cache&&a.length<=this.K)if(this.H){if(this.B.has(a))return this.B.get(a)}else this.H=setTimeout(N,50,this);this.normalize&&("function"===typeof this.normalize?a=this.normalize(a):a=la?a.normalize("NFKD").replace(la,"").toLowerCase():a.toLowerCase());this.prepare&&(a=this.prepare(a));this.numeric&&3this.maxlength)){if(b){if(e[m])continue;e[m]=1}else{if(f===m)continue;f=m}if(c)d.push(m);else if(!this.filter||("function"===typeof this.filter?this.filter(m):!this.filter.has(m))){if(this.cache&&m.length<=this.L)if(this.H){var k=this.G.get(m);if(k||""===k){k&&d.push(k);continue}}else this.H=setTimeout(N,50,this);if(this.stemmer){this.N||(this.N=new RegExp("(?!^)("+ +v.encode=function(a,b){if(this.cache&&a.length<=this.K)if(this.H){if(this.B.has(a))return this.B.get(a)}else this.H=setTimeout(N,50,this);this.normalize&&("function"===typeof this.normalize?a=this.normalize(a):a=ma?a.normalize("NFKD").replace(ma,"").toLowerCase():a.toLowerCase());this.prepare&&(a=this.prepare(a));this.numeric&&3this.maxlength)){if(b){if(e[m])continue;e[m]=1}else{if(f===m)continue;f=m}if(c)d.push(m);else if(!this.filter||("function"===typeof this.filter?this.filter(m):!this.filter.has(m))){if(this.cache&&m.length<=this.L)if(this.H){var k=this.G.get(m);if(k||""===k){k&&d.push(k);continue}}else this.H=setTimeout(N,50,this);if(this.stemmer){this.N||(this.N=new RegExp("(?!^)("+ this.A+")$"));let u;for(;u!==m&&2this.stemmer.get(r))}if(m&&(this.mapper||this.dedupe&&1this.matcher.get(u)));if(m&&this.replacer)for(k=0;m&&kthis.S&&(this.G.clear(),this.L=this.L/1.1|0));if(m){if(m!==n)if(b){if(e[m])continue;e[m]=1}else{if(g===m)continue;g=m}d.push(m)}}}this.finalize&&(d=this.finalize(d)||d);this.cache&&a.length<=this.K&&(this.B.set(a,d),this.B.size>this.S&&(this.B.clear(),this.K=this.K/1.1|0));return d};function N(a){a.H=null;a.B.clear();a.G.clear()};let pa,qa;async function ra(a){a=a.data;var b=a.task;const c=a.id;let d=a.args;switch(b){case "init":qa=a.options||{};(b=a.factory)?(Function("return "+b)()(self),pa=new self.FlexSearch.Index(qa),delete self.FlexSearch):pa=new O(qa);postMessage({id:c});break;default:let e;"export"===b&&(d[1]?(d[0]=qa.export,d[2]=0,d[3]=1):d=null);"import"===b?d[0]&&(a=await qa.import.call(pa,d[0]),pa.import(d[0],a)):(e=d&&pa[b].apply(pa,d))&&e.then&&(e=await e);postMessage("search"===b?{id:c,msg:e}:{id:c})}};function sa(a){ta.call(a,"add");ta.call(a,"append");ta.call(a,"search");ta.call(a,"update");ta.call(a,"remove");ta.call(a,"searchCache")}let ua,va,ya;function za(){ua=ya=0} -function ta(a){this[a+"Async"]=function(){const b=arguments;var c=b[b.length-1];let d;"function"===typeof c&&(d=c,delete b[b.length-1]);ua?ya||(ya=Date.now()-va>=this.priority*this.priority*3):(ua=setTimeout(za,0),va=Date.now());if(ya){const f=this;return new Promise(g=>{setTimeout(function(){g(f[a+"Async"].apply(f,b))},0)})}const e=this[a].apply(this,b);c=e.then?e:new Promise(f=>f(e));d&&c.then(d);return c}};let Aa=0; -function Ba(a={},b){function c(h){function k(l){l=l.data||l;const m=l.id,n=m&&f.h[m];n&&(n(l.msg),delete f.h[m])}this.worker=h;this.h=H();if(this.worker){e?this.worker.on("message",k):this.worker.onmessage=k;if(a.config)return new Promise(function(l){f.h[++Aa]=function(){l(f);1E9=g.length)b-=g.length;else{b=g[d?"splice":"slice"](b,c);const h=b.length;if(h&&(e=e.length?e.concat(b):b,c-=h,d&&(a.length-=h),!c))break;b=0}return e} +this.replacer[k+1]);this.cache&&n.length<=this.L&&(this.G.set(n,m),this.G.size>this.S&&(this.G.clear(),this.L=this.L/1.1|0));if(m){if(m!==n)if(b){if(e[m])continue;e[m]=1}else{if(g===m)continue;g=m}d.push(m)}}}this.finalize&&(d=this.finalize(d)||d);this.cache&&a.length<=this.K&&(this.B.set(a,d),this.B.size>this.S&&(this.B.clear(),this.K=this.K/1.1|0));return d};function N(a){a.H=null;a.B.clear();a.G.clear()};let qa,ra;async function sa(a){a=a.data;var b=a.task;const c=a.id;let d=a.args;switch(b){case "init":ra=a.options||{};(b=a.factory)?(Function("return "+b)()(self),qa=new self.FlexSearch.Index(ra),delete self.FlexSearch):qa=new O(ra);postMessage({id:c});break;default:let e;"export"===b&&(d[1]?(d[0]=ra.export,d[2]=0,d[3]=1):d=null);"import"===b?d[0]&&(a=await ra.import.call(qa,d[0]),qa.import(d[0],a)):(e=d&&qa[b].apply(qa,d))&&e.then&&(e=await e);postMessage("search"===b?{id:c,msg:e}:{id:c})}};function ta(a){ua.call(a,"add");ua.call(a,"append");ua.call(a,"search");ua.call(a,"update");ua.call(a,"remove");ua.call(a,"searchCache")}let va,ya,za;function Aa(){va=za=0} +function ua(a){this[a+"Async"]=function(){const b=arguments;var c=b[b.length-1];let d;"function"===typeof c&&(d=c,delete b[b.length-1]);va?za||(za=Date.now()-ya>=this.priority*this.priority*3):(va=setTimeout(Aa,0),ya=Date.now());if(za){const f=this;return new Promise(g=>{setTimeout(function(){g(f[a+"Async"].apply(f,b))},0)})}const e=this[a].apply(this,b);c=e.then?e:new Promise(f=>f(e));d&&c.then(d);return c}};let Ba=0; +function Ca(a={},b){function c(h){function k(l){l=l.data||l;const m=l.id,n=m&&f.h[m];n&&(n(l.msg),delete f.h[m])}this.worker=h;this.h=G();if(this.worker){e?this.worker.on("message",k):this.worker.onmessage=k;if(a.config)return new Promise(function(l){f.h[++Ba]=function(){l(f);1E9=g.length)b-=g.length;else{b=g[d?"splice":"slice"](b,c);const h=b.length;if(h&&(e=e.length?e.concat(b):b,c-=h,d&&(a.length-=h),!c))break;b=0}return e} function R(a){if(!this||this.constructor!==R)return new R(a);this.index=a?[a]:[];this.length=a?a.length:0;const b=this;return new Proxy([],{get(c,d){if("length"===d)return b.length;if("push"===d)return function(e){b.index[b.index.length-1].push(e);b.length++};if("pop"===d)return function(){if(b.length)return b.length--,b.index[b.index.length-1].pop()};if("indexOf"===d)return function(e){let f=0;for(let g=0,h,k;gb?b?a.slice(c,c+b):a.slice(c):a,d?X.call(this,a):a;let e=[];for(let f=0,g,h;f=h){c-=h;continue}cb&&(g=g.slice(0,b),h=b);if(!e.length&&h>=b)return d?X.call(this,g):g;e.push(g);b-=h;if(!b)break}e=1a.length?this.result=a[0]:(this.result=Va(a,c,d,!1,this.h),d=0));return f?this.resolve(c,d,e):this};Y.prototype.and=function(){let a=this.result.length,b,c,d,e;if(!a){const f=arguments[0];f&&(a=!!f.suggest,e=f.resolve,b=f.limit,c=f.offset,d=f.enrich&&e)}if(a){const {O:f,P:g,limit:h,offset:k,enrich:l,resolve:m,suggest:n}=Ta(this,"and",arguments);return Wa.call(this,f,g,h,k,l,m,n)}return e?this.resolve(b,c,d):this}; -function Wa(a,b,c,d,e,f,g){if(b.length){const h=this;return Promise.all(b).then(function(k){a=[];for(let l=0,m;la.length)this.result=a[0];else{if(b=fa(a))return this.result=Xa(a,b,c,d,g,this.h,f),f?e?X.call(this.index,this.result):this.result:this;this.result=[]}else g||(this.result=a);return f?this.resolve(c,d,e):this};Y.prototype.xor=function(){const {O:a,P:b,limit:c,offset:d,enrich:e,resolve:f,suggest:g}=Ta(this,"xor",arguments);return Ya.call(this,a,b,c,d,e,f,g)}; -function Ya(a,b,c,d,e,f,g){if(b.length){const h=this;return Promise.all(b).then(function(k){a=[];for(let l=0,m;la.length)this.result=a[0];else return this.result=Za.call(this,a,c,d,f,this.h),f?e?X.call(this.index,this.result):this.result:this;else g||(this.result=a);return f?this.resolve(c,d,e):this} -function Za(a,b,c,d,e){const f=[],g=H();let h=0;for(let k=0,l;kD&&(D=t.length+(t?1:0)),G=t.length+(t?1:0)+F.length,B+=C,xa.push(w.length),w.push({match:F})),t+=(t?" ":"")+F)}if(!z)A=y[x],t+=(t?" ":"")+A,k&&w.push({text:A});else if(k&&B>=k)break}B=xa.length*(f.length-2);if(r||p||k&&t.length-B>k)if(B=k+B-2*u,x=G-D, -0y&&(y=0)),w=w.length-1){if(J>= -w.length){x[z+1]=1;J>=y.length&&(B[z+1]=1);continue}C-=u}t=w[J].text;if(K=p&&I[z])if(0K)if(x[z+1]=1,l)t=t.substring(0,K);else continue;(K-=t.length)||(K=-1);I[z]=K}else{x[z+1]=1;continue}if(C+t.length+1<=k)t=" "+t,G[z]+=t;else if(l)T=k-C-1,0=J){if(0>J){x[z]=1;B[z]=1;continue}C-=u}t=w[J].text;if(K=r&&A[z])if(0K)if(x[z]=1,l)t=t.substring(t.length- -K);else continue;(K-=t.length)||(K=-1);A[z]=K}else{x[z]=1;continue}if(C+t.length+1<=k)t+=" ",G[z]=t+G[z];else if(l)T=t.length+1-(k-C),0<=T&&T=y.length-1?Ma=1:Jc||d?k.slice(d,c+d):k;else{if(ac||d)k=k.slice(d,c+d)}else{e= +if("includes"===d)return function(e){for(let f=0;fb?b?a.slice(c,c+b):a.slice(c):a,d?X.call(this,a):a;let e=[];for(let f=0,g,h;f=h){c-=h;continue}cb&&(g=g.slice(0,b),h=b);if(!e.length&&h>=b)return d?X.call(this,g):g;e.push(g);b-=h;if(!b)break}e=1a.length?this.result=a[0]:(this.result=Wa(a,c,d,!1,this.h),d=0));return f?this.resolve(c,d,e):this};Y.prototype.and=function(){let a=this.result.length,b,c,d,e;if(!a){const f=arguments[0];f&&(a=!!f.suggest,e=f.resolve,b=f.limit,c=f.offset,d=f.enrich&&e)}if(a){const {O:f,P:g,limit:h,offset:k,enrich:l,resolve:m,suggest:n}=Ua(this,"and",arguments);return Xa.call(this,f,g,h,k,l,m,n)}return e?this.resolve(b,c,d):this}; +function Xa(a,b,c,d,e,f,g){if(b.length){const h=this;return Promise.all(b).then(function(k){a=[];for(let l=0,m;la.length)this.result=a[0];else{if(b=ha(a))return this.result=Ya(a,b,c,d,g,this.h,f),f?e?X.call(this.index,this.result):this.result:this;this.result=[]}else g||(this.result=a);return f?this.resolve(c,d,e):this};Y.prototype.xor=function(){const {O:a,P:b,limit:c,offset:d,enrich:e,resolve:f,suggest:g}=Ua(this,"xor",arguments);return Za.call(this,a,b,c,d,e,f,g)}; +function Za(a,b,c,d,e,f,g){if(b.length){const h=this;return Promise.all(b).then(function(k){a=[];for(let l=0,m;la.length)this.result=a[0];else return this.result=$a.call(this,a,c,d,f,this.h),f?e?X.call(this.index,this.result):this.result:this;else g||(this.result=a);return f?this.resolve(c,d,e):this} +function $a(a,b,c,d,e){const f=[],g=G();let h=0;for(let k=0,l;kD&&(D=t.length+(t?1:0)),H=t.length+(t?1:0)+F.length,B+=C,xa.push(w.length),w.push({match:F})),t+=(t?" ":"")+F)}if(!z)A=y[x],t+=(t?" ":"")+A,k&&w.push({text:A});else if(k&&B>=k)break}B=xa.length*(f.length-2);if(r||p||k&&t.length-B>k)if(B=k+B-2*u,x=H-D, +0y&&(y=0)),w=w.length-1){if(J>= +w.length){x[z+1]=1;J>=y.length&&(B[z+1]=1);continue}C-=u}t=w[J].text;if(K=p&&I[z])if(0K)if(x[z+1]=1,l)t=t.substring(0,K);else continue;(K-=t.length)||(K=-1);I[z]=K}else{x[z+1]=1;continue}if(C+t.length+1<=k)t=" "+t,H[z]+=t;else if(l)T=k-C-1,0=J){if(0>J){x[z]=1;B[z]=1;continue}C-=u}t=w[J].text;if(K=r&&A[z])if(0K)if(x[z]=1,l)t=t.substring(t.length- +K);else continue;(K-=t.length)||(K=-1);A[z]=K}else{x[z]=1;continue}if(C+t.length+1<=k)t+=" ",H[z]=t+H[z];else if(l)T=t.length+1-(k-C),0<=T&&T=y.length-1?Ma=1:Jc||d?k.slice(d,c+d):k;else{if(ac||d)k=k.slice(d,c+d)}else{e= [];for(let n=0,u;nd)d-=u.length;else{if(c&&u.length>c||d)u=u.slice(d,c+d),c-=u.length,d&&(d-=u.length);e.push(u);if(!c)break}k=e}}return k} -function Va(a,b,c,d,e){const f=[],g=H();let h;var k=a.length;let l;if(d)for(e=k-1;0<=e;e--){if(l=(d=a[e])&&d.length)for(k=0;kc||d)a=a.slice(d,d+c);e&&(a=X.call(this,a));return a}} +function Wa(a,b,c,d,e){const f=[],g=G();let h;var k=a.length;let l;if(d)for(e=k-1;0<=e;e--){if(l=(d=a[e])&&d.length)for(k=0;kc||d)a=a.slice(d,d+c);e&&(a=X.call(this,a))}return a} function X(a){if(!this||!this.store)return a;const b=Array(a.length);for(let c=0,d;cthis.limit&&this.cache.delete(this.cache.keys().next().value)}; +v.get=function(a){return this.db?this.index.get(this.field[0]).db.enrich(a).then(function(b){return b[0]&&b[0].doc||null}):this.store.get(a)||null};v.set=function(a,b){"object"===typeof a&&(b=a,a=fa(b,this.key));this.store.set(a,b);return this};v.searchCache=rb; +v.export=function(a,b,c=0,d=0){if(cthis.limit&&this.cache.delete(this.cache.keys().next().value)}; pb.prototype.get=function(a){const b=this.cache.get(a);b&&this.h!==a&&(this.cache.delete(a),this.cache.set(this.h=a,b));return b};pb.prototype.remove=function(a){for(const b of this.cache){const c=b[0];b[1].includes(a)&&this.cache.delete(c)}};pb.prototype.clear=function(){this.cache.clear();this.h=""};O.prototype.remove=function(a,b){const c=this.reg.size&&(this.fastupdate?this.reg.get(a):this.reg.has(a));if(c){if(this.fastupdate)for(let d=0,e;de.length)e.pop();else{const f=e.indexOf(a);f===c.length-1?e.pop():e.splice(f,1)}}else sb(this.map,a),this.depth&&sb(this.ctx,a);b||this.reg.delete(a)}this.db&&(this.commit_task.push({del:a}),this.T&&tb(this));this.cache&&this.cache.remove(a);return this}; -function sb(a,b){let c=0;var d="undefined"===typeof b;if(a.constructor===Array)for(let e=0,f,g;eq;f--){g=p.substring(q,f);t=this.rtl?e-1-q:q;var h=this.score?this.score(b,p,r,g,t):vb(u, -l,r,e,t);wb(this,n,g,h,a,c)}break}case "bidirectional":case "reverse":if(1q;f--){g=p.substring(q,f);t=this.rtl?e-1-q:q;var h=this.score?this.score(b,p,r,g,t):vb(u, +l,r,e,t);wb(this,n,g,h,a,c)}break}case "bidirectional":case "reverse":if(1g?0:1),l,r,h-1,k-1),t=this.bidirectional&&p>f;wb(this,m,t?f:p,q,a,c,t?p:f)}}}}this.fastupdate||this.reg.add(a)}else b=""}this.db&&(b||this.commit_task.push({del:a}),this.T&&tb(this));return this}; -function wb(a,b,c,d,e,f,g){let h=g?a.ctx:a.map,k;if(!b[c]||g&&!(k=b[c])[g])if(g?(b=k||(b[c]=H()),b[g]=1,(k=h.get(g))?h=k:h.set(g,h=new Map)):b[c]=1,(k=h.get(c))?h=k:h.set(c,h=k=[]),h=h[d]||(h[d]=[]),!f||!h.includes(e)){if(h.length===2**31-1){b=new R(h);if(a.fastupdate)for(let l of a.reg.values())l.includes(h)&&(l[l.indexOf(h)]=b);k[d]=h=b}h.push(e);a.fastupdate&&((d=a.reg.get(e))?d.push(h):a.reg.set(e,[h]))}} +function wb(a,b,c,d,e,f,g){let h=g?a.ctx:a.map,k;if(!b[c]||g&&!(k=b[c])[g])if(g?(b=k||(b[c]=G()),b[g]=1,(k=h.get(g))?h=k:h.set(g,h=new Map)):b[c]=1,(k=h.get(c))?h=k:h.set(c,h=k=[]),h=h[d]||(h[d]=[]),!f||!h.includes(e)){if(h.length===2**31-1){b=new R(h);if(a.fastupdate)for(let l of a.reg.values())l.includes(h)&&(l[l.indexOf(h)]=b);k[d]=h=b}h.push(e);a.fastupdate&&((d=a.reg.get(e))?d.push(h):a.reg.set(e,[h]))}} function vb(a,b,c,d,e){return c&&1c)&&(k=c,c=b,b=k);if(a.db)return a.db.get(b,c,d,e,f,g,h);a=c?(a=a.ctx.get(c))&&a.get(b):a.map.get(b);return a};function O(a,b){if(!this||this.constructor!==O)return new O(a);if(a){var c=M(a)?a:a.preset;c&&(a=Object.assign({},ub[c],a))}else a={};c=a.context;const d=!0===c?{depth:1}:c||{},e=M(a.encoder)?nb[a.encoder]:a.encode||a.encoder||{};this.encoder=e.encode?e:"object"===typeof e?new ma(e):{encode:e};this.resolution=a.resolution||9;this.tokenize=c=(c=a.tokenize)&&"default"!==c&&"exact"!==c&&c||"strict";this.depth="strict"===c&&d.depth||0;this.bidirectional=!1!==d.bidirectional;this.fastupdate=!!a.fastupdate; +h,k,u,l);if(2===e&&f&&!g)return xb.call(this,r[1],r[0],b,h,k,u,l);let p=G(),q=0,t;f&&(t=r[0],q=1);n||0===n||(n=t?this.U:this.resolution);if(this.db){if(this.db.search&&(c=this.db.search(this,r,b,h,g,k,u,l),!1!==c))return c;const y=this;return async function(){for(let w,D;qc)&&(k=c,c=b,b=k);if(a.db)return a.db.get(b,c,d,e,f,g,h);a=c?(a=a.ctx.get(c))&&a.get(b):a.map.get(b);return a};function O(a,b){if(!this||this.constructor!==O)return new O(a);if(a){var c=M(a)?a:a.preset;c&&(a=Object.assign({},ub[c],a))}else a={};c=a.context;const d=!0===c?{depth:1}:c||{},e=M(a.encoder)?nb[a.encoder]:a.encode||a.encoder||{};this.encoder=e.encode?e:"object"===typeof e?new na(e):{encode:e};this.resolution=a.resolution||9;this.tokenize=c=(c=a.tokenize)&&"default"!==c&&"exact"!==c&&c||"strict";this.depth="strict"===c&&d.depth||0;this.bidirectional=!1!==d.bidirectional;this.fastupdate=!!a.fastupdate; this.score=a.score||null;(c=a.keystore||0)&&(this.keystore=c);this.map=c?new U(c):new Map;this.ctx=c?new U(c):new Map;this.reg=b||(this.fastupdate?c?new U(c):new Map:c?new V(c):new Set);this.U=d.resolution||3;this.rtl=e.rtl||a.rtl||!1;this.cache=(c=a.cache||null)&&new pb(c);this.resolve=!1!==a.resolve;if(c=a.db)this.db=this.mount(c);this.T=!1!==a.commit;this.commit_task=[];this.commit_timer=null;this.priority=a.priority||4}v=O.prototype; v.mount=function(a){this.commit_timer&&(clearTimeout(this.commit_timer),this.commit_timer=null);return a.mount(this)};v.commit=function(a,b){this.commit_timer&&(clearTimeout(this.commit_timer),this.commit_timer=null);return this.db.commit(this,a,b)};v.destroy=function(){this.commit_timer&&(clearTimeout(this.commit_timer),this.commit_timer=null);return this.db.destroy()};function tb(a){a.commit_timer||(a.commit_timer=setTimeout(function(){a.commit_timer=null;a.db.commit(a,void 0,void 0)},1))} v.clear=function(){this.map.clear();this.ctx.clear();this.reg.clear();this.cache&&this.cache.clear();this.db&&(this.commit_timer&&clearTimeout(this.commit_timer),this.commit_timer=null,this.commit_task=[{clear:!0}]);return this};v.append=function(a,b){return this.add(a,b,!0)};v.contain=function(a){return this.db?this.db.has(a):this.reg.has(a)};v.update=function(a,b){const c=this,d=this.remove(a);return d&&d.then?d.then(()=>c.add(a,b)):this.add(a,b)}; -v.cleanup=function(){if(!this.fastupdate)return this;sb(this.map);this.depth&&sb(this.ctx);return this};v.searchCache=rb;v.export=function(a,b,c=0,d=0){let e,f;switch(d){case 0:e="reg";f=Ha(this.reg);break;case 1:e="cfg";f=null;break;case 2:e="map";f=Da(this.map,this.reg.size);break;case 3:e="ctx";f=Fa(this.ctx,this.reg.size);break;default:return}return Ja.call(this,a,b,e,f,c,d)}; -v.import=function(a,b){if(b)switch("string"===typeof b&&(b=JSON.parse(b)),a=a.split("."),"json"===a[a.length-1]&&a.pop(),3===a.length&&a.shift(),a=1=f.length)return[];if(!b&&!c)return f;f=f.slice(c,c+b);return d?e.enrich(f):f})}; v.enrich=function(a){"object"!==typeof a&&(a=[a]);const b=this.db.transaction("reg","readonly").objectStore("reg"),c=[];for(let d=0;d{a.onsuccess=a.oncomplete=function(){b&&b(this.result);b=null;c(this.result)};a.onerror=a.onblocked=d;a=null})};export default {Index:O,Charset:nb,Encoder:ma,Document:W,Worker:Ba,Resolver:Y,IndexedDB:Eb,Language:{}}; -export const Index=O;export const Charset=nb;export const Encoder=ma;export const Document=W;export const Worker=Ba;export const Resolver=Y;export const IndexedDB=Eb;export const Language={}; \ No newline at end of file +function Z(a,b){return new Promise((c,d)=>{a.onsuccess=a.oncomplete=function(){b&&b(this.result);b=null;c(this.result)};a.onerror=a.onblocked=d;a=null})};export default {Index:O,Charset:nb,Encoder:na,Document:W,Worker:Ca,Resolver:Y,IndexedDB:Eb,Language:{}}; +export const Index=O;export const Charset=nb;export const Encoder=na;export const Document=W;export const Worker=Ca;export const Resolver=Y;export const IndexedDB=Eb;export const Language={}; \ No newline at end of file diff --git a/dist/flexsearch.compact.debug.js b/dist/flexsearch.compact.debug.js index 6779365..fe80d4e 100644 --- a/dist/flexsearch.compact.debug.js +++ b/dist/flexsearch.compact.debug.js @@ -1,5 +1,5 @@ /**! - * FlexSearch.js v0.8.164 (Bundle/Debug) + * FlexSearch.js v0.8.165 (Bundle/Debug) * Author and Copyright: Thomas Wilkerling * Licence: Apache-2.0 * Hosted by Nextapps GmbH @@ -8,11 +8,11 @@ (function(self){'use strict'; var B; function I(a, c, b) { - const f = typeof b, d = typeof a; - if ("undefined" !== f) { + const e = typeof b, d = typeof a; + if ("undefined" !== e) { if ("undefined" !== d) { if (b) { - if ("function" === d && f === d) { + if ("function" === d && e === d) { return function(k) { return a(b(k)); }; @@ -23,16 +23,16 @@ function I(a, c, b) { return b.concat(a); } if (c === Map) { - var e = new Map(b); + var f = new Map(b); for (var g of a) { - e.set(g[0], g[1]); + f.set(g[0], g[1]); } - return e; + return f; } if (c === Set) { g = new Set(b); - for (e of a.values()) { - g.add(e); + for (f of a.values()) { + g.add(f); } return g; } @@ -44,17 +44,20 @@ function I(a, c, b) { } return "undefined" === d ? c : a; } -function J() { +function J(a, c) { + return "undefined" === typeof a ? c : a; +} +function L() { return Object.create(null); } -function L(a) { +function P(a) { return "string" === typeof a; } -function P(a) { +function R(a) { return "object" === typeof a; } -function R(a, c) { - if (L(c)) { +function S(a, c) { + if (P(c)) { a = a[c]; } else { for (let b = 0; a && b < c.length; b++) { @@ -63,10 +66,10 @@ function R(a, c) { } return a; } -;const ca = /[^\p{L}\p{N}]+/u, da = /(\d{3})/g, ea = /(\D)(\d{3})/g, fa = /(\d{3})(\D)/g, ha = /[\u0300-\u036f]/g; -function S(a = {}) { - if (!this || this.constructor !== S) { - return new S(...arguments); +;const aa = /[^\p{L}\p{N}]+/u, da = /(\d{3})/g, ea = /(\D)(\d{3})/g, fa = /(\d{3})(\D)/g, ha = /[\u0300-\u036f]/g; +function ka(a = {}) { + if (!this || this.constructor !== ka) { + return new ka(...arguments); } if (arguments.length) { for (a = 0; a < arguments.length; a++) { @@ -76,17 +79,17 @@ function S(a = {}) { this.assign(a); } } -B = S.prototype; +B = ka.prototype; B.assign = function(a) { this.normalize = I(a.normalize, !0, this.normalize); - let c = a.include, b = c || a.exclude || a.split, f; + let c = a.include, b = c || a.exclude || a.split, e; if (b || "" === b) { if ("object" === typeof b && b.constructor !== RegExp) { let d = ""; - f = !c; + e = !c; c || (d += "\\p{Z}"); b.letter && (d += "\\p{L}"); - b.number && (d += "\\p{N}", f = !!c); + b.number && (d += "\\p{N}", e = !!c); b.symbol && (d += "\\p{S}"); b.punctuation && (d += "\\p{P}"); b.control && (d += "\\p{C}"); @@ -95,16 +98,16 @@ B.assign = function(a) { } try { this.split = new RegExp("[" + (c ? "^" : "") + d + "]+", "u"); - } catch (e) { + } catch (f) { console.error("Your split configuration:", b, "is not supported on this platform. It falls back to using simple whitespace splitter instead: /s+/."), this.split = /\s+/; } } else { - this.split = b, f = !1 === b || 2 > "a1a".split(b).length; + this.split = b, e = !1 === b || 2 > "a1a".split(b).length; } - this.numeric = I(a.numeric, f); + this.numeric = I(a.numeric, e); } else { try { - this.split = I(this.split, ca); + this.split = I(this.split, aa); } catch (d) { console.warn("This platform does not support unicode regex. It falls back to using simple whitespace splitter instead: /s+/."), this.split = /\s+/; } @@ -203,7 +206,7 @@ B.encode = function(a, c) { this.prepare && (a = this.prepare(a)); this.numeric && 3 < a.length && (a = a.replace(ea, "$1 $2").replace(fa, "$1 $2").replace(da, "$1 ")); const b = !(this.dedupe || this.mapper || this.filter || this.matcher || this.stemmer || this.replacer); - let f = [], d = J(), e, g, k = this.split || "" === this.split ? a.split(this.split) : [a]; + let e = [], d = L(), f, g, k = this.split || "" === this.split ? a.split(this.split) : [a]; for (let m = 0, n, z; m < k.length; m++) { if ((n = z = k[m]) && !(n.length < this.minlength || n.length > this.maxlength)) { if (c) { @@ -212,20 +215,20 @@ B.encode = function(a, c) { } d[n] = 1; } else { - if (e === n) { + if (f === n) { continue; } - e = n; + f = n; } if (b) { - f.push(n); + e.push(n); } else { if (!this.filter || ("function" === typeof this.filter ? this.filter(n) : !this.filter.has(n))) { if (this.cache && n.length <= this.L) { if (this.H) { var h = this.G.get(n); if (h || "" === h) { - h && f.push(h); + h && e.push(h); continue; } } else { @@ -236,13 +239,13 @@ B.encode = function(a, c) { this.N || (this.N = new RegExp("(?!^)(" + this.C + ")$")); let x; for (; x !== n && 2 < n.length;) { - x = n, n = n.replace(this.N, r => this.stemmer.get(r)); + x = n, n = n.replace(this.N, q => this.stemmer.get(q)); } } if (n && (this.mapper || this.dedupe && 1 < n.length)) { h = ""; - for (let x = 0, r = "", p, w; x < n.length; x++) { - p = n.charAt(x), p === r && this.dedupe || ((w = this.mapper && this.mapper.get(p)) || "" === w ? w === r && this.dedupe || !(r = w) || (h += w) : h += r = p); + for (let x = 0, q = "", r, w; x < n.length; x++) { + r = n.charAt(x), r === q && this.dedupe || ((w = this.mapper && this.mapper.get(r)) || "" === w ? w === q && this.dedupe || !(q = w) || (h += w) : h += q = r); } n = h; } @@ -267,22 +270,22 @@ B.encode = function(a, c) { g = n; } } - f.push(n); + e.push(n); } } } } } - this.finalize && (f = this.finalize(f) || f); - this.cache && a.length <= this.K && (this.F.set(a, f), this.F.size > this.O && (this.F.clear(), this.K = this.K / 1.1 | 0)); - return f; + this.finalize && (e = this.finalize(e) || e); + this.cache && a.length <= this.K && (this.F.set(a, e), this.F.size > this.O && (this.F.clear(), this.K = this.K / 1.1 | 0)); + return e; }; function V(a) { a.H = null; a.F.clear(); a.G.clear(); } -;function ka(a) { +;function la(a) { W.call(a, "add"); W.call(a, "append"); W.call(a, "search"); @@ -290,98 +293,98 @@ function V(a) { W.call(a, "remove"); W.call(a, "searchCache"); } -let la, ma, na; -function oa() { - la = na = 0; +let ma, na, oa; +function pa() { + ma = oa = 0; } function W(a) { this[a + "Async"] = function() { const c = arguments; var b = c[c.length - 1]; - let f; - "function" === typeof b && (f = b, delete c[c.length - 1]); - la ? na || (na = Date.now() - ma >= this.priority * this.priority * 3) : (la = setTimeout(oa, 0), ma = Date.now()); - if (na) { - const e = this; + let e; + "function" === typeof b && (e = b, delete c[c.length - 1]); + ma ? oa || (oa = Date.now() - na >= this.priority * this.priority * 3) : (ma = setTimeout(pa, 0), na = Date.now()); + if (oa) { + const f = this; return new Promise(g => { setTimeout(function() { - g(e[a + "Async"].apply(e, c)); + g(f[a + "Async"].apply(f, c)); }, 0); }); } const d = this[a].apply(this, c); - b = d.then ? d : new Promise(e => e(d)); - f && b.then(f); + b = d.then ? d : new Promise(f => f(d)); + e && b.then(e); return b; }; } -;function pa(a, c = 0) { - let b = [], f = []; +;function qa(a, c = 0) { + let b = [], e = []; c && (c = 250000 / c * 5000 | 0); for (const d of a.entries()) { - f.push(d), f.length === c && (b.push(f), f = []); + e.push(d), e.length === c && (b.push(e), e = []); } - f.length && b.push(f); + e.length && b.push(e); return b; } -function qa(a, c) { +function ra(a, c) { c || (c = new Map()); - for (let b = 0, f; b < a.length; b++) { - f = a[b], c.set(f[0], f[1]); + for (let b = 0, e; b < a.length; b++) { + e = a[b], c.set(e[0], e[1]); } return c; } -function ra(a, c = 0) { - let b = [], f = []; +function sa(a, c = 0) { + let b = [], e = []; c && (c = 250000 / c * 1000 | 0); for (const d of a.entries()) { - f.push([d[0], pa(d[1])[0]]), f.length === c && (b.push(f), f = []); + e.push([d[0], qa(d[1])[0]]), e.length === c && (b.push(e), e = []); } - f.length && b.push(f); + e.length && b.push(e); return b; } -function sa(a, c) { +function ta(a, c) { c || (c = new Map()); - for (let b = 0, f, d; b < a.length; b++) { - f = a[b], d = c.get(f[0]), c.set(f[0], qa(f[1], d)); + for (let b = 0, e, d; b < a.length; b++) { + e = a[b], d = c.get(e[0]), c.set(e[0], ra(e[1], d)); } return c; } -function ta(a) { +function wa(a) { let c = [], b = []; - for (const f of a.keys()) { - b.push(f), 250000 === b.length && (c.push(b), b = []); + for (const e of a.keys()) { + b.push(e), 250000 === b.length && (c.push(b), b = []); } b.length && c.push(b); return c; } -function wa(a, c) { +function xa(a, c) { c || (c = new Set()); for (let b = 0; b < a.length; b++) { c.add(a[b]); } return c; } -function xa(a, c, b, f, d, e, g = 0) { - const k = f && f.constructor === Array; - var h = k ? f.shift() : f; +function ya(a, c, b, e, d, f, g = 0) { + const k = e && e.constructor === Array; + var h = k ? e.shift() : e; if (!h) { - return this.export(a, c, d, e + 1); + return this.export(a, c, d, f + 1); } if ((h = a((c ? c + "." : "") + (g + 1) + "." + b, JSON.stringify(h))) && h.then) { const m = this; return h.then(function() { - return xa.call(m, a, c, b, k ? f : null, d, e, g + 1); + return ya.call(m, a, c, b, k ? e : null, d, f, g + 1); }); } - return xa.call(this, a, c, b, k ? f : null, d, e, g + 1); + return ya.call(this, a, c, b, k ? e : null, d, f, g + 1); } -function ya(a, c) { +function za(a, c) { let b = ""; - for (const f of a.entries()) { - a = f[0]; - const d = f[1]; - let e = ""; + for (const e of a.entries()) { + a = e[0]; + const d = e[1]; + let f = ""; for (let g = 0, k; g < d.length; g++) { k = d[g] || [""]; let h = ""; @@ -389,52 +392,52 @@ function ya(a, c) { h += (h ? "," : "") + ("string" === c ? '"' + k[m] + '"' : k[m]); } h = "[" + h + "]"; - e += (e ? "," : "") + h; + f += (f ? "," : "") + h; } - e = '["' + a + '",[' + e + "]]"; - b += (b ? "," : "") + e; + f = '["' + a + '",[' + f + "]]"; + b += (b ? "," : "") + f; } return b; } ;X.prototype.add = function(a, c, b) { - P(a) && (c = a, a = R(c, this.key)); + R(a) && (c = a, a = S(c, this.key)); if (c && (a || 0 === a)) { if (!b && this.reg.has(a)) { return this.update(a, c); } for (let k = 0, h; k < this.field.length; k++) { h = this.D[k]; - var f = this.index.get(this.field[k]); + var e = this.index.get(this.field[k]); if ("function" === typeof h) { var d = h(c); - d && f.add(a, d, !1, !0); + d && e.add(a, d, !1, !0); } else { if (d = h.I, !d || d(c)) { - h.constructor === String ? h = ["" + h] : L(h) && (h = [h]), za(c, h, this.J, 0, f, a, h[0], b); + h.constructor === String ? h = ["" + h] : P(h) && (h = [h]), Aa(c, h, this.J, 0, e, a, h[0], b); } } } if (this.tag) { - for (f = 0; f < this.B.length; f++) { - var e = this.B[f], g = this.R[f]; + for (e = 0; e < this.B.length; e++) { + var f = this.B[e], g = this.R[e]; d = this.tag.get(g); - let k = J(); - if ("function" === typeof e) { - if (e = e(c), !e) { + let k = L(); + if ("function" === typeof f) { + if (f = f(c), !f) { continue; } } else { - const h = e.I; + const h = f.I; if (h && !h(c)) { continue; } - e.constructor === String && (e = "" + e); - e = R(c, e); + f.constructor === String && (f = "" + f); + f = S(c, f); } - if (d && e) { - L(e) && (e = [e]); - for (let h = 0, m, n; h < e.length; h++) { - m = e[h], k[m] || (k[m] = 1, (g = d.get(m)) ? n = g : d.set(m, n = []), b && n.includes(a) || (n.push(a), this.fastupdate && ((g = this.reg.get(a)) ? g.push(n) : this.reg.set(a, [n])))); + if (d && f) { + P(f) && (f = [f]); + for (let h = 0, m, n; h < f.length; h++) { + m = f[h], k[m] || (k[m] = 1, (g = d.get(m)) ? n = g : d.set(m, n = []), b && n.includes(a) || (n.push(a), this.fastupdate && ((g = this.reg.get(a)) ? g.push(n) : this.reg.set(a, [n])))); } } else { d || console.warn("Tag '" + g + "' was not found"); @@ -444,7 +447,7 @@ function ya(a, c) { if (this.store && (!b || !this.store.has(a))) { let k; if (this.A) { - k = J(); + k = L(); for (let h = 0, m; h < this.A.length; h++) { m = this.A[h]; if ((b = m.I) && !b(c)) { @@ -457,11 +460,11 @@ function ya(a, c) { continue; } m = [m.S]; - } else if (L(m) || m.constructor === String) { + } else if (P(m) || m.constructor === String) { k[m] = c[m]; continue; } - Aa(c, k, m, 0, m[0], n); + Ba(c, k, m, 0, m[0], n); } } this.store.set(a, k || c); @@ -469,86 +472,86 @@ function ya(a, c) { } return this; }; -function Aa(a, c, b, f, d, e) { +function Ba(a, c, b, e, d, f) { a = a[d]; - if (f === b.length - 1) { - c[d] = e || a; + if (e === b.length - 1) { + c[d] = f || a; } else if (a) { if (a.constructor === Array) { for (c = c[d] = Array(a.length), d = 0; d < a.length; d++) { - Aa(a, c, b, f, d); + Ba(a, c, b, e, d); } } else { - c = c[d] || (c[d] = J()), d = b[++f], Aa(a, c, b, f, d); + c = c[d] || (c[d] = L()), d = b[++e], Ba(a, c, b, e, d); } } } -function za(a, c, b, f, d, e, g, k) { +function Aa(a, c, b, e, d, f, g, k) { if (a = a[g]) { - if (f === c.length - 1) { + if (e === c.length - 1) { if (a.constructor === Array) { - if (b[f]) { + if (b[e]) { for (c = 0; c < a.length; c++) { - d.add(e, a[c], !0, !0); + d.add(f, a[c], !0, !0); } return; } a = a.join(" "); } - d.add(e, a, k, !0); + d.add(f, a, k, !0); } else { if (a.constructor === Array) { for (g = 0; g < a.length; g++) { - za(a, c, b, f, d, e, g, k); + Aa(a, c, b, e, d, f, g, k); } } else { - g = c[++f], za(a, c, b, f, d, e, g, k); + g = c[++e], Aa(a, c, b, e, d, f, g, k); } } } } -;function Ba(a, c, b) { +;function Ca(a, c, b) { if (!a.length) { return a; } if (1 === a.length) { return a = a[0], a = b || a.length > c ? c ? a.slice(b, b + c) : a.slice(b) : a; } - let f = []; - for (let d = 0, e, g; d < a.length; d++) { - if ((e = a[d]) && (g = e.length)) { + let e = []; + for (let d = 0, f, g; d < a.length; d++) { + if ((f = a[d]) && (g = f.length)) { if (b) { if (b >= g) { b -= g; continue; } - b < g && (e = c ? e.slice(b, b + c) : e.slice(b), g = e.length, b = 0); + b < g && (f = c ? f.slice(b, b + c) : f.slice(b), g = f.length, b = 0); } - g > c && (e = e.slice(0, c), g = c); - if (!f.length && g >= c) { - return e; + g > c && (f = f.slice(0, c), g = c); + if (!e.length && g >= c) { + return f; } - f.push(e); + e.push(f); c -= g; if (!c) { break; } } } - return f = 1 < f.length ? [].concat.apply([], f) : f[0]; + return e = 1 < e.length ? [].concat.apply([], e) : e[0]; } -;function Ca(a, c, b, f, d) { - let e, g, k; - "string" === typeof d ? (e = d, d = "") : e = d.template; - if (!e) { +;function Da(a, c, b, e, d) { + let f, g, k; + "string" === typeof d ? (f = d, d = "") : f = d.template; + if (!f) { throw Error('No template pattern was specified by the search option "highlight"'); } - g = e.indexOf("$1"); + g = f.indexOf("$1"); if (-1 === g) { - throw Error('Invalid highlight template. The replacement pattern "$1" was not found in template: ' + e); + throw Error('Invalid highlight template. The replacement pattern "$1" was not found in template: ' + f); } - k = e.substring(g + 2); - g = e.substring(0, g); + k = f.substring(g + 2); + g = f.substring(0, g); let h = d && d.boundary, m = !d || !1 !== d.clip, n = d && d.merge && k && g && new RegExp(k + " " + g, "g"); d = d && d.ellipsis; var z = 0; @@ -560,31 +563,31 @@ function za(a, c, b, f, d, e, g, k) { "string" !== typeof d && (d = !1 === d ? "" : "..."); z && (d = x.replace("$1", d)); x = d.length - z; - let r, p; - "object" === typeof h && (r = h.before, 0 === r && (r = -1), p = h.after, 0 === p && (p = -1), h = h.total || 9e5); + let q, r; + "object" === typeof h && (q = h.before, 0 === q && (q = -1), r = h.after, 0 === r && (r = -1), h = h.total || 9e5); z = new Map(); - for (let ua = 0, T, Ja, aa; ua < c.length; ua++) { - let ba; - if (f) { - ba = c, aa = f; + for (let ua = 0, T, Ja, ba; ua < c.length; ua++) { + let ca; + if (e) { + ca = c, ba = e; } else { var w = c[ua]; - aa = w.field; - if (!aa) { + ba = w.field; + if (!ba) { continue; } - ba = w.result; + ca = w.result; } - Ja = b.get(aa); + Ja = b.get(ba); T = Ja.encoder; w = z.get(T); "string" !== typeof w && (w = T.encode(a), z.set(T, w)); - for (let ia = 0; ia < ba.length; ia++) { - var l = ba[ia].doc; + for (let ia = 0; ia < ca.length; ia++) { + var l = ca[ia].doc; if (!l) { continue; } - l = R(l, aa); + l = S(l, ba); if (!l) { continue; } @@ -595,154 +598,154 @@ function za(a, c, b, f, d, e, g, k) { l = ""; var v = []; let ja = []; - var D = -1, t = -1, C = 0; + var E = -1, t = -1, C = 0; for (var y = 0; y < u.length; y++) { var A = u[y], H = T.encode(A); H = 1 < H.length ? H.join(" ") : H[0]; - let q; + let p; if (H && A) { - var E = A.length, M = (T.split ? A.replace(T.split, "") : A).length - H.length, K = "", Q = 0; + var D = A.length, M = (T.split ? A.replace(T.split, "") : A).length - H.length, K = "", Q = 0; for (var U = 0; U < w.length; U++) { var N = w[U]; if (N) { var G = N.length; G += M; - Q && G <= Q || (N = H.indexOf(N), -1 < N && (K = (N ? A.substring(0, N) : "") + g + A.substring(N, N + G) + k + (N + G < E ? A.substring(N + G) : ""), Q = G, q = !0)); + Q && G <= Q || (N = H.indexOf(N), -1 < N && (K = (N ? A.substring(0, N) : "") + g + A.substring(N, N + G) + k + (N + G < D ? A.substring(N + G) : ""), Q = G, p = !0)); } } - K && (h && (0 > D && (D = l.length + (l ? 1 : 0)), t = l.length + (l ? 1 : 0) + K.length, C += E, ja.push(v.length), v.push({match:K})), l += (l ? " " : "") + K); + K && (h && (0 > E && (E = l.length + (l ? 1 : 0)), t = l.length + (l ? 1 : 0) + K.length, C += D, ja.push(v.length), v.push({match:K})), l += (l ? " " : "") + K); } - if (!q) { + if (!p) { A = u[y], l += (l ? " " : "") + A, h && v.push({text:A}); } else if (h && C >= h) { break; } } - C = ja.length * (e.length - 2); - if (r || p || h && l.length - C > h) { - if (C = h + C - 2 * x, y = t - D, 0 < r && (y += r), 0 < p && (y += p), y <= C) { - u = r ? D - (0 < r ? r : 0) : D - ((C - y) / 2 | 0), v = p ? t + (0 < p ? p : 0) : u + C, m || (0 < u && " " !== l.charAt(u) && " " !== l.charAt(u - 1) && (u = l.indexOf(" ", u), 0 > u && (u = 0)), v < l.length && " " !== l.charAt(v - 1) && " " !== l.charAt(v) && (v = l.lastIndexOf(" ", v), v < t ? v = t : ++v)), l = (u ? d : "") + l.substring(u, v) + (v < l.length ? d : ""); + C = ja.length * (f.length - 2); + if (q || r || h && l.length - C > h) { + if (C = h + C - 2 * x, y = t - E, 0 < q && (y += q), 0 < r && (y += r), y <= C) { + u = q ? E - (0 < q ? q : 0) : E - ((C - y) / 2 | 0), v = r ? t + (0 < r ? r : 0) : u + C, m || (0 < u && " " !== l.charAt(u) && " " !== l.charAt(u - 1) && (u = l.indexOf(" ", u), 0 > u && (u = 0)), v < l.length && " " !== l.charAt(v - 1) && " " !== l.charAt(v) && (v = l.lastIndexOf(" ", v), v < t ? v = t : ++v)), l = (u ? d : "") + l.substring(u, v) + (v < l.length ? d : ""); } else { t = []; - D = {}; + E = {}; C = {}; y = {}; A = {}; H = {}; - K = M = E = 0; + K = M = D = 0; for (U = Q = 1;;) { var O = void 0; - for (let q = 0, F; q < ja.length; q++) { - F = ja[q]; + for (let p = 0, F; p < ja.length; p++) { + F = ja[p]; if (K) { if (M !== K) { - if (y[q + 1]) { + if (y[p + 1]) { continue; } F += K; - if (D[F]) { - E -= x; - C[q + 1] = 1; - y[q + 1] = 1; + if (E[F]) { + D -= x; + C[p + 1] = 1; + y[p + 1] = 1; continue; } if (F >= v.length - 1) { if (F >= v.length) { - y[q + 1] = 1; - F >= u.length && (C[q + 1] = 1); + y[p + 1] = 1; + F >= u.length && (C[p + 1] = 1); continue; } - E -= x; + D -= x; } l = v[F].text; - if (G = p && H[q]) { + if (G = r && H[p]) { if (0 < G) { if (l.length > G) { - if (y[q + 1] = 1, m) { + if (y[p + 1] = 1, m) { l = l.substring(0, G); } else { continue; } } (G -= l.length) || (G = -1); - H[q] = G; + H[p] = G; } else { - y[q + 1] = 1; + y[p + 1] = 1; continue; } } - if (E + l.length + 1 <= h) { - l = " " + l, t[q] += l; + if (D + l.length + 1 <= h) { + l = " " + l, t[p] += l; } else if (m) { - O = h - E - 1, 0 < O && (l = " " + l.substring(0, O), t[q] += l), y[q + 1] = 1; + O = h - D - 1, 0 < O && (l = " " + l.substring(0, O), t[p] += l), y[p + 1] = 1; } else { - y[q + 1] = 1; + y[p + 1] = 1; continue; } } else { - if (y[q]) { + if (y[p]) { continue; } F -= M; - if (D[F]) { - E -= x; - y[q] = 1; - C[q] = 1; + if (E[F]) { + D -= x; + y[p] = 1; + C[p] = 1; continue; } if (0 >= F) { if (0 > F) { - y[q] = 1; - C[q] = 1; + y[p] = 1; + C[p] = 1; continue; } - E -= x; + D -= x; } l = v[F].text; - if (G = r && A[q]) { + if (G = q && A[p]) { if (0 < G) { if (l.length > G) { - if (y[q] = 1, m) { + if (y[p] = 1, m) { l = l.substring(l.length - G); } else { continue; } } (G -= l.length) || (G = -1); - A[q] = G; + A[p] = G; } else { - y[q] = 1; + y[p] = 1; continue; } } - if (E + l.length + 1 <= h) { - l += " ", t[q] = l + t[q]; + if (D + l.length + 1 <= h) { + l += " ", t[p] = l + t[p]; } else if (m) { - O = l.length + 1 - (h - E), 0 <= O && O < l.length && (l = l.substring(O) + " ", t[q] = l + t[q]), y[q] = 1; + O = l.length + 1 - (h - D), 0 <= O && O < l.length && (l = l.substring(O) + " ", t[p] = l + t[p]), y[p] = 1; } else { - y[q] = 1; + y[p] = 1; continue; } } } else { l = v[F].match; - r && (A[q] = r); - p && (H[q] = p); - q && E++; + q && (A[p] = q); + r && (H[p] = r); + p && D++; let va; - F ? !q && x && (E += x) : (C[q] = 1, y[q] = 1); - F >= u.length - 1 ? va = 1 : F < v.length - 1 && v[F + 1].match ? va = 1 : x && (E += x); - E -= e.length - 2; - if (!q || E + l.length <= h) { - t[q] = l; + F ? !p && x && (D += x) : (C[p] = 1, y[p] = 1); + F >= u.length - 1 ? va = 1 : F < v.length - 1 && v[F + 1].match ? va = 1 : x && (D += x); + D -= f.length - 2; + if (!p || D + l.length <= h) { + t[p] = l; } else { - O = Q = U = C[q] = 0; + O = Q = U = C[p] = 0; break; } - va && (C[q + 1] = 1, y[q + 1] = 1); + va && (C[p + 1] = 1, y[p + 1] = 1); } - E += l.length; - O = D[F] = 1; + D += l.length; + O = E[F] = 1; } if (O) { M === K ? K++ : M++; @@ -755,53 +758,53 @@ function za(a, c, b, f, d, e, g, k) { } } l = ""; - for (let q = 0, F; q < t.length; q++) { - F = (q && C[q] ? " " : (q && !d ? " " : "") + d) + t[q], l += F; + for (let p = 0, F; p < t.length; p++) { + F = (p && C[p] ? " " : (p && !d ? " " : "") + d) + t[p], l += F; } d && !C[t.length] && (l += d); } } n && (l = l.replace(n, " ")); - ba[ia].highlight = l; + ca[ia].highlight = l; } - if (f) { + if (e) { break; } } return c; } -;function Da(a, c) { - const b = J(), f = []; - for (let d = 0, e; d < c.length; d++) { - e = c[d]; - for (let g = 0; g < e.length; g++) { - b[e[g]] = 1; +;function Ea(a, c) { + const b = L(), e = []; + for (let d = 0, f; d < c.length; d++) { + f = c[d]; + for (let g = 0; g < f.length; g++) { + b[f[g]] = 1; } } - for (let d = 0, e; d < a.length; d++) { - e = a[d], b[e] && (f.push(e), b[e] = 0); + for (let d = 0, f; d < a.length; d++) { + f = a[d], b[f] && (e.push(f), b[f] = 0); } - return f; + return e; } -;J(); -X.prototype.search = function(a, c, b, f) { - b || (!c && P(a) ? (b = a, a = "") : P(c) && (b = c, c = 0)); +;L(); +X.prototype.search = function(a, c, b, e) { + b || (!c && R(a) ? (b = a, a = "") : R(c) && (b = c, c = 0)); if (b && b.cache) { b.cache = !1; var d = this.searchCache(a, c, b); b.cache = !0; return d; } - let e = []; + let f = []; var g = []; let k, h, m; let n = 0, z = !0, x; if (b) { b.constructor === Array && (b = {index:b}); a = b.query || a; - var r = b.pluck; - var p = b.merge; - h = r || b.field || (h = b.index) && (h.index ? null : h); + var q = b.pluck; + var r = b.merge; + h = q || b.field || (h = b.index) && (h.index ? null : h); m = this.tag && b.tag; k = b.suggest; z = !0; @@ -814,9 +817,9 @@ X.prototype.search = function(a, c, b, f) { if (m) { m.constructor !== Array && (m = [m]); var l = []; - for (let D = 0, t; D < m.length; D++) { - t = m[D]; - if (L(t)) { + for (let E = 0, t; E < m.length; E++) { + t = m[E]; + if (P(t)) { throw Error("A tag option can't be a string, instead it needs a { field: tag } format."); } if (t.field && t.tag) { @@ -848,31 +851,31 @@ X.prototype.search = function(a, c, b, f) { if (!a) { g = []; if (l.length) { - for (r = 0; r < l.length; r += 2) { - p = Ea.call(this, l[r], l[r + 1], c, w, d), e.push(z ? {field:l[r], tag:l[r + 1], result:p} : [p]); + for (q = 0; q < l.length; q += 2) { + r = Fa.call(this, l[q], l[q + 1], c, w, d), f.push({field:l[q], tag:l[q + 1], result:r}); } } - return g.length ? Promise.all(g).then(function(D) { - for (let t = 0; t < D.length; t++) { - z ? e[t].result = D[t] : e[t] = D[t]; + return g.length ? Promise.all(g).then(function(E) { + for (let t = 0; t < E.length; t++) { + f[t].result = E[t]; } - return e; - }) : e; + return f; + }) : f; } } h && h.constructor !== Array && (h = [h]); } h || (h = this.field); l = !1; - for (let D = 0, t, C, y; D < h.length; D++) { - C = h[D]; + for (let E = 0, t, C, y; E < h.length; E++) { + C = h[E]; let A; - L(C) || (A = C, C = A.field, a = A.query || a, c = Fa(A.limit, c), w = Fa(A.offset, w), k = Fa(A.suggest, k), x = z && this.store && Fa(A.highlight, x), d = !!x || z && this.store && Fa(A.enrich, d)); - if (f) { - t = f[D]; + P(C) || (A = C, C = A.field, a = A.query || a, c = J(A.limit, c), w = J(A.offset, w), k = J(A.suggest, k), x = z && this.store && J(A.highlight, x), d = !!x || z && this.store && J(A.enrich, d)); + if (e) { + t = e[E]; } else { if (u = A || b, v = this.index.get(C), m && (u.enrich = !1), l) { - l[D] = v.search(a, c, u); + l[E] = v.search(a, c, u); u && d && (u.enrich = d); continue; } else { @@ -883,23 +886,23 @@ X.prototype.search = function(a, c, b, f) { if (m && y) { u = []; v = 0; - for (let H = 0, E, M; H < m.length; H += 2) { - E = this.tag.get(m[H]); - if (!E) { + for (let H = 0, D, M; H < m.length; H += 2) { + D = this.tag.get(m[H]); + if (!D) { if (console.warn("Tag '" + m[H] + ":" + m[H + 1] + "' will be skipped because there is no field '" + m[H] + "'."), k) { continue; } else { - return e; + return f; } } - if (M = (E = E && E.get(m[H + 1])) && E.length) { - v++, u.push(E); + if (M = (D = D && D.get(m[H + 1])) && D.length) { + v++, u.push(D); } else if (!k) { - return e; + return f; } } if (v) { - t = Da(t, u); + t = Ea(t, u); y = t.length; if (!y && !k) { return t; @@ -908,68 +911,74 @@ X.prototype.search = function(a, c, b, f) { } } if (y) { - g[n] = C, e.push(t), n++; + g[n] = C, f.push(t), n++; } else if (1 === h.length) { - return e; + return f; } } if (l) { - const D = this; + const E = this; return Promise.all(l).then(function(t) { - return t.length ? D.search(a, c, b, t) : t; + return t.length ? E.search(a, c, b, t) : t; }); } if (!n) { - return e; + return f; } - if (r && (!d || !this.store)) { - return e = e[0], z || (e.index = this), e; + if (q && (!d || !this.store)) { + return f = f[0]; } l = []; for (w = 0; w < g.length; w++) { - f = e[w]; - d && f.length && "undefined" === typeof f[0].doc && (f = Ga.call(this, f)); - if (r) { - return x ? Ca(a, f, this.index, r, x) : f; + e = f[w]; + d && e.length && "undefined" === typeof e[0].doc && (e = Ga.call(this, e)); + if (q) { + return x ? Da(a, e, this.index, q, x) : e; } - e[w] = {field:g[w], result:f}; + f[w] = {field:g[w], result:e}; } - return p ? Ha(e) : x ? Ca(a, e, this.index, r, x) : e; + x && (f = Da(a, f, this.index, q, x)); + return r ? Ha(f) : f; }; -function Fa(a, c) { - return "undefined" === typeof a ? c : a; -} function Ha(a) { - const c = [], b = J(); - for (let f = 0, d, e; f < a.length; f++) { - d = a[f]; - e = d.result; - for (let g = 0, k, h, m; g < e.length; g++) { - h = e[g], "object" !== typeof h && (h = {id:h}), k = h.id, (m = b[k]) ? m.push(d.field) : (h.field = b[k] = [d.field], c.push(h)); + const c = [], b = L(), e = L(); + for (let d = 0, f, g, k, h, m, n, z; d < a.length; d++) { + f = a[d]; + g = f.field; + k = f.result; + for (let x = 0; x < k.length; x++) { + if (m = k[x], "object" !== typeof m ? m = {id:h = m} : h = m.id, (n = b[h]) ? n.push(g) : (m.field = b[h] = [g], c.push(m)), z = m.highlight) { + n = e[h], n || (e[h] = n = {}, m.highlight = n), n[g] = z; + } } } return c; } -function Ea(a, c, b, f, d) { - let e = this.tag.get(a); - if (!e) { - return console.warn("Tag-Field '" + a + "' was not found"), []; +function Fa(a, c, b, e, d) { + a = this.tag.get(a); + if (!a) { + return []; } - if ((a = (e = e && e.get(c)) && e.length - f) && 0 < a) { - if (b && a > b || f) { - e = e.slice(f, f + b); + a = a.get(c); + if (!a) { + return []; + } + c = a.length - e; + if (0 < c) { + if (b && c > b || e) { + a = a.slice(e, e + b); } - d && (e = Ga.call(this, e)); - return e; + d && (a = Ga.call(this, a)); } + return a; } function Ga(a) { if (!this || !this.store) { return a; } const c = Array(a.length); - for (let b = 0, f; b < a.length; b++) { - f = a[b], c[b] = {id:f, doc:this.store.get(f)}; + for (let b = 0, e; b < a.length; b++) { + e = a[b], c[b] = {id:e, doc:this.store.get(e)}; } return c; } @@ -981,10 +990,10 @@ const Oa = {a:"", e:"", i:"", o:"", u:"", y:"", b:1, f:1, p:1, v:1, c:2, g:2, j: var Pa = {Exact:Ia, Default:Ka, Normalize:Ka, LatinBalance:{mapper:La}, LatinAdvanced:{mapper:La, matcher:Ma, replacer:Na}, LatinExtra:{mapper:La, replacer:Na.concat([/(?!^)[aeo]/g, ""]), matcher:Ma}, LatinSoundex:{dedupe:!1, include:{letter:!0}, finalize:function(a) { for (let b = 0; b < a.length; b++) { var c = a[b]; - let f = c.charAt(0), d = Oa[f]; - for (let e = 1, g; e < c.length && (g = c.charAt(e), "h" === g || "w" === g || !(g = Oa[g]) || g === d || (f += g, d = g, 4 !== f.length)); e++) { + let e = c.charAt(0), d = Oa[e]; + for (let f = 1, g; f < c.length && (g = c.charAt(f), "h" === g || "w" === g || !(g = Oa[g]) || g === d || (e += g, d = g, 4 !== e.length)); f++) { } - a[b] = f; + a[b] = e; } }}, CJK:{split:""}, LatinExact:Ia, LatinDefault:Ka, LatinSimple:Ka}; function X(a) { @@ -1004,16 +1013,16 @@ function X(a) { a.cache = !1; this.priority = a.priority || 4; b = new Map(); - let f = c.index || c.field || c; - L(f) && (f = [f]); - for (let d = 0, e, g; d < f.length; d++) { - e = f[d], L(e) || (g = e, e = e.field), g = P(g) ? Object.assign({}, a, g) : a, b.set(e, new Z(g, this.reg)), g.custom ? this.D[d] = g.custom : (this.D[d] = Qa(e, this.J), g.filter && ("string" === typeof this.D[d] && (this.D[d] = new String(this.D[d])), this.D[d].I = g.filter)), this.field[d] = e; + let e = c.index || c.field || c; + P(e) && (e = [e]); + for (let d = 0, f, g; d < e.length; d++) { + f = e[d], P(f) || (g = f, f = f.field), g = R(g) ? Object.assign({}, a, g) : a, b.set(f, new Z(g, this.reg)), g.custom ? this.D[d] = g.custom : (this.D[d] = Qa(f, this.J), g.filter && ("string" === typeof this.D[d] && (this.D[d] = new String(this.D[d])), this.D[d].I = g.filter)), this.field[d] = f; } if (this.A) { a = c.store; - L(a) && (a = [a]); - for (let d = 0, e, g; d < a.length; d++) { - e = a[d], g = e.field || e, e.custom ? (this.A[d] = e.custom, e.custom.S = g) : (this.A[d] = Qa(g, this.J), e.filter && ("string" === typeof this.A[d] && (this.A[d] = new String(this.A[d])), this.A[d].I = e.filter)); + P(a) && (a = [a]); + for (let d = 0, f, g; d < a.length; d++) { + f = a[d], g = f.field || f, f.custom ? (this.A[d] = f.custom, f.custom.S = g) : (this.A[d] = Qa(g, this.J), f.filter && ("string" === typeof this.A[d] && (this.A[d] = new String(this.A[d])), this.A[d].I = f.filter)); } } this.index = b; @@ -1023,13 +1032,13 @@ function X(a) { this.tag = new Map(); this.B = []; this.R = []; - for (let d = 0, e, g; d < b.length; d++) { - e = b[d]; - g = e.field || e; + for (let d = 0, f, g; d < b.length; d++) { + f = b[d]; + g = f.field || f; if (!g) { throw Error("The tag field from the document descriptor is undefined."); } - e.custom ? this.B[d] = e.custom : (this.B[d] = Qa(g, this.J), e.filter && ("string" === typeof this.B[d] && (this.B[d] = new String(this.B[d])), this.B[d].I = e.filter)); + f.custom ? this.B[d] = f.custom : (this.B[d] = Qa(g, this.J), f.filter && ("string" === typeof this.B[d] && (this.B[d] = new String(this.B[d])), this.B[d].I = f.filter)); this.R[d] = g; this.tag.set(g, new Map()); } @@ -1038,12 +1047,12 @@ function X(a) { } function Qa(a, c) { const b = a.split(":"); - let f = 0; + let e = 0; for (let d = 0; d < b.length; d++) { - a = b[d], "]" === a[a.length - 1] && (a = a.substring(0, a.length - 2)) && (c[f] = !0), a && (b[f++] = a); + a = b[d], "]" === a[a.length - 1] && (a = a.substring(0, a.length - 2)) && (c[e] = !0), a && (b[e++] = a); } - f < b.length && (b.length = f); - return 1 < f ? b : b[0]; + e < b.length && (b.length = e); + return 1 < e ? b : b[0]; } B = X.prototype; B.append = function(a, c) { @@ -1053,17 +1062,17 @@ B.update = function(a, c) { return this.remove(a).add(a, c); }; B.remove = function(a) { - P(a) && (a = R(a, this.key)); + R(a) && (a = S(a, this.key)); for (var c of this.index.values()) { c.remove(a, !0); } if (this.reg.has(a)) { if (this.tag && !this.fastupdate) { for (let b of this.tag.values()) { - for (let f of b) { - c = f[0]; - const d = f[1], e = d.indexOf(a); - -1 < e && (1 < d.length ? d.splice(e, 1) : b.delete(c)); + for (let e of b) { + c = e[0]; + const d = e[1], f = d.indexOf(a); + -1 < f && (1 < d.length ? d.splice(f, 1) : b.delete(c)); } } } @@ -1101,15 +1110,15 @@ B.get = function(a) { return this.store.get(a) || null; }; B.set = function(a, c) { - "object" === typeof a && (c = a, a = R(c, this.key)); + "object" === typeof a && (c = a, a = S(c, this.key)); this.store.set(a, c); return this; }; B.searchCache = Ra; -B.export = function(a, c, b = 0, f = 0) { +B.export = function(a, c, b = 0, e = 0) { if (b < this.field.length) { const g = this.field[b]; - if ((c = this.index.get(g).export(a, g, b, f = 1)) && c.then) { + if ((c = this.index.get(g).export(a, g, b, e = 1)) && c.then) { const k = this; return c.then(function() { return k.export(a, g, b + 1); @@ -1117,27 +1126,27 @@ B.export = function(a, c, b = 0, f = 0) { } return this.export(a, g, b + 1); } - let d, e; - switch(f) { + let d, f; + switch(e) { case 0: d = "reg"; - e = ta(this.reg); + f = wa(this.reg); c = null; break; case 1: d = "tag"; - e = this.tag && ra(this.tag, this.reg.size); + f = this.tag && sa(this.tag, this.reg.size); c = null; break; case 2: d = "doc"; - e = this.store && pa(this.store); + f = this.store && qa(this.store); c = null; break; default: return; } - return xa.call(this, a, c, d, e, b, f); + return ya.call(this, a, c, d, f, b, e); }; B.import = function(a, c) { var b = a.split("."); @@ -1152,34 +1161,34 @@ B.import = function(a, c) { switch(b) { case "reg": this.fastupdate = !1; - this.reg = wa(c, this.reg); - for (let f = 0, d; f < this.field.length; f++) { - d = this.index.get(this.field[f]), d.fastupdate = !1, d.reg = this.reg; + this.reg = xa(c, this.reg); + for (let e = 0, d; e < this.field.length; e++) { + d = this.index.get(this.field[e]), d.fastupdate = !1, d.reg = this.reg; } break; case "tag": - this.tag = sa(c, this.tag); + this.tag = ta(c, this.tag); break; case "doc": - this.store = qa(c, this.store); + this.store = ra(c, this.store); } } }; -ka(X.prototype); +la(X.prototype); function Ra(a, c, b) { - const f = (c ? "" + a : "object" === typeof a ? "" + a.query : a).toLowerCase(); + const e = (c ? "" + a : "object" === typeof a ? "" + a.query : a).toLowerCase(); this.cache || (this.cache = new Y()); - let d = this.cache.get(f); + let d = this.cache.get(e); if (!d) { d = this.search(a, c, b); if (d.then) { - const e = this; + const f = this; d.then(function(g) { - e.cache.set(f, g); + f.cache.set(e, g); return g; }); } - this.cache.set(f, d); + this.cache.set(e, d); } return d; } @@ -1211,13 +1220,13 @@ Z.prototype.remove = function(a, c) { const b = this.reg.size && (this.fastupdate ? this.reg.get(a) : this.reg.has(a)); if (b) { if (this.fastupdate) { - for (let f = 0, d; f < b.length; f++) { - if (d = b[f]) { + for (let e = 0, d; e < b.length; e++) { + if (d = b[e]) { if (2 > d.length) { d.pop(); } else { - const e = d.indexOf(a); - e === b.length - 1 ? d.pop() : d.splice(e, 1); + const f = d.indexOf(a); + f === b.length - 1 ? d.pop() : d.splice(f, 1); } } } @@ -1231,15 +1240,15 @@ Z.prototype.remove = function(a, c) { }; function Sa(a, c) { let b = 0; - var f = "undefined" === typeof c; + var e = "undefined" === typeof c; if (a.constructor === Array) { - for (let d = 0, e, g; d < a.length; d++) { - if ((e = a[d]) && e.length) { - if (f) { + for (let d = 0, f, g; d < a.length; d++) { + if ((f = a[d]) && f.length) { + if (e) { b++; } else { - if (g = e.indexOf(c), 0 <= g) { - 1 < e.length ? (e.splice(g, 1), b++) : delete a[d]; + if (g = f.indexOf(c), 0 <= g) { + 1 < f.length ? (f.splice(g, 1), b++) : delete a[d]; break; } else { b++; @@ -1249,37 +1258,37 @@ function Sa(a, c) { } } else { for (let d of a.entries()) { - f = d[0]; - const e = Sa(d[1], c); - e ? b += e : a.delete(f); + e = d[0]; + const f = Sa(d[1], c); + f ? b += f : a.delete(e); } } return b; } ;const Ta = {memory:{resolution:1}, performance:{resolution:3, fastupdate:!0, context:{depth:1, resolution:1}}, match:{tokenize:"forward"}, score:{resolution:9, context:{depth:2, resolution:3}}}; -Z.prototype.add = function(a, c, b, f) { +Z.prototype.add = function(a, c, b, e) { if (c && (a || 0 === a)) { - if (!f && !b && this.reg.has(a)) { + if (!e && !b && this.reg.has(a)) { return this.update(a, c); } - f = this.depth; - c = this.encoder.encode(c, !f); + e = this.depth; + c = this.encoder.encode(c, !e); const m = c.length; if (m) { - const n = J(), z = J(), x = this.resolution; - for (let r = 0; r < m; r++) { - let p = c[this.rtl ? m - 1 - r : r]; - var d = p.length; - if (d && (f || !z[p])) { - var e = this.score ? this.score(c, p, r, null, 0) : Ua(x, m, r), g = ""; + const n = L(), z = L(), x = this.resolution; + for (let q = 0; q < m; q++) { + let r = c[this.rtl ? m - 1 - q : q]; + var d = r.length; + if (d && (e || !z[r])) { + var f = this.score ? this.score(c, r, q, null, 0) : Ua(x, m, q), g = ""; switch(this.tokenize) { case "full": if (2 < d) { for (let w = 0, l; w < d; w++) { - for (e = d; e > w; e--) { - g = p.substring(w, e); + for (f = d; f > w; f--) { + g = r.substring(w, f); l = this.rtl ? d - 1 - w : w; - var k = this.score ? this.score(c, p, r, g, l) : Ua(x, m, r, d, l); + var k = this.score ? this.score(c, r, q, g, l) : Ua(x, m, q, d, l); Va(this, z, g, k, a, b); } } @@ -1289,8 +1298,8 @@ Z.prototype.add = function(a, c, b, f) { case "reverse": if (1 < d) { for (k = d - 1; 0 < k; k--) { - g = p[this.rtl ? d - 1 - k : k] + g; - var h = this.score ? this.score(c, p, r, g, k) : Ua(x, m, r, d, k); + g = r[this.rtl ? d - 1 - k : k] + g; + var h = this.score ? this.score(c, r, q, g, k) : Ua(x, m, q, d, k); Va(this, z, g, h, a, b); } g = ""; @@ -1298,17 +1307,17 @@ Z.prototype.add = function(a, c, b, f) { case "forward": if (1 < d) { for (k = 0; k < d; k++) { - g += p[this.rtl ? d - 1 - k : k], Va(this, z, g, e, a, b); + g += r[this.rtl ? d - 1 - k : k], Va(this, z, g, f, a, b); } break; } default: - if (Va(this, z, p, e, a, b), f && 1 < m && r < m - 1) { - for (d = J(), g = this.P, e = p, k = Math.min(f + 1, this.rtl ? r + 1 : m - r), d[e] = 1, h = 1; h < k; h++) { - if ((p = c[this.rtl ? m - 1 - r - h : r + h]) && !d[p]) { - d[p] = 1; - const w = this.score ? this.score(c, e, r, p, h - 1) : Ua(g + (m / 2 > g ? 0 : 1), m, r, k - 1, h - 1), l = this.bidirectional && p > e; - Va(this, n, l ? e : p, w, a, b, l ? p : e); + if (Va(this, z, r, f, a, b), e && 1 < m && q < m - 1) { + for (d = L(), g = this.P, f = r, k = Math.min(e + 1, this.rtl ? q + 1 : m - q), d[f] = 1, h = 1; h < k; h++) { + if ((r = c[this.rtl ? m - 1 - q - h : q + h]) && !d[r]) { + d[r] = 1; + const w = this.score ? this.score(c, f, q, r, h - 1) : Ua(g + (m / 2 > g ? 0 : 1), m, q, k - 1, h - 1), l = this.bidirectional && r > f; + Va(this, n, l ? f : r, w, a, b, l ? r : f); } } } @@ -1320,98 +1329,98 @@ Z.prototype.add = function(a, c, b, f) { } return this; }; -function Va(a, c, b, f, d, e, g) { +function Va(a, c, b, e, d, f, g) { let k = g ? a.ctx : a.map, h; if (!c[b] || g && !(h = c[b])[g]) { - g ? (c = h || (c[b] = J()), c[g] = 1, (h = k.get(g)) ? k = h : k.set(g, k = new Map())) : c[b] = 1, (h = k.get(b)) ? k = h : k.set(b, k = []), k = k[f] || (k[f] = []), e && k.includes(d) || (k.push(d), a.fastupdate && ((c = a.reg.get(d)) ? c.push(k) : a.reg.set(d, [k]))); + g ? (c = h || (c[b] = L()), c[g] = 1, (h = k.get(g)) ? k = h : k.set(g, k = new Map())) : c[b] = 1, (h = k.get(b)) ? k = h : k.set(b, k = []), k = k[e] || (k[e] = []), f && k.includes(d) || (k.push(d), a.fastupdate && ((c = a.reg.get(d)) ? c.push(k) : a.reg.set(d, [k]))); } } -function Ua(a, c, b, f, d) { - return b && 1 < a ? c + (f || 0) <= a ? b + (d || 0) : (a - 1) / (c + (f || 0)) * (b + (d || 0)) + 1 | 0 : 0; +function Ua(a, c, b, e, d) { + return b && 1 < a ? c + (e || 0) <= a ? b + (d || 0) : (a - 1) / (c + (e || 0)) * (b + (d || 0)) + 1 | 0 : 0; } ;Z.prototype.search = function(a, c, b) { b || (c || "object" !== typeof a ? "object" === typeof c && (b = c, c = 0) : (b = a, a = "")); if (b && b.cache) { return b.cache = !1, c = this.searchCache(a, c, b), b.cache = !0, c; } - var f = [], d = 0; + var e = [], d = 0; if (b) { a = b.query || a; c = b.limit || c; d = b.offset || 0; - var e = b.context; + var f = b.context; var g = b.suggest; var k = !0; var h = b.resolution; } "undefined" === typeof k && (k = !0); - e = this.depth && !1 !== e; - b = this.encoder.encode(a, !e); + f = this.depth && !1 !== f; + b = this.encoder.encode(a, !f); a = b.length; c = c || (k ? 100 : 0); if (1 === a) { - return g = d, (d = Wa(this, b[0], "")) && d.length ? Ba.call(this, d, c, g) : []; + return g = d, (d = Wa(this, b[0], "")) && d.length ? Ca.call(this, d, c, g) : []; } - if (2 === a && e && !g) { - return g = d, (d = Wa(this, b[1], b[0])) && d.length ? Ba.call(this, d, c, g) : []; + if (2 === a && f && !g) { + return g = d, (d = Wa(this, b[1], b[0])) && d.length ? Ca.call(this, d, c, g) : []; } - k = J(); + k = L(); var m = 0; - if (e) { + if (f) { var n = b[0]; m = 1; } h || 0 === h || (h = n ? this.P : this.resolution); - for (let p, w; m < a; m++) { + for (let r, w; m < a; m++) { if ((w = b[m]) && !k[w]) { k[w] = 1; - p = Wa(this, w, n); + r = Wa(this, w, n); a: { - e = p; - var z = f, x = g, r = h; + f = r; + var z = e, x = g, q = h; let l = []; - if (e && e.length) { - if (e.length <= r) { - z.push(e); - p = void 0; + if (f && f.length) { + if (f.length <= q) { + z.push(f); + r = void 0; break a; } - for (let u = 0, v; u < r; u++) { - if (v = e[u]) { + for (let u = 0, v; u < q; u++) { + if (v = f[u]) { l[u] = v; } } if (l.length) { z.push(l); - p = void 0; + r = void 0; break a; } } - p = x ? void 0 : l; + r = x ? void 0 : l; } - if (p) { - f = p; + if (r) { + e = r; break; } - n && (g && p && f.length || (n = w)); + n && (g && r && e.length || (n = w)); } - g && n && m === a - 1 && !f.length && (h = this.resolution, n = "", m = -1, k = J()); + g && n && m === a - 1 && !e.length && (h = this.resolution, n = "", m = -1, k = L()); } a: { - b = f; - f = b.length; + b = e; + e = b.length; n = b; - if (1 < f) { + if (1 < e) { b: { - f = g; + e = g; n = b.length; g = []; - a = J(); - for (let p = 0, w, l, u, v; p < h; p++) { + a = L(); + for (let r = 0, w, l, u, v; r < h; r++) { for (m = 0; m < n; m++) { - if (u = b[m], p < u.length && (w = u[p])) { - for (e = 0; e < w.length; e++) { - if (l = w[e], (k = a[l]) ? a[l]++ : (k = 0, a[l] = 1), v = g[k] || (g[k] = []), v.push(l), c && k === n - 1 && v.length - d === c) { + if (u = b[m], r < u.length && (w = u[r])) { + for (f = 0; f < w.length; f++) { + if (l = w[f], (k = a[l]) ? a[l]++ : (k = 0, a[l] = 1), v = g[k] || (g[k] = []), v.push(l), c && k === n - 1 && v.length - d === c) { n = d ? v.slice(d) : v; break b; } @@ -1420,13 +1429,13 @@ function Ua(a, c, b, f, d) { } } if (b = g.length) { - if (f) { + if (e) { if (1 < g.length) { c: { - for (b = [], h = J(), f = g.length, k = f - 1; 0 <= k; k--) { - if (a = (f = g[k]) && f.length) { + for (b = [], h = L(), e = g.length, k = e - 1; 0 <= k; k--) { + if (a = (e = g[k]) && e.length) { for (m = 0; m < a; m++) { - if (n = f[m], !h[n]) { + if (n = e[m], !h[n]) { if (h[n] = 1, d) { d--; } else { @@ -1458,8 +1467,8 @@ function Ua(a, c, b, f, d) { } n = g; } - } else if (1 === f) { - c = Ba.call(null, b[0], c, d); + } else if (1 === e) { + c = Ca.call(null, b[0], c, d); break a; } c = n; @@ -1467,8 +1476,8 @@ function Ua(a, c, b, f, d) { return c; }; function Wa(a, c, b) { - let f; - b && (f = a.bidirectional && c > b) && (f = b, b = c, c = f); + let e; + b && (e = a.bidirectional && c > b) && (e = b, b = c, c = e); a = b ? (a = a.ctx.get(b)) && a.get(c) : a.map.get(c); return a; } @@ -1477,26 +1486,26 @@ function Wa(a, c, b) { return new Z(a); } if (a) { - var b = L(a) ? a : a.preset; + var b = P(a) ? a : a.preset; b && (Ta[b] || console.warn("Preset not found: " + b), a = Object.assign({}, Ta[b], a)); } else { a = {}; } b = a.context; - const f = !0 === b ? {depth:1} : b || {}, d = L(a.encoder) ? Pa[a.encoder] : a.encode || a.encoder || {}; - this.encoder = d.encode ? d : "object" === typeof d ? new S(d) : {encode:d}; + const e = !0 === b ? {depth:1} : b || {}, d = P(a.encoder) ? Pa[a.encoder] : a.encode || a.encoder || {}; + this.encoder = d.encode ? d : "object" === typeof d ? new ka(d) : {encode:d}; this.resolution = a.resolution || 9; this.tokenize = b = (b = a.tokenize) && "default" !== b && "exact" !== b && b || "strict"; - this.depth = "strict" === b && f.depth || 0; - this.bidirectional = !1 !== f.bidirectional; + this.depth = "strict" === b && e.depth || 0; + this.bidirectional = !1 !== e.bidirectional; this.fastupdate = !!a.fastupdate; this.score = a.score || null; - f && f.depth && "strict" !== this.tokenize && console.warn('Context-Search could not applied, because it is just supported when using the tokenizer "strict".'); + e && e.depth && "strict" !== this.tokenize && console.warn('Context-Search could not applied, because it is just supported when using the tokenizer "strict".'); b = !1; this.map = new Map(); this.ctx = new Map(); this.reg = c || (this.fastupdate ? new Map() : new Set()); - this.P = f.resolution || 3; + this.P = e.resolution || 3; this.rtl = d.rtl || a.rtl || !1; this.cache = (b = a.cache || null) && new Y(b); this.priority = a.priority || 4; @@ -1516,8 +1525,8 @@ B.contain = function(a) { return this.reg.has(a); }; B.update = function(a, c) { - const b = this, f = this.remove(a); - return f && f.then ? f.then(() => b.add(a, c)) : this.add(a, c); + const b = this, e = this.remove(a); + return e && e.then ? e.then(() => b.add(a, c)) : this.add(a, c); }; B.cleanup = function() { if (!this.fastupdate) { @@ -1528,69 +1537,69 @@ B.cleanup = function() { return this; }; B.searchCache = Ra; -B.export = function(a, c, b = 0, f = 0) { - let d, e; - switch(f) { +B.export = function(a, c, b = 0, e = 0) { + let d, f; + switch(e) { case 0: d = "reg"; - e = ta(this.reg); + f = wa(this.reg); break; case 1: d = "cfg"; - e = null; + f = null; break; case 2: d = "map"; - e = pa(this.map, this.reg.size); + f = qa(this.map, this.reg.size); break; case 3: d = "ctx"; - e = ra(this.ctx, this.reg.size); + f = sa(this.ctx, this.reg.size); break; default: return; } - return xa.call(this, a, c, d, e, b, f); + return ya.call(this, a, c, d, f, b, e); }; B.import = function(a, c) { if (c) { switch("string" === typeof c && (c = JSON.parse(c)), a = a.split("."), "json" === a[a.length - 1] && a.pop(), 3 === a.length && a.shift(), a = 1 < a.length ? a[1] : a[0], a) { case "reg": this.fastupdate = !1; - this.reg = wa(c, this.reg); + this.reg = xa(c, this.reg); break; case "map": - this.map = qa(c, this.map); + this.map = ra(c, this.map); break; case "ctx": - this.ctx = sa(c, this.ctx); + this.ctx = ta(c, this.ctx); } } }; B.serialize = function(a = !0) { - let c = "", b = "", f = ""; + let c = "", b = "", e = ""; if (this.reg.size) { - let e; + let f; for (var d of this.reg.keys()) { - e || (e = typeof d), c += (c ? "," : "") + ("string" === e ? '"' + d + '"' : d); + f || (f = typeof d), c += (c ? "," : "") + ("string" === f ? '"' + d + '"' : d); } c = "index.reg=new Set([" + c + "]);"; - b = ya(this.map, e); + b = za(this.map, f); b = "index.map=new Map([" + b + "]);"; for (const g of this.ctx.entries()) { d = g[0]; - let k = ya(g[1], e); + let k = za(g[1], f); k = "new Map([" + k + "])"; k = '["' + d + '",' + k + "]"; - f += (f ? "," : "") + k; + e += (e ? "," : "") + k; } - f = "index.ctx=new Map([" + f + "]);"; + e = "index.ctx=new Map([" + e + "]);"; } - return a ? "function inject(index){" + c + b + f + "}" : c + b + f; + return a ? "function inject(index){" + c + b + e + "}" : c + b + e; }; -ka(Z.prototype); -J(); -const Xa = {Index:Z, Charset:Pa, Encoder:S, Document:X, Worker:null, Resolver:null, IndexedDB:null, Language:{}}, Ya = "undefined" !== typeof self ? self : "undefined" !== typeof global ? global : self; +la(Z.prototype); +L(); +const Xa = {Index:Z, Charset:Pa, Encoder:ka, Document:X, Worker:null, Resolver:null, IndexedDB:null, Language:{}}, Ya = "undefined" !== typeof self ? self : "undefined" !== typeof global ? global : self; let Za; (Za = Ya.define) && Za.amd ? Za([], function() { return Xa; diff --git a/dist/flexsearch.compact.min.js b/dist/flexsearch.compact.min.js index a1d683b..c55a5d7 100644 --- a/dist/flexsearch.compact.min.js +++ b/dist/flexsearch.compact.min.js @@ -1,57 +1,57 @@ /**! - * FlexSearch.js v0.8.164 (Bundle) + * FlexSearch.js v0.8.165 (Bundle) * Author and Copyright: Thomas Wilkerling * Licence: Apache-2.0 * Hosted by Nextapps GmbH * https://github.com/nextapps-de/flexsearch */ -(function(self){'use strict';var A;function H(a,c,b){const e=typeof b,d=typeof a;if("undefined"!==e){if("undefined"!==d){if(b){if("function"===d&&e===d)return function(k){return a(b(k))};c=a.constructor;if(c===b.constructor){if(c===Array)return b.concat(a);if(c===Map){var f=new Map(b);for(var g of a)f.set(g[0],g[1]);return f}if(c===Set){g=new Set(b);for(f of a.values())g.add(f);return g}}}return a}return b}return"undefined"===d?c:a}function I(){return Object.create(null)}function N(a){return"string"===typeof a} -function P(a){return"object"===typeof a}function R(a,c){if(N(c))a=a[c];else for(let b=0;a&&b"a1a".split(b).length; -this.numeric=H(a.numeric,e)}else{try{this.split=H(this.split,ca)}catch(d){this.split=/\s+/}this.numeric=H(a.numeric,H(this.numeric,!0))}this.prepare=H(a.prepare,null,this.prepare);this.finalize=H(a.finalize,null,this.finalize);b=a.filter;this.filter="function"===typeof b?b:H(b&&new Set(b),null,this.filter);this.dedupe=H(a.dedupe,!0,this.dedupe);this.matcher=H((b=a.matcher)&&new Map(b),null,this.matcher);this.mapper=H((b=a.mapper)&&new Map(b),null,this.mapper);this.stemmer=H((b=a.stemmer)&&new Map(b), +this.numeric=H(a.numeric,e)}else{try{this.split=H(this.split,aa)}catch(d){this.split=/\s+/}this.numeric=H(a.numeric,H(this.numeric,!0))}this.prepare=H(a.prepare,null,this.prepare);this.finalize=H(a.finalize,null,this.finalize);b=a.filter;this.filter="function"===typeof b?b:H(b&&new Set(b),null,this.filter);this.dedupe=H(a.dedupe,!0,this.dedupe);this.matcher=H((b=a.matcher)&&new Map(b),null,this.matcher);this.mapper=H((b=a.mapper)&&new Map(b),null,this.mapper);this.stemmer=H((b=a.stemmer)&&new Map(b), null,this.stemmer);this.replacer=H(a.replacer,null,this.replacer);this.minlength=H(a.minlength,1,this.minlength);this.maxlength=H(a.maxlength,1024,this.maxlength);this.rtl=H(a.rtl,!1,this.rtl);if(this.cache=b=H(a.cache,!0,this.cache))this.H=null,this.O="number"===typeof b?b:2E5,this.F=new Map,this.G=new Map,this.L=this.K=128;this.h="";this.M=null;this.C="";this.N=null;if(this.matcher)for(const d of this.matcher.keys())this.h+=(this.h?"|":"")+d;if(this.stemmer)for(const d of this.stemmer.keys())this.C+= (this.C?"|":"")+d;return this};A.addStemmer=function(a,c){this.stemmer||(this.stemmer=new Map);this.stemmer.set(a,c);this.C+=(this.C?"|":"")+a;this.N=null;this.cache&&V(this);return this};A.addFilter=function(a){"function"===typeof a?this.filter=a:(this.filter||(this.filter=new Set),this.filter.add(a));this.cache&&V(this);return this}; A.addMapper=function(a,c){if("object"===typeof a)return this.addReplacer(a,c);if(1a.length&&(this.dedupe||this.mapper))return this.addMapper(a,c);this.matcher||(this.matcher=new Map);this.matcher.set(a,c);this.h+=(this.h?"|":"")+a;this.M=null;this.cache&&V(this);return this}; A.addReplacer=function(a,c){if("string"===typeof a)return this.addMatcher(a,c);this.replacer||(this.replacer=[]);this.replacer.push(a,c);this.cache&&V(this);return this}; A.encode=function(a,c){if(this.cache&&a.length<=this.K)if(this.H){if(this.F.has(a))return this.F.get(a)}else this.H=setTimeout(V,50,this);this.normalize&&("function"===typeof this.normalize?a=this.normalize(a):a=ha?a.normalize("NFKD").replace(ha,"").toLowerCase():a.toLowerCase());this.prepare&&(a=this.prepare(a));this.numeric&&3this.maxlength)){if(c){if(d[n])continue;d[n]=1}else{if(f===n)continue;f=n}if(b)e.push(n);else if(!this.filter||("function"===typeof this.filter?this.filter(n):!this.filter.has(n))){if(this.cache&&n.length<=this.L)if(this.H){var h=this.G.get(n);if(h||""===h){h&&e.push(h);continue}}else this.H=setTimeout(V,50,this);if(this.stemmer){this.N||(this.N=new RegExp("(?!^)("+ -this.C+")$"));let x;for(;x!==n&&2this.stemmer.get(r))}if(n&&(this.mapper||this.dedupe&&1this.matcher.get(x)));if(n&&this.replacer)for(h=0;n&&hthis.O&&(this.G.clear(),this.L=this.L/1.1|0));if(n){if(n!==B)if(c){if(d[n])continue;d[n]=1}else{if(g===n)continue;g=n}e.push(n)}}}this.finalize&&(e=this.finalize(e)||e);this.cache&&a.length<=this.K&&(this.F.set(a,e),this.F.size>this.O&&(this.F.clear(),this.K=this.K/1.1|0));return e};function V(a){a.H=null;a.F.clear();a.G.clear()};function ka(a){W.call(a,"add");W.call(a,"append");W.call(a,"search");W.call(a,"update");W.call(a,"remove");W.call(a,"searchCache")}let la,ma,na;function oa(){la=na=0} -function W(a){this[a+"Async"]=function(){const c=arguments;var b=c[c.length-1];let e;"function"===typeof b&&(e=b,delete c[c.length-1]);la?na||(na=Date.now()-ma>=this.priority*this.priority*3):(la=setTimeout(oa,0),ma=Date.now());if(na){const f=this;return new Promise(g=>{setTimeout(function(){g(f[a+"Async"].apply(f,c))},0)})}const d=this[a].apply(this,c);b=d.then?d:new Promise(f=>f(d));e&&b.then(e);return b}};function pa(a,c=0){let b=[],e=[];c&&(c=25E4/c*5E3|0);for(const d of a.entries())e.push(d),e.length===c&&(b.push(e),e=[]);e.length&&b.push(e);return b}function qa(a,c){c||(c=new Map);for(let b=0,e;bc?c?a.slice(b,b+c):a.slice(b):a;let e=[];for(let d=0,f,g;d=g){b-=g;continue}bc&&(f=f.slice(0,c),g=c);if(!e.length&&g>=c)return f;e.push(f);c-=g;if(!c)break}return e=1D&&(D=l.length+(l?1:0)),t=l.length+(l?1:0)+K.length,C+=E,ja.push(v.length),v.push({match:K})),l+=(l?" ":"")+K)}if(!q)z=u[y],l+=(l?" ":"")+z,h&&v.push({text:z});else if(h&&C>=h)break}C=ja.length*(f.length-2);if(r||p||h&&l.length-C>h)if(C=h+C-2*x,y=t-D,0u&&(u=0)),v=v.length-1){if(F>=v.length){y[q+1]= -1;F>=u.length&&(C[q+1]=1);continue}E-=x}l=v[F].text;if(G=p&&J[q])if(0G)if(y[q+1]=1,m)l=l.substring(0,G);else continue;(G-=l.length)||(G=-1);J[q]=G}else{y[q+1]=1;continue}if(E+l.length+1<=h)l=" "+l,t[q]+=l;else if(m)O=h-E-1,0=F){if(0>F){y[q]=1;C[q]=1;continue}E-=x}l=v[F].text;if(G=r&&z[q])if(0G)if(y[q]=1,m)l=l.substring(l.length- -G);else continue;(G-=l.length)||(G=-1);z[q]=G}else{y[q]=1;continue}if(E+l.length+1<=h)l+=" ",t[q]=l+t[q];else if(m)O=l.length+1-(h-E),0<=O&&O=u.length-1?va=1:Fb||e)a=a.slice(e,e+b);d&&(a=Ga.call(this,a));return a}}function Ga(a){if(!this||!this.store)return a;const c=Array(a.length);for(let b=0,e;bthis.maxlength)){if(c){if(d[n])continue;d[n]=1}else{if(f===n)continue;f=n}if(b)e.push(n);else if(!this.filter||("function"===typeof this.filter?this.filter(n):!this.filter.has(n))){if(this.cache&&n.length<=this.L)if(this.H){var h=this.G.get(n);if(h||""===h){h&&e.push(h);continue}}else this.H=setTimeout(V,50,this);if(this.stemmer){this.N||(this.N=new RegExp("(?!^)("+ +this.C+")$"));let x;for(;x!==n&&2this.stemmer.get(q))}if(n&&(this.mapper||this.dedupe&&1this.matcher.get(x)));if(n&&this.replacer)for(h=0;n&&hthis.O&&(this.G.clear(),this.L=this.L/1.1|0));if(n){if(n!==B)if(c){if(d[n])continue;d[n]=1}else{if(g===n)continue;g=n}e.push(n)}}}this.finalize&&(e=this.finalize(e)||e);this.cache&&a.length<=this.K&&(this.F.set(a,e),this.F.size>this.O&&(this.F.clear(),this.K=this.K/1.1|0));return e};function V(a){a.H=null;a.F.clear();a.G.clear()};function la(a){W.call(a,"add");W.call(a,"append");W.call(a,"search");W.call(a,"update");W.call(a,"remove");W.call(a,"searchCache")}let ma,na,oa;function pa(){ma=oa=0} +function W(a){this[a+"Async"]=function(){const c=arguments;var b=c[c.length-1];let e;"function"===typeof b&&(e=b,delete c[c.length-1]);ma?oa||(oa=Date.now()-na>=this.priority*this.priority*3):(ma=setTimeout(pa,0),na=Date.now());if(oa){const f=this;return new Promise(g=>{setTimeout(function(){g(f[a+"Async"].apply(f,c))},0)})}const d=this[a].apply(this,c);b=d.then?d:new Promise(f=>f(d));e&&b.then(e);return b}};function qa(a,c=0){let b=[],e=[];c&&(c=25E4/c*5E3|0);for(const d of a.entries())e.push(d),e.length===c&&(b.push(e),e=[]);e.length&&b.push(e);return b}function ra(a,c){c||(c=new Map);for(let b=0,e;bc?c?a.slice(b,b+c):a.slice(b):a;let e=[];for(let d=0,f,g;d=g){b-=g;continue}bc&&(f=f.slice(0,c),g=c);if(!e.length&&g>=c)return f;e.push(f);c-=g;if(!c)break}return e=1E&&(E=l.length+(l?1:0)),t=l.length+(l?1:0)+K.length,C+=D,ja.push(v.length),v.push({match:K})),l+=(l?" ":"")+K)}if(!p)z=u[y],l+=(l?" ":"")+z,h&&v.push({text:z});else if(h&&C>=h)break}C=ja.length*(f.length-2);if(q||r||h&&l.length-C>h)if(C=h+C-2*x,y=t-E,0u&&(u=0)),v=v.length-1){if(F>=v.length){y[p+1]= +1;F>=u.length&&(C[p+1]=1);continue}D-=x}l=v[F].text;if(G=r&&J[p])if(0G)if(y[p+1]=1,m)l=l.substring(0,G);else continue;(G-=l.length)||(G=-1);J[p]=G}else{y[p+1]=1;continue}if(D+l.length+1<=h)l=" "+l,t[p]+=l;else if(m)O=h-D-1,0=F){if(0>F){y[p]=1;C[p]=1;continue}D-=x}l=v[F].text;if(G=q&&z[p])if(0G)if(y[p]=1,m)l=l.substring(l.length- +G);else continue;(G-=l.length)||(G=-1);z[p]=G}else{y[p]=1;continue}if(D+l.length+1<=h)l+=" ",t[p]=l+t[p];else if(m)O=l.length+1-(h-D),0<=O&&O=u.length-1?va=1:Fb||e)a=a.slice(e,e+b);d&&(a=Ga.call(this,a))}return a}function Ga(a){if(!this||!this.store)return a;const c=Array(a.length);for(let b=0,e;bthis.limit&&this.cache.delete(this.cache.keys().next().value)}; +A.set=function(a,c){"object"===typeof a&&(c=a,a=S(c,this.key));this.store.set(a,c);return this};A.searchCache=Ra; +A.export=function(a,c,b=0,e=0){if(bthis.limit&&this.cache.delete(this.cache.keys().next().value)}; Y.prototype.get=function(a){const c=this.cache.get(a);c&&this.h!==a&&(this.cache.delete(a),this.cache.set(this.h=a,c));return c};Y.prototype.remove=function(a){for(const c of this.cache){const b=c[0];c[1].includes(a)&&this.cache.delete(b)}};Y.prototype.clear=function(){this.cache.clear();this.h=""};Z.prototype.remove=function(a,c){const b=this.reg.size&&(this.fastupdate?this.reg.get(a):this.reg.has(a));if(b){if(this.fastupdate)for(let e=0,d;ed.length)d.pop();else{const f=d.indexOf(a);f===b.length-1?d.pop():d.splice(f,1)}}else Sa(this.map,a),this.depth&&Sa(this.ctx,a);c||this.reg.delete(a)}this.cache&&this.cache.remove(a);return this}; -function Sa(a,c){let b=0;var e="undefined"===typeof c;if(a.constructor===Array)for(let d=0,f,g;dw;f--){g=p.substring(w,f);l=this.rtl?d-1-w:w;var k=this.score?this.score(c,p,r,g,l):Ua(x, -m,r,d,l);Va(this,B,g,k,a,b)}break}case "bidirectional":case "reverse":if(1g?0:1),m,r,k-1,h-1),l=this.bidirectional&&p>f;Va(this,n,l?f:p,w,a,b,l?p:f)}}}}this.fastupdate||this.reg.add(a)}}return this};function Va(a,c,b,e,d,f,g){let k=g?a.ctx:a.map,h;if(!c[b]||g&&!(h=c[b])[g])g?(c=h||(c[b]=I()),c[g]=1,(h=k.get(g))?k=h:k.set(g,k=new Map)):c[b]=1,(h=k.get(b))?k=h:k.set(b,k=[]),k=k[e]||(k[e]=[]),f&&k.includes(d)||(k.push(d),a.fastupdate&&((c=a.reg.get(d))?c.push(k):a.reg.set(d,[k])))} -function Ua(a,c,b,e,d){return b&&1c||d?g.slice(d,c+d):g;g=b}else{if(b< -n){n=[];break b}g=g[b-1];if(c||d)if(g.length>c||d)g=g.slice(d,c+d)}n=g}else if(1===e){c=Ba.call(null,b[0],c,d);break a}c=n}return c};function Wa(a,c,b){let e;b&&(e=a.bidirectional&&c>b)&&(e=b,b=c,c=e);a=b?(a=a.ctx.get(b))&&a.get(c):a.map.get(c);return a};function Z(a,c){if(!this||this.constructor!==Z)return new Z(a);if(a){var b=N(a)?a:a.preset;b&&(a=Object.assign({},Ta[b],a))}else a={};b=a.context;const e=!0===b?{depth:1}:b||{},d=N(a.encoder)?Pa[a.encoder]:a.encode||a.encoder||{};this.encoder=d.encode?d:"object"===typeof d?new S(d):{encode:d};this.resolution=a.resolution||9;this.tokenize=b=(b=a.tokenize)&&"default"!==b&&"exact"!==b&&b||"strict";this.depth="strict"===b&&e.depth||0;this.bidirectional=!1!==e.bidirectional;this.fastupdate=!!a.fastupdate; +function Sa(a,c){let b=0;var e="undefined"===typeof c;if(a.constructor===Array)for(let d=0,f,g;dw;f--){g=r.substring(w,f);l=this.rtl?d-1-w:w;var k=this.score?this.score(c,r,q,g,l):Ua(x, +m,q,d,l);Va(this,B,g,k,a,b)}break}case "bidirectional":case "reverse":if(1g?0:1),m,q,k-1,h-1),l=this.bidirectional&&r>f;Va(this,n,l?f:r,w,a,b,l?r:f)}}}}this.fastupdate||this.reg.add(a)}}return this};function Va(a,c,b,e,d,f,g){let k=g?a.ctx:a.map,h;if(!c[b]||g&&!(h=c[b])[g])g?(c=h||(c[b]=N()),c[g]=1,(h=k.get(g))?k=h:k.set(g,k=new Map)):c[b]=1,(h=k.get(b))?k=h:k.set(b,k=[]),k=k[e]||(k[e]=[]),f&&k.includes(d)||(k.push(d),a.fastupdate&&((c=a.reg.get(d))?c.push(k):a.reg.set(d,[k])))} +function Ua(a,c,b,e,d){return b&&1c||d?g.slice(d,c+d):g;g=b}else{if(b< +n){n=[];break b}g=g[b-1];if(c||d)if(g.length>c||d)g=g.slice(d,c+d)}n=g}else if(1===e){c=Ca.call(null,b[0],c,d);break a}c=n}return c};function Wa(a,c,b){let e;b&&(e=a.bidirectional&&c>b)&&(e=b,b=c,c=e);a=b?(a=a.ctx.get(b))&&a.get(c):a.map.get(c);return a};function Z(a,c){if(!this||this.constructor!==Z)return new Z(a);if(a){var b=P(a)?a:a.preset;b&&(a=Object.assign({},Ta[b],a))}else a={};b=a.context;const e=!0===b?{depth:1}:b||{},d=P(a.encoder)?Pa[a.encoder]:a.encode||a.encoder||{};this.encoder=d.encode?d:"object"===typeof d?new ka(d):{encode:d};this.resolution=a.resolution||9;this.tokenize=b=(b=a.tokenize)&&"default"!==b&&"exact"!==b&&b||"strict";this.depth="strict"===b&&e.depth||0;this.bidirectional=!1!==e.bidirectional;this.fastupdate=!!a.fastupdate; this.score=a.score||null;b=!1;this.map=new Map;this.ctx=new Map;this.reg=c||(this.fastupdate?new Map:new Set);this.P=e.resolution||3;this.rtl=d.rtl||a.rtl||!1;this.cache=(b=a.cache||null)&&new Y(b);this.priority=a.priority||4}A=Z.prototype;A.clear=function(){this.map.clear();this.ctx.clear();this.reg.clear();this.cache&&this.cache.clear();return this};A.append=function(a,c){return this.add(a,c,!0)};A.contain=function(a){return this.reg.has(a)}; -A.update=function(a,c){const b=this,e=this.remove(a);return e&&e.then?e.then(()=>b.add(a,c)):this.add(a,c)};A.cleanup=function(){if(!this.fastupdate)return this;Sa(this.map);this.depth&&Sa(this.ctx);return this};A.searchCache=Ra;A.export=function(a,c,b=0,e=0){let d,f;switch(e){case 0:d="reg";f=ta(this.reg);break;case 1:d="cfg";f=null;break;case 2:d="map";f=pa(this.map,this.reg.size);break;case 3:d="ctx";f=ra(this.ctx,this.reg.size);break;default:return}return xa.call(this,a,c,d,f,b,e)}; -A.import=function(a,c){if(c)switch("string"===typeof c&&(c=JSON.parse(c)),a=a.split("."),"json"===a[a.length-1]&&a.pop(),3===a.length&&a.shift(),a=1b.add(a,c)):this.add(a,c)};A.cleanup=function(){if(!this.fastupdate)return this;Sa(this.map);this.depth&&Sa(this.ctx);return this};A.searchCache=Ra;A.export=function(a,c,b=0,e=0){let d,f;switch(e){case 0:d="reg";f=wa(this.reg);break;case 1:d="cfg";f=null;break;case 2:d="map";f=qa(this.map,this.reg.size);break;case 3:d="ctx";f=sa(this.ctx,this.reg.size);break;default:return}return ya.call(this,a,c,d,f,b,e)}; +A.import=function(a,c){if(c)switch("string"===typeof c&&(c=JSON.parse(c)),a=a.split("."),"json"===a[a.length-1]&&a.pop(),3===a.length&&a.shift(),a=1 "a1a".split(b).length; + this.split = b, e = !1 === b || 2 > "a1a".split(b).length; } - this.numeric = I(a.numeric, f); + this.numeric = I(a.numeric, e); } else { try { - this.split = I(this.split, ca); + this.split = I(this.split, aa); } catch (d) { console.warn("This platform does not support unicode regex. It falls back to using simple whitespace splitter instead: /s+/."), this.split = /\s+/; } @@ -202,7 +205,7 @@ B.encode = function(a, c) { this.prepare && (a = this.prepare(a)); this.numeric && 3 < a.length && (a = a.replace(ea, "$1 $2").replace(fa, "$1 $2").replace(da, "$1 ")); const b = !(this.dedupe || this.mapper || this.filter || this.matcher || this.stemmer || this.replacer); - let f = [], d = J(), e, g, k = this.split || "" === this.split ? a.split(this.split) : [a]; + let e = [], d = L(), f, g, k = this.split || "" === this.split ? a.split(this.split) : [a]; for (let m = 0, n, z; m < k.length; m++) { if ((n = z = k[m]) && !(n.length < this.minlength || n.length > this.maxlength)) { if (c) { @@ -211,20 +214,20 @@ B.encode = function(a, c) { } d[n] = 1; } else { - if (e === n) { + if (f === n) { continue; } - e = n; + f = n; } if (b) { - f.push(n); + e.push(n); } else { if (!this.filter || ("function" === typeof this.filter ? this.filter(n) : !this.filter.has(n))) { if (this.cache && n.length <= this.L) { if (this.H) { var h = this.G.get(n); if (h || "" === h) { - h && f.push(h); + h && e.push(h); continue; } } else { @@ -235,13 +238,13 @@ B.encode = function(a, c) { this.N || (this.N = new RegExp("(?!^)(" + this.C + ")$")); let x; for (; x !== n && 2 < n.length;) { - x = n, n = n.replace(this.N, r => this.stemmer.get(r)); + x = n, n = n.replace(this.N, q => this.stemmer.get(q)); } } if (n && (this.mapper || this.dedupe && 1 < n.length)) { h = ""; - for (let x = 0, r = "", p, w; x < n.length; x++) { - p = n.charAt(x), p === r && this.dedupe || ((w = this.mapper && this.mapper.get(p)) || "" === w ? w === r && this.dedupe || !(r = w) || (h += w) : h += r = p); + for (let x = 0, q = "", r, w; x < n.length; x++) { + r = n.charAt(x), r === q && this.dedupe || ((w = this.mapper && this.mapper.get(r)) || "" === w ? w === q && this.dedupe || !(q = w) || (h += w) : h += q = r); } n = h; } @@ -266,22 +269,22 @@ B.encode = function(a, c) { g = n; } } - f.push(n); + e.push(n); } } } } } - this.finalize && (f = this.finalize(f) || f); - this.cache && a.length <= this.K && (this.F.set(a, f), this.F.size > this.O && (this.F.clear(), this.K = this.K / 1.1 | 0)); - return f; + this.finalize && (e = this.finalize(e) || e); + this.cache && a.length <= this.K && (this.F.set(a, e), this.F.size > this.O && (this.F.clear(), this.K = this.K / 1.1 | 0)); + return e; }; function V(a) { a.H = null; a.F.clear(); a.G.clear(); } -;function ka(a) { +;function la(a) { W.call(a, "add"); W.call(a, "append"); W.call(a, "search"); @@ -289,98 +292,98 @@ function V(a) { W.call(a, "remove"); W.call(a, "searchCache"); } -let la, ma, na; -function oa() { - la = na = 0; +let ma, na, oa; +function pa() { + ma = oa = 0; } function W(a) { this[a + "Async"] = function() { const c = arguments; var b = c[c.length - 1]; - let f; - "function" === typeof b && (f = b, delete c[c.length - 1]); - la ? na || (na = Date.now() - ma >= this.priority * this.priority * 3) : (la = setTimeout(oa, 0), ma = Date.now()); - if (na) { - const e = this; + let e; + "function" === typeof b && (e = b, delete c[c.length - 1]); + ma ? oa || (oa = Date.now() - na >= this.priority * this.priority * 3) : (ma = setTimeout(pa, 0), na = Date.now()); + if (oa) { + const f = this; return new Promise(g => { setTimeout(function() { - g(e[a + "Async"].apply(e, c)); + g(f[a + "Async"].apply(f, c)); }, 0); }); } const d = this[a].apply(this, c); - b = d.then ? d : new Promise(e => e(d)); - f && b.then(f); + b = d.then ? d : new Promise(f => f(d)); + e && b.then(e); return b; }; } -;function pa(a, c = 0) { - let b = [], f = []; +;function qa(a, c = 0) { + let b = [], e = []; c && (c = 250000 / c * 5000 | 0); for (const d of a.entries()) { - f.push(d), f.length === c && (b.push(f), f = []); + e.push(d), e.length === c && (b.push(e), e = []); } - f.length && b.push(f); + e.length && b.push(e); return b; } -function qa(a, c) { +function ra(a, c) { c || (c = new Map()); - for (let b = 0, f; b < a.length; b++) { - f = a[b], c.set(f[0], f[1]); + for (let b = 0, e; b < a.length; b++) { + e = a[b], c.set(e[0], e[1]); } return c; } -function ra(a, c = 0) { - let b = [], f = []; +function sa(a, c = 0) { + let b = [], e = []; c && (c = 250000 / c * 1000 | 0); for (const d of a.entries()) { - f.push([d[0], pa(d[1])[0]]), f.length === c && (b.push(f), f = []); + e.push([d[0], qa(d[1])[0]]), e.length === c && (b.push(e), e = []); } - f.length && b.push(f); + e.length && b.push(e); return b; } -function sa(a, c) { +function va(a, c) { c || (c = new Map()); - for (let b = 0, f, d; b < a.length; b++) { - f = a[b], d = c.get(f[0]), c.set(f[0], qa(f[1], d)); + for (let b = 0, e, d; b < a.length; b++) { + e = a[b], d = c.get(e[0]), c.set(e[0], ra(e[1], d)); } return c; } -function va(a) { +function wa(a) { let c = [], b = []; - for (const f of a.keys()) { - b.push(f), 250000 === b.length && (c.push(b), b = []); + for (const e of a.keys()) { + b.push(e), 250000 === b.length && (c.push(b), b = []); } b.length && c.push(b); return c; } -function wa(a, c) { +function xa(a, c) { c || (c = new Set()); for (let b = 0; b < a.length; b++) { c.add(a[b]); } return c; } -function xa(a, c, b, f, d, e, g = 0) { - const k = f && f.constructor === Array; - var h = k ? f.shift() : f; +function ya(a, c, b, e, d, f, g = 0) { + const k = e && e.constructor === Array; + var h = k ? e.shift() : e; if (!h) { - return this.export(a, c, d, e + 1); + return this.export(a, c, d, f + 1); } if ((h = a((c ? c + "." : "") + (g + 1) + "." + b, JSON.stringify(h))) && h.then) { const m = this; return h.then(function() { - return xa.call(m, a, c, b, k ? f : null, d, e, g + 1); + return ya.call(m, a, c, b, k ? e : null, d, f, g + 1); }); } - return xa.call(this, a, c, b, k ? f : null, d, e, g + 1); + return ya.call(this, a, c, b, k ? e : null, d, f, g + 1); } -function ya(a, c) { +function za(a, c) { let b = ""; - for (const f of a.entries()) { - a = f[0]; - const d = f[1]; - let e = ""; + for (const e of a.entries()) { + a = e[0]; + const d = e[1]; + let f = ""; for (let g = 0, k; g < d.length; g++) { k = d[g] || [""]; let h = ""; @@ -388,52 +391,52 @@ function ya(a, c) { h += (h ? "," : "") + ("string" === c ? '"' + k[m] + '"' : k[m]); } h = "[" + h + "]"; - e += (e ? "," : "") + h; + f += (f ? "," : "") + h; } - e = '["' + a + '",[' + e + "]]"; - b += (b ? "," : "") + e; + f = '["' + a + '",[' + f + "]]"; + b += (b ? "," : "") + f; } return b; } ;X.prototype.add = function(a, c, b) { - P(a) && (c = a, a = R(c, this.key)); + R(a) && (c = a, a = S(c, this.key)); if (c && (a || 0 === a)) { if (!b && this.reg.has(a)) { return this.update(a, c); } for (let k = 0, h; k < this.field.length; k++) { h = this.D[k]; - var f = this.index.get(this.field[k]); + var e = this.index.get(this.field[k]); if ("function" === typeof h) { var d = h(c); - d && f.add(a, d, !1, !0); + d && e.add(a, d, !1, !0); } else { if (d = h.I, !d || d(c)) { - h.constructor === String ? h = ["" + h] : L(h) && (h = [h]), za(c, h, this.J, 0, f, a, h[0], b); + h.constructor === String ? h = ["" + h] : P(h) && (h = [h]), Aa(c, h, this.J, 0, e, a, h[0], b); } } } if (this.tag) { - for (f = 0; f < this.B.length; f++) { - var e = this.B[f], g = this.R[f]; + for (e = 0; e < this.B.length; e++) { + var f = this.B[e], g = this.R[e]; d = this.tag.get(g); - let k = J(); - if ("function" === typeof e) { - if (e = e(c), !e) { + let k = L(); + if ("function" === typeof f) { + if (f = f(c), !f) { continue; } } else { - const h = e.I; + const h = f.I; if (h && !h(c)) { continue; } - e.constructor === String && (e = "" + e); - e = R(c, e); + f.constructor === String && (f = "" + f); + f = S(c, f); } - if (d && e) { - L(e) && (e = [e]); - for (let h = 0, m, n; h < e.length; h++) { - m = e[h], k[m] || (k[m] = 1, (g = d.get(m)) ? n = g : d.set(m, n = []), b && n.includes(a) || (n.push(a), this.fastupdate && ((g = this.reg.get(a)) ? g.push(n) : this.reg.set(a, [n])))); + if (d && f) { + P(f) && (f = [f]); + for (let h = 0, m, n; h < f.length; h++) { + m = f[h], k[m] || (k[m] = 1, (g = d.get(m)) ? n = g : d.set(m, n = []), b && n.includes(a) || (n.push(a), this.fastupdate && ((g = this.reg.get(a)) ? g.push(n) : this.reg.set(a, [n])))); } } else { d || console.warn("Tag '" + g + "' was not found"); @@ -443,7 +446,7 @@ function ya(a, c) { if (this.store && (!b || !this.store.has(a))) { let k; if (this.A) { - k = J(); + k = L(); for (let h = 0, m; h < this.A.length; h++) { m = this.A[h]; if ((b = m.I) && !b(c)) { @@ -456,11 +459,11 @@ function ya(a, c) { continue; } m = [m.S]; - } else if (L(m) || m.constructor === String) { + } else if (P(m) || m.constructor === String) { k[m] = c[m]; continue; } - Aa(c, k, m, 0, m[0], n); + Ba(c, k, m, 0, m[0], n); } } this.store.set(a, k || c); @@ -468,86 +471,86 @@ function ya(a, c) { } return this; }; -function Aa(a, c, b, f, d, e) { +function Ba(a, c, b, e, d, f) { a = a[d]; - if (f === b.length - 1) { - c[d] = e || a; + if (e === b.length - 1) { + c[d] = f || a; } else if (a) { if (a.constructor === Array) { for (c = c[d] = Array(a.length), d = 0; d < a.length; d++) { - Aa(a, c, b, f, d); + Ba(a, c, b, e, d); } } else { - c = c[d] || (c[d] = J()), d = b[++f], Aa(a, c, b, f, d); + c = c[d] || (c[d] = L()), d = b[++e], Ba(a, c, b, e, d); } } } -function za(a, c, b, f, d, e, g, k) { +function Aa(a, c, b, e, d, f, g, k) { if (a = a[g]) { - if (f === c.length - 1) { + if (e === c.length - 1) { if (a.constructor === Array) { - if (b[f]) { + if (b[e]) { for (c = 0; c < a.length; c++) { - d.add(e, a[c], !0, !0); + d.add(f, a[c], !0, !0); } return; } a = a.join(" "); } - d.add(e, a, k, !0); + d.add(f, a, k, !0); } else { if (a.constructor === Array) { for (g = 0; g < a.length; g++) { - za(a, c, b, f, d, e, g, k); + Aa(a, c, b, e, d, f, g, k); } } else { - g = c[++f], za(a, c, b, f, d, e, g, k); + g = c[++e], Aa(a, c, b, e, d, f, g, k); } } } } -;function Ba(a, c, b) { +;function Ca(a, c, b) { if (!a.length) { return a; } if (1 === a.length) { return a = a[0], a = b || a.length > c ? c ? a.slice(b, b + c) : a.slice(b) : a; } - let f = []; - for (let d = 0, e, g; d < a.length; d++) { - if ((e = a[d]) && (g = e.length)) { + let e = []; + for (let d = 0, f, g; d < a.length; d++) { + if ((f = a[d]) && (g = f.length)) { if (b) { if (b >= g) { b -= g; continue; } - b < g && (e = c ? e.slice(b, b + c) : e.slice(b), g = e.length, b = 0); + b < g && (f = c ? f.slice(b, b + c) : f.slice(b), g = f.length, b = 0); } - g > c && (e = e.slice(0, c), g = c); - if (!f.length && g >= c) { - return e; + g > c && (f = f.slice(0, c), g = c); + if (!e.length && g >= c) { + return f; } - f.push(e); + e.push(f); c -= g; if (!c) { break; } } } - return f = 1 < f.length ? [].concat.apply([], f) : f[0]; + return e = 1 < e.length ? [].concat.apply([], e) : e[0]; } -;function Ca(a, c, b, f, d) { - let e, g, k; - "string" === typeof d ? (e = d, d = "") : e = d.template; - if (!e) { +;function Da(a, c, b, e, d) { + let f, g, k; + "string" === typeof d ? (f = d, d = "") : f = d.template; + if (!f) { throw Error('No template pattern was specified by the search option "highlight"'); } - g = e.indexOf("$1"); + g = f.indexOf("$1"); if (-1 === g) { - throw Error('Invalid highlight template. The replacement pattern "$1" was not found in template: ' + e); + throw Error('Invalid highlight template. The replacement pattern "$1" was not found in template: ' + f); } - k = e.substring(g + 2); - g = e.substring(0, g); + k = f.substring(g + 2); + g = f.substring(0, g); let h = d && d.boundary, m = !d || !1 !== d.clip, n = d && d.merge && k && g && new RegExp(k + " " + g, "g"); d = d && d.ellipsis; var z = 0; @@ -559,31 +562,31 @@ function za(a, c, b, f, d, e, g, k) { "string" !== typeof d && (d = !1 === d ? "" : "..."); z && (d = x.replace("$1", d)); x = d.length - z; - let r, p; - "object" === typeof h && (r = h.before, 0 === r && (r = -1), p = h.after, 0 === p && (p = -1), h = h.total || 9e5); + let q, r; + "object" === typeof h && (q = h.before, 0 === q && (q = -1), r = h.after, 0 === r && (r = -1), h = h.total || 9e5); z = new Map(); - for (let ta = 0, T, Ga, aa; ta < c.length; ta++) { - let ba; - if (f) { - ba = c, aa = f; + for (let ta = 0, T, Ga, ba; ta < c.length; ta++) { + let ca; + if (e) { + ca = c, ba = e; } else { var w = c[ta]; - aa = w.field; - if (!aa) { + ba = w.field; + if (!ba) { continue; } - ba = w.result; + ca = w.result; } - Ga = b.get(aa); + Ga = b.get(ba); T = Ga.encoder; w = z.get(T); "string" !== typeof w && (w = T.encode(a), z.set(T, w)); - for (let ia = 0; ia < ba.length; ia++) { - var l = ba[ia].doc; + for (let ia = 0; ia < ca.length; ia++) { + var l = ca[ia].doc; if (!l) { continue; } - l = R(l, aa); + l = S(l, ba); if (!l) { continue; } @@ -594,154 +597,154 @@ function za(a, c, b, f, d, e, g, k) { l = ""; var v = []; let ja = []; - var D = -1, t = -1, C = 0; + var E = -1, t = -1, C = 0; for (var y = 0; y < u.length; y++) { var A = u[y], H = T.encode(A); H = 1 < H.length ? H.join(" ") : H[0]; - let q; + let p; if (H && A) { - var E = A.length, M = (T.split ? A.replace(T.split, "") : A).length - H.length, K = "", Q = 0; + var D = A.length, M = (T.split ? A.replace(T.split, "") : A).length - H.length, K = "", Q = 0; for (var U = 0; U < w.length; U++) { var N = w[U]; if (N) { var G = N.length; G += M; - Q && G <= Q || (N = H.indexOf(N), -1 < N && (K = (N ? A.substring(0, N) : "") + g + A.substring(N, N + G) + k + (N + G < E ? A.substring(N + G) : ""), Q = G, q = !0)); + Q && G <= Q || (N = H.indexOf(N), -1 < N && (K = (N ? A.substring(0, N) : "") + g + A.substring(N, N + G) + k + (N + G < D ? A.substring(N + G) : ""), Q = G, p = !0)); } } - K && (h && (0 > D && (D = l.length + (l ? 1 : 0)), t = l.length + (l ? 1 : 0) + K.length, C += E, ja.push(v.length), v.push({match:K})), l += (l ? " " : "") + K); + K && (h && (0 > E && (E = l.length + (l ? 1 : 0)), t = l.length + (l ? 1 : 0) + K.length, C += D, ja.push(v.length), v.push({match:K})), l += (l ? " " : "") + K); } - if (!q) { + if (!p) { A = u[y], l += (l ? " " : "") + A, h && v.push({text:A}); } else if (h && C >= h) { break; } } - C = ja.length * (e.length - 2); - if (r || p || h && l.length - C > h) { - if (C = h + C - 2 * x, y = t - D, 0 < r && (y += r), 0 < p && (y += p), y <= C) { - u = r ? D - (0 < r ? r : 0) : D - ((C - y) / 2 | 0), v = p ? t + (0 < p ? p : 0) : u + C, m || (0 < u && " " !== l.charAt(u) && " " !== l.charAt(u - 1) && (u = l.indexOf(" ", u), 0 > u && (u = 0)), v < l.length && " " !== l.charAt(v - 1) && " " !== l.charAt(v) && (v = l.lastIndexOf(" ", v), v < t ? v = t : ++v)), l = (u ? d : "") + l.substring(u, v) + (v < l.length ? d : ""); + C = ja.length * (f.length - 2); + if (q || r || h && l.length - C > h) { + if (C = h + C - 2 * x, y = t - E, 0 < q && (y += q), 0 < r && (y += r), y <= C) { + u = q ? E - (0 < q ? q : 0) : E - ((C - y) / 2 | 0), v = r ? t + (0 < r ? r : 0) : u + C, m || (0 < u && " " !== l.charAt(u) && " " !== l.charAt(u - 1) && (u = l.indexOf(" ", u), 0 > u && (u = 0)), v < l.length && " " !== l.charAt(v - 1) && " " !== l.charAt(v) && (v = l.lastIndexOf(" ", v), v < t ? v = t : ++v)), l = (u ? d : "") + l.substring(u, v) + (v < l.length ? d : ""); } else { t = []; - D = {}; + E = {}; C = {}; y = {}; A = {}; H = {}; - K = M = E = 0; + K = M = D = 0; for (U = Q = 1;;) { var O = void 0; - for (let q = 0, F; q < ja.length; q++) { - F = ja[q]; + for (let p = 0, F; p < ja.length; p++) { + F = ja[p]; if (K) { if (M !== K) { - if (y[q + 1]) { + if (y[p + 1]) { continue; } F += K; - if (D[F]) { - E -= x; - C[q + 1] = 1; - y[q + 1] = 1; + if (E[F]) { + D -= x; + C[p + 1] = 1; + y[p + 1] = 1; continue; } if (F >= v.length - 1) { if (F >= v.length) { - y[q + 1] = 1; - F >= u.length && (C[q + 1] = 1); + y[p + 1] = 1; + F >= u.length && (C[p + 1] = 1); continue; } - E -= x; + D -= x; } l = v[F].text; - if (G = p && H[q]) { + if (G = r && H[p]) { if (0 < G) { if (l.length > G) { - if (y[q + 1] = 1, m) { + if (y[p + 1] = 1, m) { l = l.substring(0, G); } else { continue; } } (G -= l.length) || (G = -1); - H[q] = G; + H[p] = G; } else { - y[q + 1] = 1; + y[p + 1] = 1; continue; } } - if (E + l.length + 1 <= h) { - l = " " + l, t[q] += l; + if (D + l.length + 1 <= h) { + l = " " + l, t[p] += l; } else if (m) { - O = h - E - 1, 0 < O && (l = " " + l.substring(0, O), t[q] += l), y[q + 1] = 1; + O = h - D - 1, 0 < O && (l = " " + l.substring(0, O), t[p] += l), y[p + 1] = 1; } else { - y[q + 1] = 1; + y[p + 1] = 1; continue; } } else { - if (y[q]) { + if (y[p]) { continue; } F -= M; - if (D[F]) { - E -= x; - y[q] = 1; - C[q] = 1; + if (E[F]) { + D -= x; + y[p] = 1; + C[p] = 1; continue; } if (0 >= F) { if (0 > F) { - y[q] = 1; - C[q] = 1; + y[p] = 1; + C[p] = 1; continue; } - E -= x; + D -= x; } l = v[F].text; - if (G = r && A[q]) { + if (G = q && A[p]) { if (0 < G) { if (l.length > G) { - if (y[q] = 1, m) { + if (y[p] = 1, m) { l = l.substring(l.length - G); } else { continue; } } (G -= l.length) || (G = -1); - A[q] = G; + A[p] = G; } else { - y[q] = 1; + y[p] = 1; continue; } } - if (E + l.length + 1 <= h) { - l += " ", t[q] = l + t[q]; + if (D + l.length + 1 <= h) { + l += " ", t[p] = l + t[p]; } else if (m) { - O = l.length + 1 - (h - E), 0 <= O && O < l.length && (l = l.substring(O) + " ", t[q] = l + t[q]), y[q] = 1; + O = l.length + 1 - (h - D), 0 <= O && O < l.length && (l = l.substring(O) + " ", t[p] = l + t[p]), y[p] = 1; } else { - y[q] = 1; + y[p] = 1; continue; } } } else { l = v[F].match; - r && (A[q] = r); - p && (H[q] = p); - q && E++; + q && (A[p] = q); + r && (H[p] = r); + p && D++; let ua; - F ? !q && x && (E += x) : (C[q] = 1, y[q] = 1); - F >= u.length - 1 ? ua = 1 : F < v.length - 1 && v[F + 1].match ? ua = 1 : x && (E += x); - E -= e.length - 2; - if (!q || E + l.length <= h) { - t[q] = l; + F ? !p && x && (D += x) : (C[p] = 1, y[p] = 1); + F >= u.length - 1 ? ua = 1 : F < v.length - 1 && v[F + 1].match ? ua = 1 : x && (D += x); + D -= f.length - 2; + if (!p || D + l.length <= h) { + t[p] = l; } else { - O = Q = U = C[q] = 0; + O = Q = U = C[p] = 0; break; } - ua && (C[q + 1] = 1, y[q + 1] = 1); + ua && (C[p + 1] = 1, y[p + 1] = 1); } - E += l.length; - O = D[F] = 1; + D += l.length; + O = E[F] = 1; } if (O) { M === K ? K++ : M++; @@ -754,53 +757,53 @@ function za(a, c, b, f, d, e, g, k) { } } l = ""; - for (let q = 0, F; q < t.length; q++) { - F = (q && C[q] ? " " : (q && !d ? " " : "") + d) + t[q], l += F; + for (let p = 0, F; p < t.length; p++) { + F = (p && C[p] ? " " : (p && !d ? " " : "") + d) + t[p], l += F; } d && !C[t.length] && (l += d); } } n && (l = l.replace(n, " ")); - ba[ia].highlight = l; + ca[ia].highlight = l; } - if (f) { + if (e) { break; } } return c; } -;function Da(a, c) { - const b = J(), f = []; - for (let d = 0, e; d < c.length; d++) { - e = c[d]; - for (let g = 0; g < e.length; g++) { - b[e[g]] = 1; +;function Ea(a, c) { + const b = L(), e = []; + for (let d = 0, f; d < c.length; d++) { + f = c[d]; + for (let g = 0; g < f.length; g++) { + b[f[g]] = 1; } } - for (let d = 0, e; d < a.length; d++) { - e = a[d], b[e] && (f.push(e), b[e] = 0); + for (let d = 0, f; d < a.length; d++) { + f = a[d], b[f] && (e.push(f), b[f] = 0); } - return f; + return e; } -;J(); -X.prototype.search = function(a, c, b, f) { - b || (!c && P(a) ? (b = a, a = "") : P(c) && (b = c, c = 0)); +;L(); +X.prototype.search = function(a, c, b, e) { + b || (!c && R(a) ? (b = a, a = "") : R(c) && (b = c, c = 0)); if (b && b.cache) { b.cache = !1; var d = this.searchCache(a, c, b); b.cache = !0; return d; } - let e = []; + let f = []; var g = []; let k, h, m; let n = 0, z = !0, x; if (b) { b.constructor === Array && (b = {index:b}); a = b.query || a; - var r = b.pluck; - var p = b.merge; - h = r || b.field || (h = b.index) && (h.index ? null : h); + var q = b.pluck; + var r = b.merge; + h = q || b.field || (h = b.index) && (h.index ? null : h); m = this.tag && b.tag; k = b.suggest; z = !0; @@ -813,9 +816,9 @@ X.prototype.search = function(a, c, b, f) { if (m) { m.constructor !== Array && (m = [m]); var l = []; - for (let D = 0, t; D < m.length; D++) { - t = m[D]; - if (L(t)) { + for (let E = 0, t; E < m.length; E++) { + t = m[E]; + if (P(t)) { throw Error("A tag option can't be a string, instead it needs a { field: tag } format."); } if (t.field && t.tag) { @@ -847,31 +850,31 @@ X.prototype.search = function(a, c, b, f) { if (!a) { g = []; if (l.length) { - for (r = 0; r < l.length; r += 2) { - p = Ea.call(this, l[r], l[r + 1], c, w, d), e.push(z ? {field:l[r], tag:l[r + 1], result:p} : [p]); + for (q = 0; q < l.length; q += 2) { + r = Fa.call(this, l[q], l[q + 1], c, w, d), f.push({field:l[q], tag:l[q + 1], result:r}); } } - return g.length ? Promise.all(g).then(function(D) { - for (let t = 0; t < D.length; t++) { - z ? e[t].result = D[t] : e[t] = D[t]; + return g.length ? Promise.all(g).then(function(E) { + for (let t = 0; t < E.length; t++) { + f[t].result = E[t]; } - return e; - }) : e; + return f; + }) : f; } } h && h.constructor !== Array && (h = [h]); } h || (h = this.field); l = !1; - for (let D = 0, t, C, y; D < h.length; D++) { - C = h[D]; + for (let E = 0, t, C, y; E < h.length; E++) { + C = h[E]; let A; - L(C) || (A = C, C = A.field, a = A.query || a, c = Fa(A.limit, c), w = Fa(A.offset, w), k = Fa(A.suggest, k), x = z && this.store && Fa(A.highlight, x), d = !!x || z && this.store && Fa(A.enrich, d)); - if (f) { - t = f[D]; + P(C) || (A = C, C = A.field, a = A.query || a, c = J(A.limit, c), w = J(A.offset, w), k = J(A.suggest, k), x = z && this.store && J(A.highlight, x), d = !!x || z && this.store && J(A.enrich, d)); + if (e) { + t = e[E]; } else { if (u = A || b, v = this.index.get(C), m && (u.enrich = !1), l) { - l[D] = v.search(a, c, u); + l[E] = v.search(a, c, u); u && d && (u.enrich = d); continue; } else { @@ -882,23 +885,23 @@ X.prototype.search = function(a, c, b, f) { if (m && y) { u = []; v = 0; - for (let H = 0, E, M; H < m.length; H += 2) { - E = this.tag.get(m[H]); - if (!E) { + for (let H = 0, D, M; H < m.length; H += 2) { + D = this.tag.get(m[H]); + if (!D) { if (console.warn("Tag '" + m[H] + ":" + m[H + 1] + "' will be skipped because there is no field '" + m[H] + "'."), k) { continue; } else { - return e; + return f; } } - if (M = (E = E && E.get(m[H + 1])) && E.length) { - v++, u.push(E); + if (M = (D = D && D.get(m[H + 1])) && D.length) { + v++, u.push(D); } else if (!k) { - return e; + return f; } } if (v) { - t = Da(t, u); + t = Ea(t, u); y = t.length; if (!y && !k) { return t; @@ -907,68 +910,74 @@ X.prototype.search = function(a, c, b, f) { } } if (y) { - g[n] = C, e.push(t), n++; + g[n] = C, f.push(t), n++; } else if (1 === h.length) { - return e; + return f; } } if (l) { - const D = this; + const E = this; return Promise.all(l).then(function(t) { - return t.length ? D.search(a, c, b, t) : t; + return t.length ? E.search(a, c, b, t) : t; }); } if (!n) { - return e; + return f; } - if (r && (!d || !this.store)) { - return e = e[0], z || (e.index = this), e; + if (q && (!d || !this.store)) { + return f = f[0]; } l = []; for (w = 0; w < g.length; w++) { - f = e[w]; - d && f.length && "undefined" === typeof f[0].doc && (f = Ha.call(this, f)); - if (r) { - return x ? Ca(a, f, this.index, r, x) : f; + e = f[w]; + d && e.length && "undefined" === typeof e[0].doc && (e = Ha.call(this, e)); + if (q) { + return x ? Da(a, e, this.index, q, x) : e; } - e[w] = {field:g[w], result:f}; + f[w] = {field:g[w], result:e}; } - return p ? Ia(e) : x ? Ca(a, e, this.index, r, x) : e; + x && (f = Da(a, f, this.index, q, x)); + return r ? Ia(f) : f; }; -function Fa(a, c) { - return "undefined" === typeof a ? c : a; -} function Ia(a) { - const c = [], b = J(); - for (let f = 0, d, e; f < a.length; f++) { - d = a[f]; - e = d.result; - for (let g = 0, k, h, m; g < e.length; g++) { - h = e[g], "object" !== typeof h && (h = {id:h}), k = h.id, (m = b[k]) ? m.push(d.field) : (h.field = b[k] = [d.field], c.push(h)); + const c = [], b = L(), e = L(); + for (let d = 0, f, g, k, h, m, n, z; d < a.length; d++) { + f = a[d]; + g = f.field; + k = f.result; + for (let x = 0; x < k.length; x++) { + if (m = k[x], "object" !== typeof m ? m = {id:h = m} : h = m.id, (n = b[h]) ? n.push(g) : (m.field = b[h] = [g], c.push(m)), z = m.highlight) { + n = e[h], n || (e[h] = n = {}, m.highlight = n), n[g] = z; + } } } return c; } -function Ea(a, c, b, f, d) { - let e = this.tag.get(a); - if (!e) { - return console.warn("Tag-Field '" + a + "' was not found"), []; +function Fa(a, c, b, e, d) { + a = this.tag.get(a); + if (!a) { + return []; } - if ((a = (e = e && e.get(c)) && e.length - f) && 0 < a) { - if (b && a > b || f) { - e = e.slice(f, f + b); + a = a.get(c); + if (!a) { + return []; + } + c = a.length - e; + if (0 < c) { + if (b && c > b || e) { + a = a.slice(e, e + b); } - d && (e = Ha.call(this, e)); - return e; + d && (a = Ha.call(this, a)); } + return a; } function Ha(a) { if (!this || !this.store) { return a; } const c = Array(a.length); - for (let b = 0, f; b < a.length; b++) { - f = a[b], c[b] = {id:f, doc:this.store.get(f)}; + for (let b = 0, e; b < a.length; b++) { + e = a[b], c[b] = {id:e, doc:this.store.get(e)}; } return c; } @@ -980,10 +989,10 @@ const Oa = {a:"", e:"", i:"", o:"", u:"", y:"", b:1, f:1, p:1, v:1, c:2, g:2, j: var Pa = {Exact:Ja, Default:Ka, Normalize:Ka, LatinBalance:{mapper:La}, LatinAdvanced:{mapper:La, matcher:Ma, replacer:Na}, LatinExtra:{mapper:La, replacer:Na.concat([/(?!^)[aeo]/g, ""]), matcher:Ma}, LatinSoundex:{dedupe:!1, include:{letter:!0}, finalize:function(a) { for (let b = 0; b < a.length; b++) { var c = a[b]; - let f = c.charAt(0), d = Oa[f]; - for (let e = 1, g; e < c.length && (g = c.charAt(e), "h" === g || "w" === g || !(g = Oa[g]) || g === d || (f += g, d = g, 4 !== f.length)); e++) { + let e = c.charAt(0), d = Oa[e]; + for (let f = 1, g; f < c.length && (g = c.charAt(f), "h" === g || "w" === g || !(g = Oa[g]) || g === d || (e += g, d = g, 4 !== e.length)); f++) { } - a[b] = f; + a[b] = e; } }}, CJK:{split:""}, LatinExact:Ja, LatinDefault:Ka, LatinSimple:Ka}; function X(a) { @@ -1003,16 +1012,16 @@ function X(a) { a.cache = !1; this.priority = a.priority || 4; b = new Map(); - let f = c.index || c.field || c; - L(f) && (f = [f]); - for (let d = 0, e, g; d < f.length; d++) { - e = f[d], L(e) || (g = e, e = e.field), g = P(g) ? Object.assign({}, a, g) : a, b.set(e, new Z(g, this.reg)), g.custom ? this.D[d] = g.custom : (this.D[d] = Qa(e, this.J), g.filter && ("string" === typeof this.D[d] && (this.D[d] = new String(this.D[d])), this.D[d].I = g.filter)), this.field[d] = e; + let e = c.index || c.field || c; + P(e) && (e = [e]); + for (let d = 0, f, g; d < e.length; d++) { + f = e[d], P(f) || (g = f, f = f.field), g = R(g) ? Object.assign({}, a, g) : a, b.set(f, new Z(g, this.reg)), g.custom ? this.D[d] = g.custom : (this.D[d] = Qa(f, this.J), g.filter && ("string" === typeof this.D[d] && (this.D[d] = new String(this.D[d])), this.D[d].I = g.filter)), this.field[d] = f; } if (this.A) { a = c.store; - L(a) && (a = [a]); - for (let d = 0, e, g; d < a.length; d++) { - e = a[d], g = e.field || e, e.custom ? (this.A[d] = e.custom, e.custom.S = g) : (this.A[d] = Qa(g, this.J), e.filter && ("string" === typeof this.A[d] && (this.A[d] = new String(this.A[d])), this.A[d].I = e.filter)); + P(a) && (a = [a]); + for (let d = 0, f, g; d < a.length; d++) { + f = a[d], g = f.field || f, f.custom ? (this.A[d] = f.custom, f.custom.S = g) : (this.A[d] = Qa(g, this.J), f.filter && ("string" === typeof this.A[d] && (this.A[d] = new String(this.A[d])), this.A[d].I = f.filter)); } } this.index = b; @@ -1022,13 +1031,13 @@ function X(a) { this.tag = new Map(); this.B = []; this.R = []; - for (let d = 0, e, g; d < b.length; d++) { - e = b[d]; - g = e.field || e; + for (let d = 0, f, g; d < b.length; d++) { + f = b[d]; + g = f.field || f; if (!g) { throw Error("The tag field from the document descriptor is undefined."); } - e.custom ? this.B[d] = e.custom : (this.B[d] = Qa(g, this.J), e.filter && ("string" === typeof this.B[d] && (this.B[d] = new String(this.B[d])), this.B[d].I = e.filter)); + f.custom ? this.B[d] = f.custom : (this.B[d] = Qa(g, this.J), f.filter && ("string" === typeof this.B[d] && (this.B[d] = new String(this.B[d])), this.B[d].I = f.filter)); this.R[d] = g; this.tag.set(g, new Map()); } @@ -1037,12 +1046,12 @@ function X(a) { } function Qa(a, c) { const b = a.split(":"); - let f = 0; + let e = 0; for (let d = 0; d < b.length; d++) { - a = b[d], "]" === a[a.length - 1] && (a = a.substring(0, a.length - 2)) && (c[f] = !0), a && (b[f++] = a); + a = b[d], "]" === a[a.length - 1] && (a = a.substring(0, a.length - 2)) && (c[e] = !0), a && (b[e++] = a); } - f < b.length && (b.length = f); - return 1 < f ? b : b[0]; + e < b.length && (b.length = e); + return 1 < e ? b : b[0]; } B = X.prototype; B.append = function(a, c) { @@ -1052,17 +1061,17 @@ B.update = function(a, c) { return this.remove(a).add(a, c); }; B.remove = function(a) { - P(a) && (a = R(a, this.key)); + R(a) && (a = S(a, this.key)); for (var c of this.index.values()) { c.remove(a, !0); } if (this.reg.has(a)) { if (this.tag && !this.fastupdate) { for (let b of this.tag.values()) { - for (let f of b) { - c = f[0]; - const d = f[1], e = d.indexOf(a); - -1 < e && (1 < d.length ? d.splice(e, 1) : b.delete(c)); + for (let e of b) { + c = e[0]; + const d = e[1], f = d.indexOf(a); + -1 < f && (1 < d.length ? d.splice(f, 1) : b.delete(c)); } } } @@ -1100,15 +1109,15 @@ B.get = function(a) { return this.store.get(a) || null; }; B.set = function(a, c) { - "object" === typeof a && (c = a, a = R(c, this.key)); + "object" === typeof a && (c = a, a = S(c, this.key)); this.store.set(a, c); return this; }; B.searchCache = Ra; -B.export = function(a, c, b = 0, f = 0) { +B.export = function(a, c, b = 0, e = 0) { if (b < this.field.length) { const g = this.field[b]; - if ((c = this.index.get(g).export(a, g, b, f = 1)) && c.then) { + if ((c = this.index.get(g).export(a, g, b, e = 1)) && c.then) { const k = this; return c.then(function() { return k.export(a, g, b + 1); @@ -1116,27 +1125,27 @@ B.export = function(a, c, b = 0, f = 0) { } return this.export(a, g, b + 1); } - let d, e; - switch(f) { + let d, f; + switch(e) { case 0: d = "reg"; - e = va(this.reg); + f = wa(this.reg); c = null; break; case 1: d = "tag"; - e = this.tag && ra(this.tag, this.reg.size); + f = this.tag && sa(this.tag, this.reg.size); c = null; break; case 2: d = "doc"; - e = this.store && pa(this.store); + f = this.store && qa(this.store); c = null; break; default: return; } - return xa.call(this, a, c, d, e, b, f); + return ya.call(this, a, c, d, f, b, e); }; B.import = function(a, c) { var b = a.split("."); @@ -1151,34 +1160,34 @@ B.import = function(a, c) { switch(b) { case "reg": this.fastupdate = !1; - this.reg = wa(c, this.reg); - for (let f = 0, d; f < this.field.length; f++) { - d = this.index.get(this.field[f]), d.fastupdate = !1, d.reg = this.reg; + this.reg = xa(c, this.reg); + for (let e = 0, d; e < this.field.length; e++) { + d = this.index.get(this.field[e]), d.fastupdate = !1, d.reg = this.reg; } break; case "tag": - this.tag = sa(c, this.tag); + this.tag = va(c, this.tag); break; case "doc": - this.store = qa(c, this.store); + this.store = ra(c, this.store); } } }; -ka(X.prototype); +la(X.prototype); function Ra(a, c, b) { - const f = (c ? "" + a : "object" === typeof a ? "" + a.query : a).toLowerCase(); + const e = (c ? "" + a : "object" === typeof a ? "" + a.query : a).toLowerCase(); this.cache || (this.cache = new Y()); - let d = this.cache.get(f); + let d = this.cache.get(e); if (!d) { d = this.search(a, c, b); if (d.then) { - const e = this; + const f = this; d.then(function(g) { - e.cache.set(f, g); + f.cache.set(e, g); return g; }); } - this.cache.set(f, d); + this.cache.set(e, d); } return d; } @@ -1210,13 +1219,13 @@ Z.prototype.remove = function(a, c) { const b = this.reg.size && (this.fastupdate ? this.reg.get(a) : this.reg.has(a)); if (b) { if (this.fastupdate) { - for (let f = 0, d; f < b.length; f++) { - if (d = b[f]) { + for (let e = 0, d; e < b.length; e++) { + if (d = b[e]) { if (2 > d.length) { d.pop(); } else { - const e = d.indexOf(a); - e === b.length - 1 ? d.pop() : d.splice(e, 1); + const f = d.indexOf(a); + f === b.length - 1 ? d.pop() : d.splice(f, 1); } } } @@ -1230,15 +1239,15 @@ Z.prototype.remove = function(a, c) { }; function Sa(a, c) { let b = 0; - var f = "undefined" === typeof c; + var e = "undefined" === typeof c; if (a.constructor === Array) { - for (let d = 0, e, g; d < a.length; d++) { - if ((e = a[d]) && e.length) { - if (f) { + for (let d = 0, f, g; d < a.length; d++) { + if ((f = a[d]) && f.length) { + if (e) { b++; } else { - if (g = e.indexOf(c), 0 <= g) { - 1 < e.length ? (e.splice(g, 1), b++) : delete a[d]; + if (g = f.indexOf(c), 0 <= g) { + 1 < f.length ? (f.splice(g, 1), b++) : delete a[d]; break; } else { b++; @@ -1248,37 +1257,37 @@ function Sa(a, c) { } } else { for (let d of a.entries()) { - f = d[0]; - const e = Sa(d[1], c); - e ? b += e : a.delete(f); + e = d[0]; + const f = Sa(d[1], c); + f ? b += f : a.delete(e); } } return b; } ;const Ta = {memory:{resolution:1}, performance:{resolution:3, fastupdate:!0, context:{depth:1, resolution:1}}, match:{tokenize:"forward"}, score:{resolution:9, context:{depth:2, resolution:3}}}; -Z.prototype.add = function(a, c, b, f) { +Z.prototype.add = function(a, c, b, e) { if (c && (a || 0 === a)) { - if (!f && !b && this.reg.has(a)) { + if (!e && !b && this.reg.has(a)) { return this.update(a, c); } - f = this.depth; - c = this.encoder.encode(c, !f); + e = this.depth; + c = this.encoder.encode(c, !e); const m = c.length; if (m) { - const n = J(), z = J(), x = this.resolution; - for (let r = 0; r < m; r++) { - let p = c[this.rtl ? m - 1 - r : r]; - var d = p.length; - if (d && (f || !z[p])) { - var e = this.score ? this.score(c, p, r, null, 0) : Ua(x, m, r), g = ""; + const n = L(), z = L(), x = this.resolution; + for (let q = 0; q < m; q++) { + let r = c[this.rtl ? m - 1 - q : q]; + var d = r.length; + if (d && (e || !z[r])) { + var f = this.score ? this.score(c, r, q, null, 0) : Ua(x, m, q), g = ""; switch(this.tokenize) { case "full": if (2 < d) { for (let w = 0, l; w < d; w++) { - for (e = d; e > w; e--) { - g = p.substring(w, e); + for (f = d; f > w; f--) { + g = r.substring(w, f); l = this.rtl ? d - 1 - w : w; - var k = this.score ? this.score(c, p, r, g, l) : Ua(x, m, r, d, l); + var k = this.score ? this.score(c, r, q, g, l) : Ua(x, m, q, d, l); Va(this, z, g, k, a, b); } } @@ -1288,8 +1297,8 @@ Z.prototype.add = function(a, c, b, f) { case "reverse": if (1 < d) { for (k = d - 1; 0 < k; k--) { - g = p[this.rtl ? d - 1 - k : k] + g; - var h = this.score ? this.score(c, p, r, g, k) : Ua(x, m, r, d, k); + g = r[this.rtl ? d - 1 - k : k] + g; + var h = this.score ? this.score(c, r, q, g, k) : Ua(x, m, q, d, k); Va(this, z, g, h, a, b); } g = ""; @@ -1297,17 +1306,17 @@ Z.prototype.add = function(a, c, b, f) { case "forward": if (1 < d) { for (k = 0; k < d; k++) { - g += p[this.rtl ? d - 1 - k : k], Va(this, z, g, e, a, b); + g += r[this.rtl ? d - 1 - k : k], Va(this, z, g, f, a, b); } break; } default: - if (Va(this, z, p, e, a, b), f && 1 < m && r < m - 1) { - for (d = J(), g = this.P, e = p, k = Math.min(f + 1, this.rtl ? r + 1 : m - r), d[e] = 1, h = 1; h < k; h++) { - if ((p = c[this.rtl ? m - 1 - r - h : r + h]) && !d[p]) { - d[p] = 1; - const w = this.score ? this.score(c, e, r, p, h - 1) : Ua(g + (m / 2 > g ? 0 : 1), m, r, k - 1, h - 1), l = this.bidirectional && p > e; - Va(this, n, l ? e : p, w, a, b, l ? p : e); + if (Va(this, z, r, f, a, b), e && 1 < m && q < m - 1) { + for (d = L(), g = this.P, f = r, k = Math.min(e + 1, this.rtl ? q + 1 : m - q), d[f] = 1, h = 1; h < k; h++) { + if ((r = c[this.rtl ? m - 1 - q - h : q + h]) && !d[r]) { + d[r] = 1; + const w = this.score ? this.score(c, f, q, r, h - 1) : Ua(g + (m / 2 > g ? 0 : 1), m, q, k - 1, h - 1), l = this.bidirectional && r > f; + Va(this, n, l ? f : r, w, a, b, l ? r : f); } } } @@ -1319,98 +1328,98 @@ Z.prototype.add = function(a, c, b, f) { } return this; }; -function Va(a, c, b, f, d, e, g) { +function Va(a, c, b, e, d, f, g) { let k = g ? a.ctx : a.map, h; if (!c[b] || g && !(h = c[b])[g]) { - g ? (c = h || (c[b] = J()), c[g] = 1, (h = k.get(g)) ? k = h : k.set(g, k = new Map())) : c[b] = 1, (h = k.get(b)) ? k = h : k.set(b, k = []), k = k[f] || (k[f] = []), e && k.includes(d) || (k.push(d), a.fastupdate && ((c = a.reg.get(d)) ? c.push(k) : a.reg.set(d, [k]))); + g ? (c = h || (c[b] = L()), c[g] = 1, (h = k.get(g)) ? k = h : k.set(g, k = new Map())) : c[b] = 1, (h = k.get(b)) ? k = h : k.set(b, k = []), k = k[e] || (k[e] = []), f && k.includes(d) || (k.push(d), a.fastupdate && ((c = a.reg.get(d)) ? c.push(k) : a.reg.set(d, [k]))); } } -function Ua(a, c, b, f, d) { - return b && 1 < a ? c + (f || 0) <= a ? b + (d || 0) : (a - 1) / (c + (f || 0)) * (b + (d || 0)) + 1 | 0 : 0; +function Ua(a, c, b, e, d) { + return b && 1 < a ? c + (e || 0) <= a ? b + (d || 0) : (a - 1) / (c + (e || 0)) * (b + (d || 0)) + 1 | 0 : 0; } ;Z.prototype.search = function(a, c, b) { b || (c || "object" !== typeof a ? "object" === typeof c && (b = c, c = 0) : (b = a, a = "")); if (b && b.cache) { return b.cache = !1, c = this.searchCache(a, c, b), b.cache = !0, c; } - var f = [], d = 0; + var e = [], d = 0; if (b) { a = b.query || a; c = b.limit || c; d = b.offset || 0; - var e = b.context; + var f = b.context; var g = b.suggest; var k = !0; var h = b.resolution; } "undefined" === typeof k && (k = !0); - e = this.depth && !1 !== e; - b = this.encoder.encode(a, !e); + f = this.depth && !1 !== f; + b = this.encoder.encode(a, !f); a = b.length; c = c || (k ? 100 : 0); if (1 === a) { - return g = d, (d = Wa(this, b[0], "")) && d.length ? Ba.call(this, d, c, g) : []; + return g = d, (d = Wa(this, b[0], "")) && d.length ? Ca.call(this, d, c, g) : []; } - if (2 === a && e && !g) { - return g = d, (d = Wa(this, b[1], b[0])) && d.length ? Ba.call(this, d, c, g) : []; + if (2 === a && f && !g) { + return g = d, (d = Wa(this, b[1], b[0])) && d.length ? Ca.call(this, d, c, g) : []; } - k = J(); + k = L(); var m = 0; - if (e) { + if (f) { var n = b[0]; m = 1; } h || 0 === h || (h = n ? this.P : this.resolution); - for (let p, w; m < a; m++) { + for (let r, w; m < a; m++) { if ((w = b[m]) && !k[w]) { k[w] = 1; - p = Wa(this, w, n); + r = Wa(this, w, n); a: { - e = p; - var z = f, x = g, r = h; + f = r; + var z = e, x = g, q = h; let l = []; - if (e && e.length) { - if (e.length <= r) { - z.push(e); - p = void 0; + if (f && f.length) { + if (f.length <= q) { + z.push(f); + r = void 0; break a; } - for (let u = 0, v; u < r; u++) { - if (v = e[u]) { + for (let u = 0, v; u < q; u++) { + if (v = f[u]) { l[u] = v; } } if (l.length) { z.push(l); - p = void 0; + r = void 0; break a; } } - p = x ? void 0 : l; + r = x ? void 0 : l; } - if (p) { - f = p; + if (r) { + e = r; break; } - n && (g && p && f.length || (n = w)); + n && (g && r && e.length || (n = w)); } - g && n && m === a - 1 && !f.length && (h = this.resolution, n = "", m = -1, k = J()); + g && n && m === a - 1 && !e.length && (h = this.resolution, n = "", m = -1, k = L()); } a: { - b = f; - f = b.length; + b = e; + e = b.length; n = b; - if (1 < f) { + if (1 < e) { b: { - f = g; + e = g; n = b.length; g = []; - a = J(); - for (let p = 0, w, l, u, v; p < h; p++) { + a = L(); + for (let r = 0, w, l, u, v; r < h; r++) { for (m = 0; m < n; m++) { - if (u = b[m], p < u.length && (w = u[p])) { - for (e = 0; e < w.length; e++) { - if (l = w[e], (k = a[l]) ? a[l]++ : (k = 0, a[l] = 1), v = g[k] || (g[k] = []), v.push(l), c && k === n - 1 && v.length - d === c) { + if (u = b[m], r < u.length && (w = u[r])) { + for (f = 0; f < w.length; f++) { + if (l = w[f], (k = a[l]) ? a[l]++ : (k = 0, a[l] = 1), v = g[k] || (g[k] = []), v.push(l), c && k === n - 1 && v.length - d === c) { n = d ? v.slice(d) : v; break b; } @@ -1419,13 +1428,13 @@ function Ua(a, c, b, f, d) { } } if (b = g.length) { - if (f) { + if (e) { if (1 < g.length) { c: { - for (b = [], h = J(), f = g.length, k = f - 1; 0 <= k; k--) { - if (a = (f = g[k]) && f.length) { + for (b = [], h = L(), e = g.length, k = e - 1; 0 <= k; k--) { + if (a = (e = g[k]) && e.length) { for (m = 0; m < a; m++) { - if (n = f[m], !h[n]) { + if (n = e[m], !h[n]) { if (h[n] = 1, d) { d--; } else { @@ -1457,8 +1466,8 @@ function Ua(a, c, b, f, d) { } n = g; } - } else if (1 === f) { - c = Ba.call(null, b[0], c, d); + } else if (1 === e) { + c = Ca.call(null, b[0], c, d); break a; } c = n; @@ -1466,8 +1475,8 @@ function Ua(a, c, b, f, d) { return c; }; function Wa(a, c, b) { - let f; - b && (f = a.bidirectional && c > b) && (f = b, b = c, c = f); + let e; + b && (e = a.bidirectional && c > b) && (e = b, b = c, c = e); a = b ? (a = a.ctx.get(b)) && a.get(c) : a.map.get(c); return a; } @@ -1476,26 +1485,26 @@ function Wa(a, c, b) { return new Z(a); } if (a) { - var b = L(a) ? a : a.preset; + var b = P(a) ? a : a.preset; b && (Ta[b] || console.warn("Preset not found: " + b), a = Object.assign({}, Ta[b], a)); } else { a = {}; } b = a.context; - const f = !0 === b ? {depth:1} : b || {}, d = L(a.encoder) ? Pa[a.encoder] : a.encode || a.encoder || {}; - this.encoder = d.encode ? d : "object" === typeof d ? new S(d) : {encode:d}; + const e = !0 === b ? {depth:1} : b || {}, d = P(a.encoder) ? Pa[a.encoder] : a.encode || a.encoder || {}; + this.encoder = d.encode ? d : "object" === typeof d ? new ka(d) : {encode:d}; this.resolution = a.resolution || 9; this.tokenize = b = (b = a.tokenize) && "default" !== b && "exact" !== b && b || "strict"; - this.depth = "strict" === b && f.depth || 0; - this.bidirectional = !1 !== f.bidirectional; + this.depth = "strict" === b && e.depth || 0; + this.bidirectional = !1 !== e.bidirectional; this.fastupdate = !!a.fastupdate; this.score = a.score || null; - f && f.depth && "strict" !== this.tokenize && console.warn('Context-Search could not applied, because it is just supported when using the tokenizer "strict".'); + e && e.depth && "strict" !== this.tokenize && console.warn('Context-Search could not applied, because it is just supported when using the tokenizer "strict".'); b = !1; this.map = new Map(); this.ctx = new Map(); this.reg = c || (this.fastupdate ? new Map() : new Set()); - this.P = f.resolution || 3; + this.P = e.resolution || 3; this.rtl = d.rtl || a.rtl || !1; this.cache = (b = a.cache || null) && new Y(b); this.priority = a.priority || 4; @@ -1515,8 +1524,8 @@ B.contain = function(a) { return this.reg.has(a); }; B.update = function(a, c) { - const b = this, f = this.remove(a); - return f && f.then ? f.then(() => b.add(a, c)) : this.add(a, c); + const b = this, e = this.remove(a); + return e && e.then ? e.then(() => b.add(a, c)) : this.add(a, c); }; B.cleanup = function() { if (!this.fastupdate) { @@ -1527,68 +1536,68 @@ B.cleanup = function() { return this; }; B.searchCache = Ra; -B.export = function(a, c, b = 0, f = 0) { - let d, e; - switch(f) { +B.export = function(a, c, b = 0, e = 0) { + let d, f; + switch(e) { case 0: d = "reg"; - e = va(this.reg); + f = wa(this.reg); break; case 1: d = "cfg"; - e = null; + f = null; break; case 2: d = "map"; - e = pa(this.map, this.reg.size); + f = qa(this.map, this.reg.size); break; case 3: d = "ctx"; - e = ra(this.ctx, this.reg.size); + f = sa(this.ctx, this.reg.size); break; default: return; } - return xa.call(this, a, c, d, e, b, f); + return ya.call(this, a, c, d, f, b, e); }; B.import = function(a, c) { if (c) { switch("string" === typeof c && (c = JSON.parse(c)), a = a.split("."), "json" === a[a.length - 1] && a.pop(), 3 === a.length && a.shift(), a = 1 < a.length ? a[1] : a[0], a) { case "reg": this.fastupdate = !1; - this.reg = wa(c, this.reg); + this.reg = xa(c, this.reg); break; case "map": - this.map = qa(c, this.map); + this.map = ra(c, this.map); break; case "ctx": - this.ctx = sa(c, this.ctx); + this.ctx = va(c, this.ctx); } } }; B.serialize = function(a = !0) { - let c = "", b = "", f = ""; + let c = "", b = "", e = ""; if (this.reg.size) { - let e; + let f; for (var d of this.reg.keys()) { - e || (e = typeof d), c += (c ? "," : "") + ("string" === e ? '"' + d + '"' : d); + f || (f = typeof d), c += (c ? "," : "") + ("string" === f ? '"' + d + '"' : d); } c = "index.reg=new Set([" + c + "]);"; - b = ya(this.map, e); + b = za(this.map, f); b = "index.map=new Map([" + b + "]);"; for (const g of this.ctx.entries()) { d = g[0]; - let k = ya(g[1], e); + let k = za(g[1], f); k = "new Map([" + k + "])"; k = '["' + d + '",' + k + "]"; - f += (f ? "," : "") + k; + e += (e ? "," : "") + k; } - f = "index.ctx=new Map([" + f + "]);"; + e = "index.ctx=new Map([" + e + "]);"; } - return a ? "function inject(index){" + c + b + f + "}" : c + b + f; + return a ? "function inject(index){" + c + b + e + "}" : c + b + e; }; -ka(Z.prototype); -J(); -export default {Index:Z, Charset:Pa, Encoder:S, Document:X, Worker:null, Resolver:null, IndexedDB:null, Language:{}}; +la(Z.prototype); +L(); +export default {Index:Z, Charset:Pa, Encoder:ka, Document:X, Worker:null, Resolver:null, IndexedDB:null, Language:{}}; -export const Index=Z;export const Charset=Pa;export const Encoder=S;export const Document=X;export const Worker=null;export const Resolver=null;export const IndexedDB=null;export const Language={}; \ No newline at end of file +export const Index=Z;export const Charset=Pa;export const Encoder=ka;export const Document=X;export const Worker=null;export const Resolver=null;export const IndexedDB=null;export const Language={}; \ No newline at end of file diff --git a/dist/flexsearch.compact.module.min.js b/dist/flexsearch.compact.module.min.js index 6f70dc3..b312172 100644 --- a/dist/flexsearch.compact.module.min.js +++ b/dist/flexsearch.compact.module.min.js @@ -1,58 +1,58 @@ /**! - * FlexSearch.js v0.8.164 (Bundle) + * FlexSearch.js v0.8.165 (Bundle) * Author and Copyright: Thomas Wilkerling * Licence: Apache-2.0 * Hosted by Nextapps GmbH * https://github.com/nextapps-de/flexsearch */ -var A;function H(a,c,b){const e=typeof b,d=typeof a;if("undefined"!==e){if("undefined"!==d){if(b){if("function"===d&&e===d)return function(k){return a(b(k))};c=a.constructor;if(c===b.constructor){if(c===Array)return b.concat(a);if(c===Map){var f=new Map(b);for(var g of a)f.set(g[0],g[1]);return f}if(c===Set){g=new Set(b);for(f of a.values())g.add(f);return g}}}return a}return b}return"undefined"===d?c:a}function I(){return Object.create(null)}function N(a){return"string"===typeof a} -function P(a){return"object"===typeof a}function R(a,c){if(N(c))a=a[c];else for(let b=0;a&&b"a1a".split(b).length; -this.numeric=H(a.numeric,e)}else{try{this.split=H(this.split,ca)}catch(d){this.split=/\s+/}this.numeric=H(a.numeric,H(this.numeric,!0))}this.prepare=H(a.prepare,null,this.prepare);this.finalize=H(a.finalize,null,this.finalize);b=a.filter;this.filter="function"===typeof b?b:H(b&&new Set(b),null,this.filter);this.dedupe=H(a.dedupe,!0,this.dedupe);this.matcher=H((b=a.matcher)&&new Map(b),null,this.matcher);this.mapper=H((b=a.mapper)&&new Map(b),null,this.mapper);this.stemmer=H((b=a.stemmer)&&new Map(b), +this.numeric=H(a.numeric,e)}else{try{this.split=H(this.split,aa)}catch(d){this.split=/\s+/}this.numeric=H(a.numeric,H(this.numeric,!0))}this.prepare=H(a.prepare,null,this.prepare);this.finalize=H(a.finalize,null,this.finalize);b=a.filter;this.filter="function"===typeof b?b:H(b&&new Set(b),null,this.filter);this.dedupe=H(a.dedupe,!0,this.dedupe);this.matcher=H((b=a.matcher)&&new Map(b),null,this.matcher);this.mapper=H((b=a.mapper)&&new Map(b),null,this.mapper);this.stemmer=H((b=a.stemmer)&&new Map(b), null,this.stemmer);this.replacer=H(a.replacer,null,this.replacer);this.minlength=H(a.minlength,1,this.minlength);this.maxlength=H(a.maxlength,1024,this.maxlength);this.rtl=H(a.rtl,!1,this.rtl);if(this.cache=b=H(a.cache,!0,this.cache))this.H=null,this.O="number"===typeof b?b:2E5,this.F=new Map,this.G=new Map,this.L=this.K=128;this.h="";this.M=null;this.C="";this.N=null;if(this.matcher)for(const d of this.matcher.keys())this.h+=(this.h?"|":"")+d;if(this.stemmer)for(const d of this.stemmer.keys())this.C+= (this.C?"|":"")+d;return this};A.addStemmer=function(a,c){this.stemmer||(this.stemmer=new Map);this.stemmer.set(a,c);this.C+=(this.C?"|":"")+a;this.N=null;this.cache&&V(this);return this};A.addFilter=function(a){"function"===typeof a?this.filter=a:(this.filter||(this.filter=new Set),this.filter.add(a));this.cache&&V(this);return this}; A.addMapper=function(a,c){if("object"===typeof a)return this.addReplacer(a,c);if(1a.length&&(this.dedupe||this.mapper))return this.addMapper(a,c);this.matcher||(this.matcher=new Map);this.matcher.set(a,c);this.h+=(this.h?"|":"")+a;this.M=null;this.cache&&V(this);return this}; A.addReplacer=function(a,c){if("string"===typeof a)return this.addMatcher(a,c);this.replacer||(this.replacer=[]);this.replacer.push(a,c);this.cache&&V(this);return this}; A.encode=function(a,c){if(this.cache&&a.length<=this.K)if(this.H){if(this.F.has(a))return this.F.get(a)}else this.H=setTimeout(V,50,this);this.normalize&&("function"===typeof this.normalize?a=this.normalize(a):a=ha?a.normalize("NFKD").replace(ha,"").toLowerCase():a.toLowerCase());this.prepare&&(a=this.prepare(a));this.numeric&&3this.maxlength)){if(c){if(d[n])continue;d[n]=1}else{if(f===n)continue;f=n}if(b)e.push(n);else if(!this.filter||("function"===typeof this.filter?this.filter(n):!this.filter.has(n))){if(this.cache&&n.length<=this.L)if(this.H){var h=this.G.get(n);if(h||""===h){h&&e.push(h);continue}}else this.H=setTimeout(V,50,this);if(this.stemmer){this.N||(this.N=new RegExp("(?!^)("+ -this.C+")$"));let x;for(;x!==n&&2this.stemmer.get(r))}if(n&&(this.mapper||this.dedupe&&1this.matcher.get(x)));if(n&&this.replacer)for(h=0;n&&hthis.O&&(this.G.clear(),this.L=this.L/1.1|0));if(n){if(n!==B)if(c){if(d[n])continue;d[n]=1}else{if(g===n)continue;g=n}e.push(n)}}}this.finalize&&(e=this.finalize(e)||e);this.cache&&a.length<=this.K&&(this.F.set(a,e),this.F.size>this.O&&(this.F.clear(),this.K=this.K/1.1|0));return e};function V(a){a.H=null;a.F.clear();a.G.clear()};function ka(a){W.call(a,"add");W.call(a,"append");W.call(a,"search");W.call(a,"update");W.call(a,"remove");W.call(a,"searchCache")}let la,ma,na;function oa(){la=na=0} -function W(a){this[a+"Async"]=function(){const c=arguments;var b=c[c.length-1];let e;"function"===typeof b&&(e=b,delete c[c.length-1]);la?na||(na=Date.now()-ma>=this.priority*this.priority*3):(la=setTimeout(oa,0),ma=Date.now());if(na){const f=this;return new Promise(g=>{setTimeout(function(){g(f[a+"Async"].apply(f,c))},0)})}const d=this[a].apply(this,c);b=d.then?d:new Promise(f=>f(d));e&&b.then(e);return b}};function pa(a,c=0){let b=[],e=[];c&&(c=25E4/c*5E3|0);for(const d of a.entries())e.push(d),e.length===c&&(b.push(e),e=[]);e.length&&b.push(e);return b}function qa(a,c){c||(c=new Map);for(let b=0,e;bc?c?a.slice(b,b+c):a.slice(b):a;let e=[];for(let d=0,f,g;d=g){b-=g;continue}bc&&(f=f.slice(0,c),g=c);if(!e.length&&g>=c)return f;e.push(f);c-=g;if(!c)break}return e=1D&&(D=l.length+(l?1:0)),t=l.length+(l?1:0)+K.length,C+=E,ja.push(v.length),v.push({match:K})),l+=(l?" ":"")+K)}if(!q)z=u[y],l+=(l?" ":"")+z,h&&v.push({text:z});else if(h&&C>=h)break}C=ja.length*(f.length-2);if(r||p||h&&l.length-C>h)if(C=h+C-2*x,y=t-D,0u&&(u=0)),v=v.length-1){if(F>=v.length){y[q+1]= -1;F>=u.length&&(C[q+1]=1);continue}E-=x}l=v[F].text;if(G=p&&J[q])if(0G)if(y[q+1]=1,m)l=l.substring(0,G);else continue;(G-=l.length)||(G=-1);J[q]=G}else{y[q+1]=1;continue}if(E+l.length+1<=h)l=" "+l,t[q]+=l;else if(m)O=h-E-1,0=F){if(0>F){y[q]=1;C[q]=1;continue}E-=x}l=v[F].text;if(G=r&&z[q])if(0G)if(y[q]=1,m)l=l.substring(l.length- -G);else continue;(G-=l.length)||(G=-1);z[q]=G}else{y[q]=1;continue}if(E+l.length+1<=h)l+=" ",t[q]=l+t[q];else if(m)O=l.length+1-(h-E),0<=O&&O=u.length-1?ua=1:Fb||e)a=a.slice(e,e+b);d&&(a=Ha.call(this,a));return a}}function Ha(a){if(!this||!this.store)return a;const c=Array(a.length);for(let b=0,e;bthis.maxlength)){if(c){if(d[n])continue;d[n]=1}else{if(f===n)continue;f=n}if(b)e.push(n);else if(!this.filter||("function"===typeof this.filter?this.filter(n):!this.filter.has(n))){if(this.cache&&n.length<=this.L)if(this.H){var h=this.G.get(n);if(h||""===h){h&&e.push(h);continue}}else this.H=setTimeout(V,50,this);if(this.stemmer){this.N||(this.N=new RegExp("(?!^)("+ +this.C+")$"));let x;for(;x!==n&&2this.stemmer.get(q))}if(n&&(this.mapper||this.dedupe&&1this.matcher.get(x)));if(n&&this.replacer)for(h=0;n&&hthis.O&&(this.G.clear(),this.L=this.L/1.1|0));if(n){if(n!==B)if(c){if(d[n])continue;d[n]=1}else{if(g===n)continue;g=n}e.push(n)}}}this.finalize&&(e=this.finalize(e)||e);this.cache&&a.length<=this.K&&(this.F.set(a,e),this.F.size>this.O&&(this.F.clear(),this.K=this.K/1.1|0));return e};function V(a){a.H=null;a.F.clear();a.G.clear()};function la(a){W.call(a,"add");W.call(a,"append");W.call(a,"search");W.call(a,"update");W.call(a,"remove");W.call(a,"searchCache")}let ma,na,oa;function pa(){ma=oa=0} +function W(a){this[a+"Async"]=function(){const c=arguments;var b=c[c.length-1];let e;"function"===typeof b&&(e=b,delete c[c.length-1]);ma?oa||(oa=Date.now()-na>=this.priority*this.priority*3):(ma=setTimeout(pa,0),na=Date.now());if(oa){const f=this;return new Promise(g=>{setTimeout(function(){g(f[a+"Async"].apply(f,c))},0)})}const d=this[a].apply(this,c);b=d.then?d:new Promise(f=>f(d));e&&b.then(e);return b}};function qa(a,c=0){let b=[],e=[];c&&(c=25E4/c*5E3|0);for(const d of a.entries())e.push(d),e.length===c&&(b.push(e),e=[]);e.length&&b.push(e);return b}function ra(a,c){c||(c=new Map);for(let b=0,e;bc?c?a.slice(b,b+c):a.slice(b):a;let e=[];for(let d=0,f,g;d=g){b-=g;continue}bc&&(f=f.slice(0,c),g=c);if(!e.length&&g>=c)return f;e.push(f);c-=g;if(!c)break}return e=1E&&(E=l.length+(l?1:0)),t=l.length+(l?1:0)+K.length,C+=D,ja.push(v.length),v.push({match:K})),l+=(l?" ":"")+K)}if(!p)z=u[y],l+=(l?" ":"")+z,h&&v.push({text:z});else if(h&&C>=h)break}C=ja.length*(f.length-2);if(q||r||h&&l.length-C>h)if(C=h+C-2*x,y=t-E,0u&&(u=0)),v=v.length-1){if(F>=v.length){y[p+1]= +1;F>=u.length&&(C[p+1]=1);continue}D-=x}l=v[F].text;if(G=r&&J[p])if(0G)if(y[p+1]=1,m)l=l.substring(0,G);else continue;(G-=l.length)||(G=-1);J[p]=G}else{y[p+1]=1;continue}if(D+l.length+1<=h)l=" "+l,t[p]+=l;else if(m)O=h-D-1,0=F){if(0>F){y[p]=1;C[p]=1;continue}D-=x}l=v[F].text;if(G=q&&z[p])if(0G)if(y[p]=1,m)l=l.substring(l.length- +G);else continue;(G-=l.length)||(G=-1);z[p]=G}else{y[p]=1;continue}if(D+l.length+1<=h)l+=" ",t[p]=l+t[p];else if(m)O=l.length+1-(h-D),0<=O&&O=u.length-1?ua=1:Fb||e)a=a.slice(e,e+b);d&&(a=Ha.call(this,a))}return a}function Ha(a){if(!this||!this.store)return a;const c=Array(a.length);for(let b=0,e;bthis.limit&&this.cache.delete(this.cache.keys().next().value)}; +A.set=function(a,c){"object"===typeof a&&(c=a,a=S(c,this.key));this.store.set(a,c);return this};A.searchCache=Ra; +A.export=function(a,c,b=0,e=0){if(bthis.limit&&this.cache.delete(this.cache.keys().next().value)}; Y.prototype.get=function(a){const c=this.cache.get(a);c&&this.h!==a&&(this.cache.delete(a),this.cache.set(this.h=a,c));return c};Y.prototype.remove=function(a){for(const c of this.cache){const b=c[0];c[1].includes(a)&&this.cache.delete(b)}};Y.prototype.clear=function(){this.cache.clear();this.h=""};Z.prototype.remove=function(a,c){const b=this.reg.size&&(this.fastupdate?this.reg.get(a):this.reg.has(a));if(b){if(this.fastupdate)for(let e=0,d;ed.length)d.pop();else{const f=d.indexOf(a);f===b.length-1?d.pop():d.splice(f,1)}}else Sa(this.map,a),this.depth&&Sa(this.ctx,a);c||this.reg.delete(a)}this.cache&&this.cache.remove(a);return this}; -function Sa(a,c){let b=0;var e="undefined"===typeof c;if(a.constructor===Array)for(let d=0,f,g;dw;f--){g=p.substring(w,f);l=this.rtl?d-1-w:w;var k=this.score?this.score(c,p,r,g,l):Ua(x, -m,r,d,l);Va(this,B,g,k,a,b)}break}case "bidirectional":case "reverse":if(1g?0:1),m,r,k-1,h-1),l=this.bidirectional&&p>f;Va(this,n,l?f:p,w,a,b,l?p:f)}}}}this.fastupdate||this.reg.add(a)}}return this};function Va(a,c,b,e,d,f,g){let k=g?a.ctx:a.map,h;if(!c[b]||g&&!(h=c[b])[g])g?(c=h||(c[b]=I()),c[g]=1,(h=k.get(g))?k=h:k.set(g,k=new Map)):c[b]=1,(h=k.get(b))?k=h:k.set(b,k=[]),k=k[e]||(k[e]=[]),f&&k.includes(d)||(k.push(d),a.fastupdate&&((c=a.reg.get(d))?c.push(k):a.reg.set(d,[k])))} -function Ua(a,c,b,e,d){return b&&1c||d?g.slice(d,c+d):g;g=b}else{if(b< -n){n=[];break b}g=g[b-1];if(c||d)if(g.length>c||d)g=g.slice(d,c+d)}n=g}else if(1===e){c=Ba.call(null,b[0],c,d);break a}c=n}return c};function Wa(a,c,b){let e;b&&(e=a.bidirectional&&c>b)&&(e=b,b=c,c=e);a=b?(a=a.ctx.get(b))&&a.get(c):a.map.get(c);return a};function Z(a,c){if(!this||this.constructor!==Z)return new Z(a);if(a){var b=N(a)?a:a.preset;b&&(a=Object.assign({},Ta[b],a))}else a={};b=a.context;const e=!0===b?{depth:1}:b||{},d=N(a.encoder)?Pa[a.encoder]:a.encode||a.encoder||{};this.encoder=d.encode?d:"object"===typeof d?new S(d):{encode:d};this.resolution=a.resolution||9;this.tokenize=b=(b=a.tokenize)&&"default"!==b&&"exact"!==b&&b||"strict";this.depth="strict"===b&&e.depth||0;this.bidirectional=!1!==e.bidirectional;this.fastupdate=!!a.fastupdate; +function Sa(a,c){let b=0;var e="undefined"===typeof c;if(a.constructor===Array)for(let d=0,f,g;dw;f--){g=r.substring(w,f);l=this.rtl?d-1-w:w;var k=this.score?this.score(c,r,q,g,l):Ua(x, +m,q,d,l);Va(this,B,g,k,a,b)}break}case "bidirectional":case "reverse":if(1g?0:1),m,q,k-1,h-1),l=this.bidirectional&&r>f;Va(this,n,l?f:r,w,a,b,l?r:f)}}}}this.fastupdate||this.reg.add(a)}}return this};function Va(a,c,b,e,d,f,g){let k=g?a.ctx:a.map,h;if(!c[b]||g&&!(h=c[b])[g])g?(c=h||(c[b]=N()),c[g]=1,(h=k.get(g))?k=h:k.set(g,k=new Map)):c[b]=1,(h=k.get(b))?k=h:k.set(b,k=[]),k=k[e]||(k[e]=[]),f&&k.includes(d)||(k.push(d),a.fastupdate&&((c=a.reg.get(d))?c.push(k):a.reg.set(d,[k])))} +function Ua(a,c,b,e,d){return b&&1c||d?g.slice(d,c+d):g;g=b}else{if(b< +n){n=[];break b}g=g[b-1];if(c||d)if(g.length>c||d)g=g.slice(d,c+d)}n=g}else if(1===e){c=Ca.call(null,b[0],c,d);break a}c=n}return c};function Wa(a,c,b){let e;b&&(e=a.bidirectional&&c>b)&&(e=b,b=c,c=e);a=b?(a=a.ctx.get(b))&&a.get(c):a.map.get(c);return a};function Z(a,c){if(!this||this.constructor!==Z)return new Z(a);if(a){var b=P(a)?a:a.preset;b&&(a=Object.assign({},Ta[b],a))}else a={};b=a.context;const e=!0===b?{depth:1}:b||{},d=P(a.encoder)?Pa[a.encoder]:a.encode||a.encoder||{};this.encoder=d.encode?d:"object"===typeof d?new ka(d):{encode:d};this.resolution=a.resolution||9;this.tokenize=b=(b=a.tokenize)&&"default"!==b&&"exact"!==b&&b||"strict";this.depth="strict"===b&&e.depth||0;this.bidirectional=!1!==e.bidirectional;this.fastupdate=!!a.fastupdate; this.score=a.score||null;b=!1;this.map=new Map;this.ctx=new Map;this.reg=c||(this.fastupdate?new Map:new Set);this.P=e.resolution||3;this.rtl=d.rtl||a.rtl||!1;this.cache=(b=a.cache||null)&&new Y(b);this.priority=a.priority||4}A=Z.prototype;A.clear=function(){this.map.clear();this.ctx.clear();this.reg.clear();this.cache&&this.cache.clear();return this};A.append=function(a,c){return this.add(a,c,!0)};A.contain=function(a){return this.reg.has(a)}; -A.update=function(a,c){const b=this,e=this.remove(a);return e&&e.then?e.then(()=>b.add(a,c)):this.add(a,c)};A.cleanup=function(){if(!this.fastupdate)return this;Sa(this.map);this.depth&&Sa(this.ctx);return this};A.searchCache=Ra;A.export=function(a,c,b=0,e=0){let d,f;switch(e){case 0:d="reg";f=va(this.reg);break;case 1:d="cfg";f=null;break;case 2:d="map";f=pa(this.map,this.reg.size);break;case 3:d="ctx";f=ra(this.ctx,this.reg.size);break;default:return}return xa.call(this,a,c,d,f,b,e)}; -A.import=function(a,c){if(c)switch("string"===typeof c&&(c=JSON.parse(c)),a=a.split("."),"json"===a[a.length-1]&&a.pop(),3===a.length&&a.shift(),a=1b.add(a,c)):this.add(a,c)};A.cleanup=function(){if(!this.fastupdate)return this;Sa(this.map);this.depth&&Sa(this.ctx);return this};A.searchCache=Ra;A.export=function(a,c,b=0,e=0){let d,f;switch(e){case 0:d="reg";f=wa(this.reg);break;case 1:d="cfg";f=null;break;case 2:d="map";f=qa(this.map,this.reg.size);break;case 3:d="ctx";f=sa(this.ctx,this.reg.size);break;default:return}return ya.call(this,a,c,d,f,b,e)}; +A.import=function(a,c){if(c)switch("string"===typeof c&&(c=JSON.parse(c)),a=a.split("."),"json"===a[a.length-1]&&a.pop(),3===a.length&&a.shift(),a=1 this.maxlength)) { if (b) { @@ -1085,7 +1088,7 @@ v.encode = function(a, b) { continue; } } else { - this.D = setTimeout(Ma, 50, this); + this.D = setTimeout(Na, 50, this); } } if (this.stemmer) { @@ -1135,13 +1138,13 @@ v.encode = function(a, b) { this.cache && a.length <= this.G && (this.B.set(a, e), this.B.size > this.T && (this.B.clear(), this.G = this.G / 1.1 | 0)); return e; }; -function Ma(a) { +function Na(a) { a.D = null; a.B.clear(); a.C.clear(); } -;var Na, Oa; -function Pa(a) { +;var Oa, Pa; +function Qa(a) { var b, c, d, e, f, g; return xa(function(h) { switch(h.h) { @@ -1152,8 +1155,8 @@ function Pa(a) { d = a.args; switch(b) { case "init": - Oa = a.options || {}; - (e = a.factory) ? (Function("return " + e)()(self), Na = new self.FlexSearch.Index(Oa), delete self.FlexSearch) : Na = new W(Oa); + Pa = a.options || {}; + (e = a.factory) ? (Function("return " + e)()(self), Oa = new self.FlexSearch.Index(Pa), delete self.FlexSearch) : Oa = new W(Pa); postMessage({id:c}); break; default: @@ -1163,22 +1166,22 @@ function Pa(a) { break; case 2: if ("export" === b) { - if (!Oa.export || "function" !== typeof Oa.export) { + if (!Pa.export || "function" !== typeof Pa.export) { throw Error('Either no extern configuration provided for the Worker-Index or no method was defined on the config property "export".'); } - d[1] ? (d[0] = Oa.export, d[2] = 0, d[3] = 1) : d = null; + d[1] ? (d[0] = Pa.export, d[2] = 0, d[3] = 1) : d = null; } if ("import" === b) { - if (!Oa.import || "function" !== typeof Oa.import) { + if (!Pa.import || "function" !== typeof Pa.import) { throw Error('Either no extern configuration provided for the Worker-Index or no method was defined on the config property "import".'); } if (!d[0]) { h.h = 5; break; } - return L(h, Oa.import.call(Na, d[0]), 9); + return L(h, Pa.import.call(Oa, d[0]), 9); } - f = d && Na[b].apply(Na, d); + f = d && Oa[b].apply(Oa, d); if (!f || !f.then) { h.h = 5; break; @@ -1189,33 +1192,33 @@ function Pa(a) { h.h = 5; break; case 9: - g = h.D, Na.import(d[0], g); + g = h.D, Oa.import(d[0], g); case 5: postMessage("search" === b ? {id:c, msg:f} : {id:c}), h.h = 0; } }); } -;function Qa(a) { - Ra.call(a, "add"); - Ra.call(a, "append"); - Ra.call(a, "search"); - Ra.call(a, "update"); - Ra.call(a, "remove"); - Ra.call(a, "searchCache"); +;function Ra(a) { + Sa.call(a, "add"); + Sa.call(a, "append"); + Sa.call(a, "search"); + Sa.call(a, "update"); + Sa.call(a, "remove"); + Sa.call(a, "searchCache"); } -var Sa, Ta, Ua; -function Va() { - Sa = Ua = 0; +var Ta, Ua, Va; +function Wa() { + Ta = Va = 0; } -function Ra(a) { +function Sa(a) { this[a + "Async"] = function() { var b = arguments, c = b[b.length - 1]; if ("function" === typeof c) { var d = c; delete b[b.length - 1]; } - Sa ? Ua || (Ua = Date.now() - Ta >= this.priority * this.priority * 3) : (Sa = setTimeout(Va, 0), Ta = Date.now()); - if (Ua) { + Ta ? Va || (Va = Date.now() - Ua >= this.priority * this.priority * 3) : (Ta = setTimeout(Wa, 0), Ua = Date.now()); + if (Va) { var e = this; return new Promise(function(g) { setTimeout(function() { @@ -1231,8 +1234,8 @@ function Ra(a) { return c; }; } -;var Wa = 0; -function Xa(a, b) { +;var Xa = 0; +function Ya(a, b) { function c(h) { function k(l) { l = l.data || l; @@ -1245,41 +1248,42 @@ function Xa(a, b) { e ? this.worker.on("message", k) : this.worker.onmessage = k; if (a.config) { return new Promise(function(l) { - f.h[++Wa] = function() { + f.h[++Xa] = function() { l(f); - 1e9 < Wa && (Wa = 0); + 1e9 < Xa && (Xa = 0); }; - f.worker.postMessage({id:Wa, task:"init", factory:d, options:a}); + f.worker.postMessage({id:Xa, task:"init", factory:d, options:a}); }); } - this.worker.postMessage({task:"init", factory:d, options:a}); this.priority = a.priority || 4; - b && (this.encoder = b); + this.encoder = b || null; + this.worker.postMessage({task:"init", factory:d, options:a}); return this; } } a = void 0 === a ? {} : a; - if (!this || this.constructor !== Xa) { - return new Xa(a); + if (!this || this.constructor !== Ya) { + return new Ya(a); } var d = "undefined" !== typeof self ? self._factory : "undefined" !== typeof window ? window._factory : null; d && (d = d.toString()); - var e = "undefined" === typeof window, f = this, g = Ya(d, e, a.worker); + var e = "undefined" === typeof window, f = this, g = Za(d, e, a.worker); return g.then ? g.then(function(h) { return c.call(f, h); }) : c.call(this, g); } -Za("add"); -Za("append"); -Za("search"); -Za("update"); -Za("remove"); -Za("clear"); -Za("export"); -Za("import"); -Qa(Xa.prototype); -function Za(a) { - Xa.prototype[a] = function() { +$a("add"); +$a("append"); +$a("search"); +$a("searchCache"); +$a("update"); +$a("remove"); +$a("clear"); +$a("export"); +$a("import"); +Ra(Ya.prototype); +function $a(a) { + Ya.prototype[a] = function() { var b = this, c = [].slice.call(arguments), d = c[c.length - 1]; if ("function" === typeof d) { var e = d; @@ -1287,17 +1291,17 @@ function Za(a) { } d = new Promise(function(f) { "export" === a && "function" === typeof c[0] && (c[0] = null); - b.h[++Wa] = f; - b.worker.postMessage({task:a, id:Wa, args:c}); + b.h[++Xa] = f; + b.worker.postMessage({task:a, id:Xa, args:c}); }); return e ? (d.then(e), this) : d; }; } -function Ya(a, b, c) { - return b ? "undefined" !== typeof module ? new(require("worker_threads")["Worker"])(__dirname+"/node/node.js") : import("worker_threads").then(function(worker){return new worker["Worker"]((1,eval)("import.meta.dirname")+"/node/node.mjs")}) : a ? new window.Worker(URL.createObjectURL(new Blob(["onmessage=" + Pa.toString()], {type:"text/javascript"}))) : new window.Worker("string" === typeof c ? c : (0,eval)("import.meta.url").replace("/worker.js", "/worker/worker.js").replace("flexsearch.bundle.module.min.js", +function Za(a, b, c) { + return b ? "undefined" !== typeof module ? new(require("worker_threads")["Worker"])(__dirname+"/node/node.js") : import("worker_threads").then(function(worker){return new worker["Worker"]((1,eval)("import.meta.dirname")+"/node/node.mjs")}) : a ? new window.Worker(URL.createObjectURL(new Blob(["onmessage=" + Qa.toString()], {type:"text/javascript"}))) : new window.Worker("string" === typeof c ? c : (0,eval)("import.meta.url").replace("/worker.js", "/worker/worker.js").replace("flexsearch.bundle.module.min.js", "module/worker/worker.js"), {type:"module"}); } -;function $a(a, b) { +;function ab(a, b) { b = void 0 === b ? 0 : b; var c = [], d = []; b && (b = 250000 / b * 5000 | 0); @@ -1308,32 +1312,32 @@ function Ya(a, b, c) { d.length && c.push(d); return c; } -function ab(a, b) { +function bb(a, b) { b || (b = new Map()); for (var c = 0, d; c < a.length; c++) { d = a[c], b.set(d[0], d[1]); } return b; } -function bb(a, b) { +function cb(a, b) { b = void 0 === b ? 0 : b; var c = [], d = []; b && (b = 250000 / b * 1000 | 0); a = A(a.entries()); for (var e = a.next(); !e.done; e = a.next()) { - e = e.value, d.push([e[0], $a(e[1])[0]]), d.length === b && (c.push(d), d = []); + e = e.value, d.push([e[0], ab(e[1])[0]]), d.length === b && (c.push(d), d = []); } d.length && c.push(d); return c; } -function cb(a, b) { +function db(a, b) { b || (b = new Map()); for (var c = 0, d, e; c < a.length; c++) { - d = a[c], e = b.get(d[0]), b.set(d[0], ab(d[1], e)); + d = a[c], e = b.get(d[0]), b.set(d[0], bb(d[1], e)); } return b; } -function db(a) { +function eb(a) { var b = [], c = []; a = A(a.keys()); for (var d = a.next(); !d.done; d = a.next()) { @@ -1342,14 +1346,14 @@ function db(a) { c.length && b.push(c); return b; } -function eb(a, b) { +function fb(a, b) { b || (b = new Set()); for (var c = 0; c < a.length; c++) { b.add(a[c]); } return b; } -function fb(a, b, c, d, e, f, g) { +function gb(a, b, c, d, e, f, g) { g = void 0 === g ? 0 : g; var h = d && d.constructor === Array, k = h ? d.shift() : d; if (!k) { @@ -1358,12 +1362,12 @@ function fb(a, b, c, d, e, f, g) { if ((k = a((b ? b + "." : "") + (g + 1) + "." + c, JSON.stringify(k))) && k.then) { var l = this; return k.then(function() { - return fb.call(l, a, b, c, h ? d : null, e, f, g + 1); + return gb.call(l, a, b, c, h ? d : null, e, f, g + 1); }); } - return fb.call(this, a, b, c, h ? d : null, e, f, g + 1); + return gb.call(this, a, b, c, h ? d : null, e, f, g + 1); } -function gb(a, b) { +function hb(a, b) { var c = ""; a = A(a.entries()); for (var d = a.next(); !d.done; d = a.next()) { @@ -1383,7 +1387,7 @@ function gb(a, b) { } return c; } -;function hb(a, b, c, d) { +;function ib(a, b, c, d) { for (var e = [], f = 0, g; f < a.index.length; f++) { if (g = a.index[f], b >= g.length) { b -= g.length; @@ -1399,9 +1403,9 @@ function gb(a, b) { } return e; } -function ib(a) { - if (!this || this.constructor !== ib) { - return new ib(a); +function jb(a) { + if (!this || this.constructor !== jb) { + return new jb(a); } this.index = a ? [a] : []; this.length = a ? a.length : 0; @@ -1448,12 +1452,12 @@ function ib(a) { } if ("slice" === d) { return function(e, f) { - return hb(b, e || 0, f || b.length, !1); + return ib(b, e || 0, f || b.length, !1); }; } if ("splice" === d) { return function(e, f) { - return hb(b, e || 0, f || b.length, !0); + return ib(b, e || 0, f || b.length, !0); }; } if ("constructor" === d) { @@ -1469,13 +1473,13 @@ function ib(a) { return !0; }}); } -ib.prototype.clear = function() { +jb.prototype.clear = function() { this.index.length = 0; }; -ib.prototype.destroy = function() { +jb.prototype.destroy = function() { this.proxy = this.index = null; }; -ib.prototype.push = function() { +jb.prototype.push = function() { }; function X(a) { a = void 0 === a ? 8 : a; @@ -1485,7 +1489,7 @@ function X(a) { this.index = S(); this.h = []; this.size = 0; - 32 < a ? (this.A = jb, this.B = BigInt(a)) : (this.A = kb, this.B = a); + 32 < a ? (this.A = kb, this.B = BigInt(a)) : (this.A = lb, this.B = a); } X.prototype.get = function(a) { var b = this.A(a); @@ -1503,7 +1507,7 @@ function Y(a) { this.index = S(); this.h = []; this.size = 0; - 32 < a ? (this.A = jb, this.B = BigInt(a)) : (this.A = kb, this.B = a); + 32 < a ? (this.A = kb, this.B = BigInt(a)) : (this.A = lb, this.B = a); } Y.prototype.add = function(a) { var b = this.A(a), c = this.index[b]; @@ -1523,9 +1527,9 @@ v.clear = Y.prototype.clear = function() { this.h = []; this.size = 0; }; -v.values = Y.prototype.values = function lb() { +v.values = Y.prototype.values = function mb() { var b, c = this, d, e, f; - return va(lb, function(g) { + return va(mb, function(g) { switch(g.h) { case 1: b = 0; @@ -1549,9 +1553,9 @@ v.values = Y.prototype.values = function lb() { } }); }; -v.keys = Y.prototype.keys = function mb() { +v.keys = Y.prototype.keys = function nb() { var b, c = this, d, e, f; - return va(mb, function(g) { + return va(nb, function(g) { switch(g.h) { case 1: b = 0; @@ -1575,9 +1579,9 @@ v.keys = Y.prototype.keys = function mb() { } }); }; -v.entries = Y.prototype.entries = function nb() { +v.entries = Y.prototype.entries = function ob() { var b, c = this, d, e, f; - return va(nb, function(g) { + return va(ob, function(g) { switch(g.h) { case 1: b = 0; @@ -1601,7 +1605,7 @@ v.entries = Y.prototype.entries = function nb() { } }); }; -function kb(a) { +function lb(a) { var b = Math.pow(2, this.B) - 1; if ("number" == typeof a) { return a & b; @@ -1611,11 +1615,11 @@ function kb(a) { } return 32 === this.B ? c + Math.pow(2, 31) : c; } -function jb() { +function kb() { throw Error("The keystore is limited to 32 for EcmaScript5"); } -;ob.prototype.add = function(a, b, c) { - Ca(a) && (b = a, a = Ea(b, this.key)); +;pb.prototype.add = function(a, b, c) { + Da(a) && (b = a, a = Fa(b, this.key)); if (b && (a || 0 === a)) { if (!c && this.reg.has(a)) { return this.update(a, b); @@ -1628,7 +1632,7 @@ function jb() { } else { var g = e.R; if (!g || g(b)) { - e.constructor === String ? e = ["" + e] : T(e) && (e = [e]), pb(b, e, this.S, 0, f, a, e[0], c); + e.constructor === String ? e = ["" + e] : T(e) && (e = [e]), qb(b, e, this.S, 0, f, a, e[0], c); } } } @@ -1648,7 +1652,7 @@ function jb() { continue; } g.constructor === String && (g = "" + g); - g = Ea(b, g); + g = Fa(b, g); } if (f && g) { for (T(g) && (g = [g]), h = 0, k = void 0; h < g.length; h++) { @@ -1659,7 +1663,7 @@ function jb() { (m = f.get(l)) ? k = m : f.set(l, k = []); if (!c || !k.includes(a)) { if (k.length === Math.pow(2, 31) - 1) { - m = new ib(k); + m = new jb(k); if (this.fastupdate) { for (var q = A(this.reg.values()), p = q.next(); !p.done; p = q.next()) { p = p.value, p.includes(k) && (p[p.indexOf(k)] = m); @@ -1693,7 +1697,7 @@ function jb() { n[d] = b[d]; continue; } - qb(b, n, d, 0, d[0], f); + rb(b, n, d, 0, d[0], f); } } } @@ -1703,21 +1707,21 @@ function jb() { } return this; }; -function qb(a, b, c, d, e, f) { +function rb(a, b, c, d, e, f) { a = a[e]; if (d === c.length - 1) { b[e] = f || a; } else if (a) { if (a.constructor === Array) { for (b = b[e] = Array(a.length), e = 0; e < a.length; e++) { - qb(a, b, c, d, e); + rb(a, b, c, d, e); } } else { - b = b[e] || (b[e] = S()), e = c[++d], qb(a, b, c, d, e); + b = b[e] || (b[e] = S()), e = c[++d], rb(a, b, c, d, e); } } } -function pb(a, b, c, d, e, f, g, h) { +function qb(a, b, c, d, e, f, g, h) { if (a = a[g]) { if (d === b.length - 1) { if (a.constructor === Array) { @@ -1733,22 +1737,22 @@ function pb(a, b, c, d, e, f, g, h) { } else { if (a.constructor === Array) { for (g = 0; g < a.length; g++) { - pb(a, b, c, d, e, f, g, h); + qb(a, b, c, d, e, f, g, h); } } else { - g = b[++d], pb(a, b, c, d, e, f, g, h); + g = b[++d], qb(a, b, c, d, e, f, g, h); } } } else { e.db && e.remove(f); } } -;function rb(a, b, c, d) { +;function sb(a, b, c, d) { if (!a.length) { return a; } if (1 === a.length) { - return a = a[0], a = c || a.length > b ? b ? a.slice(c, c + b) : a.slice(c) : a, d ? sb.call(this, a) : a; + return a = a[0], a = c || a.length > b ? b ? a.slice(c, c + b) : a.slice(c) : a, d ? tb.call(this, a) : a; } for (var e = [], f = 0, g = void 0, h = void 0; f < a.length; f++) { if ((g = a[f]) && (h = g.length)) { @@ -1761,7 +1765,7 @@ function pb(a, b, c, d, e, f, g, h) { } h > b && (g = g.slice(0, b), h = b); if (!e.length && h >= b) { - return d ? sb.call(this, g) : g; + return d ? tb.call(this, g) : g; } e.push(g); b -= h; @@ -1771,9 +1775,9 @@ function pb(a, b, c, d, e, f, g, h) { } } e = 1 < e.length ? [].concat.apply([], e) : e[0]; - return d ? sb.call(this, e) : e; + return d ? tb.call(this, e) : e; } -;function tb(a, b, c) { +;function ub(a, b, c) { var d = c[0]; if (d.then) { return Promise.all(c).then(function(x) { @@ -1835,10 +1839,10 @@ function pb(a, b, c, d, e, f, g, h) { return {W:d, $:e, limit:f, offset:g, enrich:h, resolve:k, suggest:l, highlight:m, ma:q}; } ;Z.prototype.or = function() { - var a = tb(this, "or", arguments); - return ub.call(this, a.W, a.$, a.limit, a.offset, a.enrich, a.resolve); + var a = ub(this, "or", arguments); + return vb.call(this, a.W, a.$, a.limit, a.offset, a.enrich, a.resolve); }; -function ub(a, b, c, d, e, f) { +function vb(a, b, c, d, e, f) { if (b.length) { var g = this; return Promise.all(b).then(function(h) { @@ -1846,10 +1850,10 @@ function ub(a, b, c, d, e, f) { for (var k = 0, l = void 0; k < h.length; k++) { (l = h[k]).length && (a[k] = l); } - return ub.call(g, a, [], c, d, e, f); + return vb.call(g, a, [], c, d, e, f); }); } - a.length && (this.result.length && a.push(this.result), 2 > a.length ? this.result = a[0] : (this.result = vb(a, c, d, !1, this.h), d = 0)); + a.length && (this.result.length && a.push(this.result), 2 > a.length ? this.result = a[0] : (this.result = wb(a, c, d, !1, this.h), d = 0)); return f ? this.resolve(c, d, e) : this; } ;Z.prototype.and = function() { @@ -1864,9 +1868,9 @@ function ub(a, b, c, d, e, f) { var f = b.enrich && c; } } - return a ? (a = tb(this, "and", arguments), wb.call(this, a.W, a.$, a.limit, a.offset, a.enrich, a.resolve, a.suggest)) : c ? this.resolve(d, e, f) : this; + return a ? (a = ub(this, "and", arguments), xb.call(this, a.W, a.$, a.limit, a.offset, a.enrich, a.resolve, a.suggest)) : c ? this.resolve(d, e, f) : this; }; -function wb(a, b, c, d, e, f, g) { +function xb(a, b, c, d, e, f, g) { if (b.length) { var h = this; return Promise.all(b).then(function(k) { @@ -1874,15 +1878,15 @@ function wb(a, b, c, d, e, f, g) { for (var l = 0, m = void 0; l < k.length; l++) { (m = k[l]).length && (a[l] = m); } - return wb.call(h, a, [], c, d, e, f, g); + return xb.call(h, a, [], c, d, e, f, g); }); } if (a.length) { if (this.result.length && a.unshift(this.result), 2 > a.length) { this.result = a[0]; } else { - if (b = Fa(a)) { - return this.result = xb(a, b, c, d, g, this.h, f), f ? e ? sb.call(this.index, this.result) : this.result : this; + if (b = Ga(a)) { + return this.result = yb(a, b, c, d, g, this.h, f), f ? e ? tb.call(this.index, this.result) : this.result : this; } this.result = []; } @@ -1892,10 +1896,10 @@ function wb(a, b, c, d, e, f, g) { return f ? this.resolve(c, d, e) : this; } ;Z.prototype.xor = function() { - var a = tb(this, "xor", arguments); - return yb.call(this, a.W, a.$, a.limit, a.offset, a.enrich, a.resolve, a.suggest); + var a = ub(this, "xor", arguments); + return zb.call(this, a.W, a.$, a.limit, a.offset, a.enrich, a.resolve, a.suggest); }; -function yb(a, b, c, d, e, f, g) { +function zb(a, b, c, d, e, f, g) { if (b.length) { var h = this; return Promise.all(b).then(function(k) { @@ -1903,21 +1907,21 @@ function yb(a, b, c, d, e, f, g) { for (var l = 0, m = void 0; l < k.length; l++) { (m = k[l]).length && (a[l] = m); } - return yb.call(h, a, [], c, d, e, f, g); + return zb.call(h, a, [], c, d, e, f, g); }); } if (a.length) { if (this.result.length && a.unshift(this.result), 2 > a.length) { this.result = a[0]; } else { - return this.result = zb.call(this, a, c, d, f, this.h), f ? e ? sb.call(this.index, this.result) : this.result : this; + return this.result = Ab.call(this, a, c, d, f, this.h), f ? e ? tb.call(this.index, this.result) : this.result : this; } } else { g || (this.result = a); } return f ? this.resolve(c, d, e) : this; } -function zb(a, b, c, d, e) { +function Ab(a, b, c, d, e) { for (var f = [], g = S(), h = 0, k = 0, l; k < a.length; k++) { if (l = a[k]) { h < l.length && (h = l.length); @@ -1961,10 +1965,10 @@ function zb(a, b, c, d, e) { return f; } ;Z.prototype.not = function() { - var a = tb(this, "not", arguments); - return Ab.call(this, a.W, a.$, a.limit, a.offset, a.enrich, a.resolve, a.suggest); + var a = ub(this, "not", arguments); + return Bb.call(this, a.W, a.$, a.limit, a.offset, a.enrich, a.resolve, a.suggest); }; -function Ab(a, b, c, d, e, f, g) { +function Bb(a, b, c, d, e, f, g) { if (b.length) { var h = this; return Promise.all(b).then(function(k) { @@ -1972,17 +1976,17 @@ function Ab(a, b, c, d, e, f, g) { for (var l = 0, m = void 0; l < k.length; l++) { (m = k[l]).length && (a[l] = m); } - return Ab.call(h, a, [], c, d, e, f, g); + return Bb.call(h, a, [], c, d, e, f, g); }); } if (a.length && this.result.length) { - this.result = Bb.call(this, a, c, d, f); + this.result = Cb.call(this, a, c, d, f); } else if (f) { return this.resolve(c, d, e); } - return f ? e ? sb.call(this.index, this.result) : this.result : this; + return f ? e ? tb.call(this.index, this.result) : this.result : this; } -function Bb(a, b, c, d) { +function Cb(a, b, c, d) { var e = []; a = new Set(a.flat().flat()); for (var f = 0, g, h = 0; f < this.result.length; f++) { @@ -2008,7 +2012,7 @@ function Bb(a, b, c, d) { } return e; } -;function Cb(a, b, c, d, e) { +;function Db(a, b, c, d, e) { if ("string" === typeof e) { var f = e; e = ""; @@ -2061,7 +2065,7 @@ function Bb(a, b, c, d) { "string" !== typeof u && (u = w.encode(a), q.set(w, u)); for (var y = 0; y < B.length; y++) { var t = B[y].doc; - if (t && (t = Ea(t, E))) { + if (t && (t = Fa(t, E))) { var D = t.trim().split(/\s+/); if (D.length) { t = ""; @@ -2288,10 +2292,10 @@ Z.prototype.boost = function(a) { Z.prototype.resolve = function(a, b, c) { var d = this.index, e = this.result; this.result = this.index = null; - e.length && ("object" === typeof a && (c = a.enrich, b = a.offset, a = a.limit), e = rb.call(d, e, a || 100, b, c)); + e.length && ("object" === typeof a && (c = a.enrich, b = a.offset, a = a.limit), e = sb.call(d, e, a || 100, b, c)); return e; }; -function xb(a, b, c, d, e, f, g) { +function yb(a, b, c, d, e, f, g) { var h = a.length, k = []; var l = S(); for (var m = 0, q = void 0, p, n; m < b; m++) { @@ -2316,7 +2320,7 @@ function xb(a, b, c, d, e, f, g) { } if (a = k.length) { if (e) { - k = 1 < k.length ? vb(k, c, d, g, f) : (k = k[0]).length > c || d ? k.slice(d, c + d) : k; + k = 1 < k.length ? wb(k, c, d, g, f) : (k = k[0]).length > c || d ? k.slice(d, c + d) : k; } else { if (a < h) { return []; @@ -2351,7 +2355,7 @@ function xb(a, b, c, d, e, f, g) { } return k; } -function vb(a, b, c, d, e) { +function wb(a, b, c, d, e) { var f = [], g = S(), h = a.length, k; if (d) { for (e = h - 1; 0 <= e; e--) { @@ -2394,7 +2398,7 @@ function vb(a, b, c, d, e) { } return f; } -function Db(a, b, c) { +function Eb(a, b, c) { for (var d = S(), e = [], f = 0, g; f < b.length; f++) { g = b[f]; for (var h = 0; h < g.length; h++) { @@ -2415,8 +2419,8 @@ function Db(a, b, c) { return e; } ;S(); -ob.prototype.search = function(a, b, c, d) { - c || (!b && Ca(a) ? (c = a, a = "") : Ca(b) && (c = b, b = 0)); +pb.prototype.search = function(a, b, c, d) { + c || (!b && Da(a) ? (c = a, a = "") : Da(b) && (c = b, b = 0)); if (c && c.cache) { c.cache = !1; var e = this.searchCache(a, b, c); @@ -2487,7 +2491,7 @@ ob.prototype.search = function(a, b, c, d) { } g.push(d = d.db.tag(w[n + 1], b, x, e)); } else { - d = Eb.call(this, w[n], w[n + 1], b, x, e); + d = Fb.call(this, w[n], w[n + 1], b, x, e); } f.push(k ? {field:w[n], tag:w[n + 1], result:d} : [d]); } @@ -2498,10 +2502,10 @@ ob.prototype.search = function(a, b, c, d) { for (var N = 0; N < G.length; N++) { k ? f[N].result = G[N] : f[N] = G[N]; } - return k ? f : new Z(1 < f.length ? xb(f, 1, 0, 0, r, q) : f[0], Q); + return k ? f : new Z(1 < f.length ? yb(f, 1, 0, 0, r, q) : f[0], Q); }); } - return k ? f : new Z(1 < f.length ? xb(f, 1, 0, 0, r, q) : f[0], this); + return k ? f : new Z(1 < f.length ? yb(f, 1, 0, 0, r, q) : f[0], this); } } if (!k && !l) { @@ -2520,7 +2524,7 @@ ob.prototype.search = function(a, b, c, d) { for (t = B = y = void 0; E < p.length; E++) { if (B = p[E], !this.db || !this.tag || this.L[E]) { y = void 0; - T(B) || (y = B, B = y.field, a = y.query || a, b = Fb(y.limit, b), x = Fb(y.offset, x), r = Fb(y.suggest, r), u = k && this.store && Fb(y.highlight, u), e = !!u || k && this.store && Fb(y.enrich, e)); + T(B) || (y = B, B = y.field, a = y.query || a, b = Ca(y.limit, b), x = Ca(y.offset, x), r = Ca(y.suggest, r), u = k && this.store && Ca(y.highlight, u), e = !!u || k && this.store && Ca(y.enrich, e)); if (d) { y = d[E]; } else { @@ -2576,7 +2580,7 @@ ob.prototype.search = function(a, b, c, d) { } } if (C) { - y = Db(y, D, k); + y = Eb(y, D, k); t = y.length; if (!t && !r) { return k ? y : new Z(y, this); @@ -2619,9 +2623,9 @@ ob.prototype.search = function(a, b, c, d) { w = []; for (x = 0; x < g.length; x++) { n = f[x]; - e && n.length && "undefined" === typeof n[0].doc && (this.db ? w.push(n = this.index.get(this.field[0]).db.enrich(n)) : n = sb.call(this, n)); + e && n.length && "undefined" === typeof n[0].doc && (this.db ? w.push(n = this.index.get(this.field[0]).db.enrich(n)) : n = tb.call(this, n)); if (l) { - return k ? u ? Cb(a, n, this.index, l, u) : n : new Z(n, this); + return k ? u ? Db(a, n, this.index, l, u) : n : new Z(n, this); } f[x] = {field:g[x], result:n}; } @@ -2631,38 +2635,45 @@ ob.prototype.search = function(a, b, c, d) { for (var N = 0; N < G.length; N++) { f[N].result = G[N]; } - return m ? Gb(f) : u ? Cb(a, f, V.index, l, u) : f; + u && (f = Db(a, f, V.index, l, u)); + return m ? Gb(f) : f; }); } - return m ? Gb(f) : u ? Cb(a, f, this.index, l, u) : f; + u && (f = Db(a, f, this.index, l, u)); + return m ? Gb(f) : f; }; -function Fb(a, b) { - return "undefined" === typeof a ? b : a; -} function Gb(a) { - for (var b = [], c = S(), d = 0, e, f; d < a.length; d++) { - e = a[d]; - f = e.result; - for (var g = 0, h, k, l; g < f.length; g++) { - k = f[g], "object" !== typeof k && (k = {id:k}), h = k.id, (l = c[h]) ? l.push(e.field) : (k.field = c[h] = [e.field], b.push(k)); + for (var b = [], c = S(), d = S(), e = 0, f, g, h = void 0, k, l, m; e < a.length; e++) { + f = a[e]; + g = f.field; + f = f.result; + for (var q = 0; q < f.length; q++) { + if (k = f[q], "object" !== typeof k ? k = {id:h = k} : h = k.id, (l = c[h]) ? l.push(g) : (k.field = c[h] = [g], b.push(k)), m = k.highlight) { + l = d[h], l || (d[h] = l = {}, k.highlight = l), l[g] = m; + } } } return b; } -function Eb(a, b, c, d, e) { - var f = this.tag.get(a); - if (!f) { - return console.warn("Tag-Field '" + a + "' was not found"), []; +function Fb(a, b, c, d, e) { + a = this.tag.get(a); + if (!a) { + return []; } - if ((a = (f = f && f.get(b)) && f.length - d) && 0 < a) { - if (c && a > c || d) { - f = f.slice(d, d + c); + a = a.get(b); + if (!a) { + return []; + } + b = a.length - d; + if (0 < b) { + if (c && b > c || d) { + a = a.slice(d, d + c); } - e && (f = sb.call(this, f)); - return f; + e && (a = tb.call(this, a)); } + return a; } -function sb(a) { +function tb(a) { if (!this || !this.store) { return a; } @@ -2683,9 +2694,9 @@ var Nb = {Exact:Hb, Default:Ib, Normalize:Ib, LatinBalance:{mapper:Jb}, LatinAdv a[b] = d; } }}, CJK:{split:""}, LatinExact:Hb, LatinDefault:Ib, LatinSimple:Ib}; -function ob(a) { - if (!this || this.constructor !== ob) { - return new ob(a); +function pb(a) { + if (!this || this.constructor !== pb) { + return new pb(a); } var b = a.document || a.doc || a, c, d; this.L = []; @@ -2744,7 +2755,7 @@ function ob(a) { a.db && (this.fastupdate = !1, this.mount(a.db)); } } -v = ob.prototype; +v = pb.prototype; v.mount = function(a) { if (this.worker) { throw Error("You can't use Worker-Indexes on a persistent model. That would be useless, since each of the persistent model acts like Worker-Index by default (Master/Slave)."); @@ -2805,10 +2816,10 @@ function Qb(a, b) { for (var e = 0, f, g = void 0; e < d.length; e++) { f = d[e]; T(f) || (g = f, f = f.field); - g = Ca(g) ? Object.assign({}, a, g) : a; + g = Da(g) ? Object.assign({}, a, g) : a; if (this.worker) { - var h = (h = g.encoder) && h.encode ? h : new La("string" === typeof h ? Nb[h] : h); - h = new Xa(g, h); + var h = (h = g.encoder) && h.encode ? h : new Ma("string" === typeof h ? Nb[h] : h); + h = new Ya(g, h); c.set(f, h); } this.worker || c.set(f, new W(g, this.reg)); @@ -2836,7 +2847,7 @@ v.update = function(a, b) { return this.remove(a).add(a, b); }; v.remove = function(a) { - Ca(a) && (a = Ea(a, this.key)); + Da(a) && (a = Fa(a, this.key)); for (var b = A(this.index.values()), c = b.next(); !c.done; c = b.next()) { c.value.remove(a, !0); } @@ -2887,7 +2898,7 @@ v.get = function(a) { }) : this.store.get(a) || null; }; v.set = function(a, b) { - "object" === typeof a && (b = a, a = Ea(b, this.key)); + "object" === typeof a && (b = a, a = Fa(b, this.key)); this.store.set(a, b); return this; }; @@ -2908,23 +2919,23 @@ v.export = function(a, b, c, d) { switch(d) { case 0: var g = "reg"; - var h = db(this.reg); + var h = eb(this.reg); b = null; break; case 1: g = "tag"; - h = this.tag && bb(this.tag, this.reg.size); + h = this.tag && cb(this.tag, this.reg.size); b = null; break; case 2: g = "doc"; - h = this.store && $a(this.store); + h = this.store && ab(this.store); b = null; break; default: return; } - return fb.call(this, a, b, g, h, c, d); + return gb.call(this, a, b, g, h, c, d); }; v.import = function(a, b) { var c = a.split("."); @@ -2942,7 +2953,7 @@ v.import = function(a, b) { switch(c) { case "reg": this.fastupdate = !1; - this.reg = eb(b, this.reg); + this.reg = fb(b, this.reg); for (b = 0; b < this.field.length; b++) { d = this.index.get(this.field[b]), d.fastupdate = !1, d.reg = this.reg; } @@ -2956,14 +2967,14 @@ v.import = function(a, b) { } break; case "tag": - this.tag = cb(b, this.tag); + this.tag = db(b, this.tag); break; case "doc": - this.store = ab(b, this.store); + this.store = bb(b, this.store); } } }; -Qa(ob.prototype); +Ra(pb.prototype); function Rb(a, b, c) { var d = (b ? "" + a : "object" === typeof a ? "" + a.query : a).toLowerCase(); this.cache || (this.cache = new Pb()); @@ -3119,7 +3130,7 @@ function Wb(a, b, c, d, e, f, g) { if (!b[c] || g && !(k = b[c])[g]) { if (g ? (b = k || (b[c] = S()), b[g] = 1, (k = h.get(g)) ? h = k : h.set(g, h = new Map())) : b[c] = 1, (k = h.get(c)) ? h = k : h.set(c, h = k = []), h = h[d] || (h[d] = []), !f || !h.includes(e)) { if (h.length === Math.pow(2, 31) - 1) { - b = new ib(h); + b = new jb(h); if (a.fastupdate) { for (c = A(a.reg.values()), f = c.next(); !f.done; f = c.next()) { f = f.value, f.includes(h) && (f[f.indexOf(h)] = b); @@ -3228,9 +3239,9 @@ function Vb(a, b, c, d, e) { function $b(a, b, c, d, e, f, g) { var h = a.length, k = a; if (1 < h) { - k = xb(a, b, c, d, e, f, g); + k = yb(a, b, c, d, e, f, g); } else if (1 === h) { - return g ? rb.call(null, a[0], c, d) : new Z(a[0], this); + return g ? sb.call(null, a[0], c, d) : new Z(a[0], this); } return g ? k : new Z(k, this); } @@ -3238,7 +3249,7 @@ function Xb(a, b, c, d, e, f, g) { a = Yb(this, a, b, c, d, e, f, g); return this.db ? a.then(function(h) { return e ? h || [] : new Z(h, this); - }) : a && a.length ? e ? rb.call(this, a, c, d) : new Z(a, this) : e ? [] : new Z([], this); + }) : a && a.length ? e ? sb.call(this, a, c, d) : new Z(a, this) : e ? [] : new Z([], this); } function Zb(a, b, c, d) { var e = []; @@ -3282,7 +3293,7 @@ function Yb(a, b, c, d, e, f, g, h) { } c = a.context; var d = !0 === c ? {depth:1} : c || {}, e = T(a.encoder) ? Nb[a.encoder] : a.encode || a.encoder || {}; - this.encoder = e.encode ? e : "object" === typeof e ? new La(e) : {encode:e}; + this.encoder = e.encode ? e : "object" === typeof e ? new Ma(e) : {encode:e}; this.resolution = a.resolution || 9; this.tokenize = c = (c = a.tokenize) && "default" !== c && "exact" !== c && c || "strict"; this.depth = "strict" === c && d.depth || 0; @@ -3360,7 +3371,7 @@ v.export = function(a, b, c, d) { switch(d) { case 0: var e = "reg"; - var f = db(this.reg); + var f = eb(this.reg); break; case 1: e = "cfg"; @@ -3368,29 +3379,29 @@ v.export = function(a, b, c, d) { break; case 2: e = "map"; - f = $a(this.map, this.reg.size); + f = ab(this.map, this.reg.size); break; case 3: e = "ctx"; - f = bb(this.ctx, this.reg.size); + f = cb(this.ctx, this.reg.size); break; default: return; } - return fb.call(this, a, b, e, f, c, d); + return gb.call(this, a, b, e, f, c, d); }; v.import = function(a, b) { if (b) { switch("string" === typeof b && (b = JSON.parse(b)), a = a.split("."), "json" === a[a.length - 1] && a.pop(), 3 === a.length && a.shift(), a = 1 < a.length ? a[1] : a[0], a) { case "reg": this.fastupdate = !1; - this.reg = eb(b, this.reg); + this.reg = fb(b, this.reg); break; case "map": - this.map = ab(b, this.map); + this.map = bb(b, this.map); break; case "ctx": - this.ctx = cb(b, this.ctx); + this.ctx = db(b, this.ctx); } } }; @@ -3404,13 +3415,13 @@ v.serialize = function(a) { f = f.value, e || (e = typeof f), b += (b ? "," : "") + ("string" === e ? '"' + f + '"' : f); } b = "index.reg=new Set([" + b + "]);"; - c = gb(this.map, e); + c = hb(this.map, e); c = "index.map=new Map([" + c + "]);"; f = A(this.ctx.entries()); for (var g = f.next(); !g.done; g = f.next()) { var h = g.value; g = h[0]; - h = gb(h[1], e); + h = hb(h[1], e); h = "new Map([" + h + "])"; h = '["' + g + '",' + h + "]"; d += (d ? "," : "") + h; @@ -3419,7 +3430,7 @@ v.serialize = function(a) { } return a ? "function inject(index){" + b + c + d + "}" : b + c + d; }; -Qa(W.prototype); +Ra(W.prototype); var ac = "undefined" !== typeof window && (window.indexedDB || window.mozIndexedDB || window.webkitIndexedDB || window.msIndexedDB), bc = ["map", "ctx", "tag", "reg", "cfg"], cc = S(); function dc(a, b) { b = void 0 === b ? {} : b; @@ -3614,7 +3625,7 @@ v.commit = function(a, b, c) { h.h = 3; break; } - c || (e = e.concat(Da(a.reg))); + c || (e = e.concat(Ea(a.reg))); if (!e.length) { h.h = 10; break; @@ -3782,7 +3793,7 @@ function ec(a, b) { a = null; }); } -;var gc = {Index:W, Charset:Nb, Encoder:La, Document:ob, Worker:Xa, Resolver:Z, IndexedDB:dc, Language:{}}, hc = "undefined" !== typeof self ? self : "undefined" !== typeof global ? global : self, ic; +;var gc = {Index:W, Charset:Nb, Encoder:Ma, Document:pb, Worker:Ya, Resolver:Z, IndexedDB:dc, Language:{}}, hc = "undefined" !== typeof self ? self : "undefined" !== typeof global ? global : self, ic; (ic = hc.define) && ic.amd ? ic([], function() { return gc; }) : "object" === typeof hc.exports ? hc.exports = gc : hc.FlexSearch = gc; diff --git a/dist/flexsearch.es5.min.js b/dist/flexsearch.es5.min.js index 9991f36..36678af 100644 --- a/dist/flexsearch.es5.min.js +++ b/dist/flexsearch.es5.min.js @@ -1,5 +1,5 @@ /**! - * FlexSearch.js v0.8.164 (ES5) + * FlexSearch.js v0.8.165 (ES5) * Author and Copyright: Thomas Wilkerling * Licence: Apache-2.0 * Hosted by Nextapps GmbH @@ -37,93 +37,93 @@ H("Array.prototype.includes",function(a){return a?a:function(b,c){var d=this;d i H("String.prototype.includes",function(a){return a?a:function(b,c){if(null==this)throw new TypeError("The 'this' value for String.prototype.includes must not be null or undefined");if(b instanceof RegExp)throw new TypeError("First argument to String.prototype.includes must not be a regular expression");return-1!==this.indexOf(b,c||0)}}); H("Array.prototype.flat",function(a){return a?a:function(b){b=void 0===b?1:b;var c=[];Array.prototype.forEach.call(this,function(d){Array.isArray(d)&&0"a1a".split(c).length; -this.numeric=O(a.numeric,e)}else{try{this.split=O(this.split,Ga)}catch(f){this.split=/\s+/}this.numeric=O(a.numeric,O(this.numeric,!0))}this.prepare=O(a.prepare,null,this.prepare);this.finalize=O(a.finalize,null,this.finalize);c=a.filter;this.filter="function"===typeof c?c:O(c&&new Set(c),null,this.filter);this.dedupe=O(a.dedupe,!0,this.dedupe);this.matcher=O((c=a.matcher)&&new Map(c),null,this.matcher);this.mapper=O((c=a.mapper)&&new Map(c),null,this.mapper);this.stemmer=O((c=a.stemmer)&&new Map(c), +this.numeric=O(a.numeric,e)}else{try{this.split=O(this.split,Ha)}catch(f){this.split=/\s+/}this.numeric=O(a.numeric,O(this.numeric,!0))}this.prepare=O(a.prepare,null,this.prepare);this.finalize=O(a.finalize,null,this.finalize);c=a.filter;this.filter="function"===typeof c?c:O(c&&new Set(c),null,this.filter);this.dedupe=O(a.dedupe,!0,this.dedupe);this.matcher=O((c=a.matcher)&&new Map(c),null,this.matcher);this.mapper=O((c=a.mapper)&&new Map(c),null,this.mapper);this.stemmer=O((c=a.stemmer)&&new Map(c), null,this.stemmer);this.replacer=O(a.replacer,null,this.replacer);this.minlength=O(a.minlength,1,this.minlength);this.maxlength=O(a.maxlength,1024,this.maxlength);this.rtl=O(a.rtl,!1,this.rtl);if(this.cache=c=O(a.cache,!0,this.cache))this.D=null,this.T="number"===typeof c?c:2E5,this.B=new Map,this.C=new Map,this.H=this.G=128;this.h="";this.M=null;this.A="";this.N=null;if(this.matcher)for(a=A(this.matcher.keys()),b=a.next();!b.done;b=a.next())this.h+=(this.h?"|":"")+b.value;if(this.stemmer)for(a=A(this.stemmer.keys()), -b=a.next();!b.done;b=a.next())this.A+=(this.A?"|":"")+b.value;return this};v.addStemmer=function(a,b){this.stemmer||(this.stemmer=new Map);this.stemmer.set(a,b);this.A+=(this.A?"|":"")+a;this.N=null;this.cache&&Ma(this);return this};v.addFilter=function(a){"function"===typeof a?this.filter=a:(this.filter||(this.filter=new Set),this.filter.add(a));this.cache&&Ma(this);return this}; -v.addMapper=function(a,b){if("object"===typeof a)return this.addReplacer(a,b);if(1a.length&&(this.dedupe||this.mapper))return this.addMapper(a,b);this.matcher||(this.matcher=new Map);this.matcher.set(a,b);this.h+=(this.h?"|":"")+a;this.M=null;this.cache&&Ma(this);return this}; -v.addReplacer=function(a,b){if("string"===typeof a)return this.addMatcher(a,b);this.replacer||(this.replacer=[]);this.replacer.push(a,b);this.cache&&Ma(this);return this}; -v.encode=function(a,b){var c=this;if(this.cache&&a.length<=this.G)if(this.D){if(this.B.has(a))return this.B.get(a)}else this.D=setTimeout(Ma,50,this);this.normalize&&("function"===typeof this.normalize?a=this.normalize(a):a=Ka?a.normalize("NFKD").replace(Ka,"").toLowerCase():a.toLowerCase());this.prepare&&(a=this.prepare(a));this.numeric&&3this.maxlength)){if(b){if(f[m])continue;f[m]=1}else{if(g===m)continue;g=m}if(d)e.push(m);else if(!this.filter||("function"===typeof this.filter?this.filter(m):!this.filter.has(m))){if(this.cache&&m.length<=this.H)if(this.D){var p=this.C.get(m);if(p||""===p){p&&e.push(p);continue}}else this.D=setTimeout(Ma,50,this);if(this.stemmer)for(this.N|| +b=a.next();!b.done;b=a.next())this.A+=(this.A?"|":"")+b.value;return this};v.addStemmer=function(a,b){this.stemmer||(this.stemmer=new Map);this.stemmer.set(a,b);this.A+=(this.A?"|":"")+a;this.N=null;this.cache&&Na(this);return this};v.addFilter=function(a){"function"===typeof a?this.filter=a:(this.filter||(this.filter=new Set),this.filter.add(a));this.cache&&Na(this);return this}; +v.addMapper=function(a,b){if("object"===typeof a)return this.addReplacer(a,b);if(1a.length&&(this.dedupe||this.mapper))return this.addMapper(a,b);this.matcher||(this.matcher=new Map);this.matcher.set(a,b);this.h+=(this.h?"|":"")+a;this.M=null;this.cache&&Na(this);return this}; +v.addReplacer=function(a,b){if("string"===typeof a)return this.addMatcher(a,b);this.replacer||(this.replacer=[]);this.replacer.push(a,b);this.cache&&Na(this);return this}; +v.encode=function(a,b){var c=this;if(this.cache&&a.length<=this.G)if(this.D){if(this.B.has(a))return this.B.get(a)}else this.D=setTimeout(Na,50,this);this.normalize&&("function"===typeof this.normalize?a=this.normalize(a):a=La?a.normalize("NFKD").replace(La,"").toLowerCase():a.toLowerCase());this.prepare&&(a=this.prepare(a));this.numeric&&3this.maxlength)){if(b){if(f[m])continue;f[m]=1}else{if(g===m)continue;g=m}if(d)e.push(m);else if(!this.filter||("function"===typeof this.filter?this.filter(m):!this.filter.has(m))){if(this.cache&&m.length<=this.H)if(this.D){var p=this.C.get(m);if(p||""===p){p&&e.push(p);continue}}else this.D=setTimeout(Na,50,this);if(this.stemmer)for(this.N|| (this.N=new RegExp("(?!^)("+this.A+")$")),p=void 0;p!==m&&2this.T&&(this.C.clear(),this.H=this.H/1.1|0));if(m){if(m!==q)if(b){if(f[m])continue;f[m]=1}else{if(h===m)continue;h=m}e.push(m)}}}this.finalize&&(e=this.finalize(e)||e);this.cache&&a.length<=this.G&&(this.B.set(a,e),this.B.size>this.T&&(this.B.clear(),this.G=this.G/1.1|0));return e};function Ma(a){a.D=null;a.B.clear();a.C.clear()};var Na,Oa; -function Pa(a){var b,c,d,e,f,g;return xa(function(h){switch(h.h){case 1:a=a.data;b=a.task;c=a.id;d=a.args;switch(b){case "init":Oa=a.options||{};(e=a.factory)?(Function("return "+e)()(self),Na=new self.FlexSearch.Index(Oa),delete self.FlexSearch):Na=new W(Oa);postMessage({id:c});break;default:h.h=2;return}h.h=0;break;case 2:"export"===b&&(d[1]?(d[0]=Oa.export,d[2]=0,d[3]=1):d=null);if("import"===b){if(!d[0]){h.h=5;break}return L(h,Oa.import.call(Na,d[0]),9)}f=d&&Na[b].apply(Na,d);if(!f||!f.then){h.h= -5;break}return L(h,f,7);case 7:f=h.D;h.h=5;break;case 9:g=h.D,Na.import(d[0],g);case 5:postMessage("search"===b?{id:c,msg:f}:{id:c}),h.h=0}})};function Qa(a){Ra.call(a,"add");Ra.call(a,"append");Ra.call(a,"search");Ra.call(a,"update");Ra.call(a,"remove");Ra.call(a,"searchCache")}var Sa,Ta,Ua;function Va(){Sa=Ua=0} -function Ra(a){this[a+"Async"]=function(){var b=arguments,c=b[b.length-1];if("function"===typeof c){var d=c;delete b[b.length-1]}Sa?Ua||(Ua=Date.now()-Ta>=this.priority*this.priority*3):(Sa=setTimeout(Va,0),Ta=Date.now());if(Ua){var e=this;return new Promise(function(g){setTimeout(function(){g(e[a+"Async"].apply(e,b))},0)})}var f=this[a].apply(this,b);c=f.then?f:new Promise(function(g){return g(f)});d&&c.then(d);return c}};var Wa=0; -function Xa(a,b){function c(h){function k(l){l=l.data||l;var m=l.id,q=m&&f.h[m];q&&(q(l.msg),delete f.h[m])}this.worker=h;this.h=S();if(this.worker){e?this.worker.on("message",k):this.worker.onmessage=k;if(a.config)return new Promise(function(l){f.h[++Wa]=function(){l(f);1E9=g.length)b-=g.length;else{b=g[d?"splice":"slice"](b,c);if(g=b.length)if(e=e.length?e.concat(b):b,c-=g,d&&(a.length-=g),!c)break;b=0}return e} -function ib(a){if(!this||this.constructor!==ib)return new ib(a);this.index=a?[a]:[];this.length=a?a.length:0;var b=this;return new Proxy([],{get:function(c,d){if("length"===d)return b.length;if("push"===d)return function(e){b.index[b.index.length-1].push(e);b.length++};if("pop"===d)return function(){if(b.length)return b.length--,b.index[b.index.length-1].pop()};if("indexOf"===d)return function(e){for(var f=0,g=0,h,k;gthis.T&&(this.C.clear(),this.H=this.H/1.1|0));if(m){if(m!==q)if(b){if(f[m])continue;f[m]=1}else{if(h===m)continue;h=m}e.push(m)}}}this.finalize&&(e=this.finalize(e)||e);this.cache&&a.length<=this.G&&(this.B.set(a,e),this.B.size>this.T&&(this.B.clear(),this.G=this.G/1.1|0));return e};function Na(a){a.D=null;a.B.clear();a.C.clear()};var Oa,Pa; +function Qa(a){var b,c,d,e,f,g;return xa(function(h){switch(h.h){case 1:a=a.data;b=a.task;c=a.id;d=a.args;switch(b){case "init":Pa=a.options||{};(e=a.factory)?(Function("return "+e)()(self),Oa=new self.FlexSearch.Index(Pa),delete self.FlexSearch):Oa=new W(Pa);postMessage({id:c});break;default:h.h=2;return}h.h=0;break;case 2:"export"===b&&(d[1]?(d[0]=Pa.export,d[2]=0,d[3]=1):d=null);if("import"===b){if(!d[0]){h.h=5;break}return L(h,Pa.import.call(Oa,d[0]),9)}f=d&&Oa[b].apply(Oa,d);if(!f||!f.then){h.h= +5;break}return L(h,f,7);case 7:f=h.D;h.h=5;break;case 9:g=h.D,Oa.import(d[0],g);case 5:postMessage("search"===b?{id:c,msg:f}:{id:c}),h.h=0}})};function Ra(a){Sa.call(a,"add");Sa.call(a,"append");Sa.call(a,"search");Sa.call(a,"update");Sa.call(a,"remove");Sa.call(a,"searchCache")}var Ta,Ua,Va;function Wa(){Ta=Va=0} +function Sa(a){this[a+"Async"]=function(){var b=arguments,c=b[b.length-1];if("function"===typeof c){var d=c;delete b[b.length-1]}Ta?Va||(Va=Date.now()-Ua>=this.priority*this.priority*3):(Ta=setTimeout(Wa,0),Ua=Date.now());if(Va){var e=this;return new Promise(function(g){setTimeout(function(){g(e[a+"Async"].apply(e,b))},0)})}var f=this[a].apply(this,b);c=f.then?f:new Promise(function(g){return g(f)});d&&c.then(d);return c}};var Xa=0; +function Ya(a,b){function c(h){function k(l){l=l.data||l;var m=l.id,q=m&&f.h[m];q&&(q(l.msg),delete f.h[m])}this.worker=h;this.h=S();if(this.worker){e?this.worker.on("message",k):this.worker.onmessage=k;if(a.config)return new Promise(function(l){f.h[++Xa]=function(){l(f);1E9=g.length)b-=g.length;else{b=g[d?"splice":"slice"](b,c);if(g=b.length)if(e=e.length?e.concat(b):b,c-=g,d&&(a.length-=g),!c)break;b=0}return e} +function jb(a){if(!this||this.constructor!==jb)return new jb(a);this.index=a?[a]:[];this.length=a?a.length:0;var b=this;return new Proxy([],{get:function(c,d){if("length"===d)return b.length;if("push"===d)return function(e){b.index[b.index.length-1].push(e);b.length++};if("pop"===d)return function(){if(b.length)return b.length--,b.index[b.index.length-1].pop()};if("indexOf"===d)return function(e){for(var f=0,g=0,h,k;gb?b?a.slice(c,c+b):a.slice(c):a,d?sb.call(this,a):a;for(var e=[],f=0,g=void 0,h=void 0;f=h){c-=h;continue}cb&&(g=g.slice(0,b),h=b);if(!e.length&&h>=b)return d?sb.call(this,g):g;e.push(g);b-=h;if(!b)break}e=1a.length?this.result=a[0]:(this.result=vb(a,c,d,!1,this.h),d=0));return f?this.resolve(c,d,e):this};Z.prototype.and=function(){var a=this.result.length;if(!a){var b=arguments[0];if(b){a=!!b.suggest;var c=b.resolve;var d=b.limit;var e=b.offset;var f=b.enrich&&c}}return a?(a=tb(this,"and",arguments),wb.call(this,a.W,a.$,a.limit,a.offset,a.enrich,a.resolve,a.suggest)):c?this.resolve(d,e,f):this}; -function wb(a,b,c,d,e,f,g){if(b.length){var h=this;return Promise.all(b).then(function(k){a=[];for(var l=0,m=void 0;la.length)this.result=a[0];else{if(b=Fa(a))return this.result=xb(a,b,c,d,g,this.h,f),f?e?sb.call(this.index,this.result):this.result:this;this.result=[]}else g||(this.result=a);return f?this.resolve(c,d,e):this};Z.prototype.xor=function(){var a=tb(this,"xor",arguments);return yb.call(this,a.W,a.$,a.limit,a.offset,a.enrich,a.resolve,a.suggest)}; -function yb(a,b,c,d,e,f,g){if(b.length){var h=this;return Promise.all(b).then(function(k){a=[];for(var l=0,m=void 0;la.length)this.result=a[0];else return this.result=zb.call(this,a,c,d,f,this.h),f?e?sb.call(this.index,this.result):this.result:this;else g||(this.result=a);return f?this.resolve(c,d,e):this} -function zb(a,b,c,d,e){for(var f=[],g=S(),h=0,k=0,l;kb?b?a.slice(c,c+b):a.slice(c):a,d?tb.call(this,a):a;for(var e=[],f=0,g=void 0,h=void 0;f=h){c-=h;continue}cb&&(g=g.slice(0,b),h=b);if(!e.length&&h>=b)return d?tb.call(this,g):g;e.push(g);b-=h;if(!b)break}e=1a.length?this.result=a[0]:(this.result=wb(a,c,d,!1,this.h),d=0));return f?this.resolve(c,d,e):this};Z.prototype.and=function(){var a=this.result.length;if(!a){var b=arguments[0];if(b){a=!!b.suggest;var c=b.resolve;var d=b.limit;var e=b.offset;var f=b.enrich&&c}}return a?(a=ub(this,"and",arguments),xb.call(this,a.W,a.$,a.limit,a.offset,a.enrich,a.resolve,a.suggest)):c?this.resolve(d,e,f):this}; +function xb(a,b,c,d,e,f,g){if(b.length){var h=this;return Promise.all(b).then(function(k){a=[];for(var l=0,m=void 0;la.length)this.result=a[0];else{if(b=Ga(a))return this.result=yb(a,b,c,d,g,this.h,f),f?e?tb.call(this.index,this.result):this.result:this;this.result=[]}else g||(this.result=a);return f?this.resolve(c,d,e):this};Z.prototype.xor=function(){var a=ub(this,"xor",arguments);return zb.call(this,a.W,a.$,a.limit,a.offset,a.enrich,a.resolve,a.suggest)}; +function zb(a,b,c,d,e,f,g){if(b.length){var h=this;return Promise.all(b).then(function(k){a=[];for(var l=0,m=void 0;la.length)this.result=a[0];else return this.result=Ab.call(this,a,c,d,f,this.h),f?e?tb.call(this.index,this.result):this.result:this;else g||(this.result=a);return f?this.resolve(c,d,e):this} +function Ab(a,b,c,d,e){for(var f=[],g=S(),h=0,k=0,l;kQ&&(Q=t.length+(t?1:0)),M=t.length+(t?1:0)+ba.length,J+=N,P.push(C.length),C.push({match:ba})),t+=(t?" ":"")+ba)}if(!G)R=D[F],t+=(t?" ":"")+R,k&&C.push({text:R});else if(k&&J>=k)break}J=P.length*(f.length-2);if(n||r||k&&t.length-J>k)if(J=k+J-2*p,F=M-Q,0D&&(D=0)),C=C.length-1){if(K>=C.length){F[z+1]=1;K>=D.length&&(Q[z+1]=1);continue}G-=p}t=C[K].text;var U=r&&V[z]; if(U)if(0U)if(F[z+1]=1,l)t=t.substring(0,U);else continue;(U-=t.length)||(U=-1);V[z]=U}else{F[z+1]=1;continue}if(G+t.length+1<=k)t=" "+t,M[z]+=t;else if(l)I=k-G-1,0=K){if(0>K){F[z]=1;Q[z]=1;continue}G-=p}t=C[K].text;if(U=n&&R[z])if(0U)if(F[z]=1,l)t=t.substring(t.length-U);else continue;(U-=t.length)||(U=-1);R[z]=U}else{F[z]=1;continue}if(G+ t.length+1<=k)t+=" ",M[z]=t+M[z];else if(l)I=t.length+1-(k-G),0<=I&&I=D.length-1?I=1:Kc||d?k.slice(d,c+d):k;else{if(ac||d)k=k.slice(d,c+ +Z.prototype.offset=function(a){if(this.result.length){for(var b=[],c=0,d;cc||d?k.slice(d,c+d):k;else{if(ac||d)k=k.slice(d,c+ d)}else{e=[];for(f=0;fd)d-=g.length;else{if(c&&g.length>c||d)g=g.slice(d,c+d),c-=g.length,d&&(d-=g.length);e.push(g);if(!c)break}k=e}}return k} -function vb(a,b,c,d,e){var f=[],g=S(),h=a.length,k;if(d)for(e=h-1;0<=e;e--){if(k=(d=a[e])&&d.length)for(h=0;hc||d)a=a.slice(d,d+c);e&&(a=sb.call(this,a));return a}} -function sb(a){if(!this||!this.store)return a;for(var b=Array(a.length),c=0,d;cc||d)a=a.slice(d,d+c);e&&(a=tb.call(this,a))}return a} +function tb(a){if(!this||!this.store)return a;for(var b=Array(a.length),c=0,d;cthis.limit&&this.cache.delete(this.cache.keys().next().value)}; +v.cleanup=function(){for(var a=A(this.index.values()),b=a.next();!b.done;b=a.next())b.value.cleanup();return this};v.get=function(a){return this.db?this.index.get(this.field[0]).db.enrich(a).then(function(b){return b[0]&&b[0].doc||null}):this.store.get(a)||null};v.set=function(a,b){"object"===typeof a&&(b=a,a=Fa(b,this.key));this.store.set(a,b);return this};v.searchCache=Rb; +v.export=function(a,b,c,d){c=void 0===c?0:c;d=void 0===d?0:d;if(cthis.limit&&this.cache.delete(this.cache.keys().next().value)}; Pb.prototype.get=function(a){var b=this.cache.get(a);b&&this.h!==a&&(this.cache.delete(a),this.cache.set(this.h=a,b));return b};Pb.prototype.remove=function(a){for(var b=A(this.cache),c=b.next();!c.done;c=b.next()){c=c.value;var d=c[0];c[1].includes(a)&&this.cache.delete(d)}};Pb.prototype.clear=function(){this.cache.clear();this.h=""};W.prototype.remove=function(a,b){var c=this.reg.size&&(this.fastupdate?this.reg.get(a):this.reg.has(a));if(c){if(this.fastupdate)for(var d=0,e;de.length)e.pop();else{var f=e.indexOf(a);f===c.length-1?e.pop():e.splice(f,1)}}else Sb(this.map,a),this.depth&&Sb(this.ctx,a);b||this.reg.delete(a)}this.db&&(this.commit_task.push({del:a}),this.ca&&Tb(this));this.cache&&this.cache.remove(a);return this}; function Sb(a,b){var c=0,d="undefined"===typeof b;if(a.constructor===Array)for(var e=0,f=void 0,g;eq;r--)p=l.substring(q,r),n=this.rtl?m-1-q:q,n=this.score?this.score(b,l,k,p,n):Vb(h,e,k,m,n),Wb(this, g,p,n,a,c);break}case "bidirectional":case "reverse":if(1p?0:1),e,k,r-1,n-1),w=this.bidirectional&& l>q;Wb(this,f,w?q:l,u,a,c,w?l:q)}}}}this.fastupdate||this.reg.add(a)}else b=""}this.db&&(b||this.commit_task.push({del:a}),this.ca&&Tb(this));return this}; -function Wb(a,b,c,d,e,f,g){var h=g?a.ctx:a.map,k;if(!b[c]||g&&!(k=b[c])[g])if(g?(b=k||(b[c]=S()),b[g]=1,(k=h.get(g))?h=k:h.set(g,h=new Map)):b[c]=1,(k=h.get(c))?h=k:h.set(c,h=k=[]),h=h[d]||(h[d]=[]),!f||!h.includes(e)){if(h.length===Math.pow(2,31)-1){b=new ib(h);if(a.fastupdate)for(c=A(a.reg.values()),f=c.next();!f.done;f=c.next())f=f.value,f.includes(h)&&(f[f.indexOf(h)]=b);k[d]=h=b}h.push(e);a.fastupdate&&((d=a.reg.get(e))?d.push(h):a.reg.set(e,[h]))}} +function Wb(a,b,c,d,e,f,g){var h=g?a.ctx:a.map,k;if(!b[c]||g&&!(k=b[c])[g])if(g?(b=k||(b[c]=S()),b[g]=1,(k=h.get(g))?h=k:h.set(g,h=new Map)):b[c]=1,(k=h.get(c))?h=k:h.set(c,h=k=[]),h=h[d]||(h[d]=[]),!f||!h.includes(e)){if(h.length===Math.pow(2,31)-1){b=new jb(h);if(a.fastupdate)for(c=A(a.reg.values()),f=c.next();!f.done;f=c.next())f=f.value,f.includes(h)&&(f[f.indexOf(h)]=b);k[d]=h=b}h.push(e);a.fastupdate&&((d=a.reg.get(e))?d.push(h):a.reg.set(e,[h]))}} function Vb(a,b,c,d,e){return c&&1c)&&(k=c,c=b,b=k);if(a.db)return a.db.get(b,c,d,e,f,g,h);a=c?(a=a.ctx.get(c))&&a.get(b):a.map.get(b);return a};function W(a,b){if(!this||this.constructor!==W)return new W(a);if(a){var c=T(a)?a:a.preset;c&&(a=Object.assign({},Ub[c],a))}else a={};c=a.context;var d=!0===c?{depth:1}:c||{},e=T(a.encoder)?Nb[a.encoder]:a.encode||a.encoder||{};this.encoder=e.encode?e:"object"===typeof e?new La(e):{encode:e};this.resolution=a.resolution||9;this.tokenize=c=(c=a.tokenize)&&"default"!==c&&"exact"!==c&&c||"strict";this.depth="strict"===c&&d.depth||0;this.bidirectional=!1!==d.bidirectional;this.fastupdate=!!a.fastupdate; +function $b(a,b,c,d,e,f,g){var h=a.length,k=a;if(1c)&&(k=c,c=b,b=k);if(a.db)return a.db.get(b,c,d,e,f,g,h);a=c?(a=a.ctx.get(c))&&a.get(b):a.map.get(b);return a};function W(a,b){if(!this||this.constructor!==W)return new W(a);if(a){var c=T(a)?a:a.preset;c&&(a=Object.assign({},Ub[c],a))}else a={};c=a.context;var d=!0===c?{depth:1}:c||{},e=T(a.encoder)?Nb[a.encoder]:a.encode||a.encoder||{};this.encoder=e.encode?e:"object"===typeof e?new Ma(e):{encode:e};this.resolution=a.resolution||9;this.tokenize=c=(c=a.tokenize)&&"default"!==c&&"exact"!==c&&c||"strict";this.depth="strict"===c&&d.depth||0;this.bidirectional=!1!==d.bidirectional;this.fastupdate=!!a.fastupdate; this.score=a.score||null;(c=a.keystore||0)&&(this.keystore=c);this.map=c?new X(c):new Map;this.ctx=c?new X(c):new Map;this.reg=b||(this.fastupdate?c?new X(c):new Map:c?new Y(c):new Set);this.da=d.resolution||3;this.rtl=e.rtl||a.rtl||!1;this.cache=(c=a.cache||null)&&new Pb(c);this.resolve=!1!==a.resolve;if(c=a.db)this.db=this.mount(c);this.ca=!1!==a.commit;this.commit_task=[];this.commit_timer=null;this.priority=a.priority||4}v=W.prototype; v.mount=function(a){this.commit_timer&&(clearTimeout(this.commit_timer),this.commit_timer=null);return a.mount(this)};v.commit=function(a,b){this.commit_timer&&(clearTimeout(this.commit_timer),this.commit_timer=null);return this.db.commit(this,a,b)};v.destroy=function(){this.commit_timer&&(clearTimeout(this.commit_timer),this.commit_timer=null);return this.db.destroy()};function Tb(a){a.commit_timer||(a.commit_timer=setTimeout(function(){a.commit_timer=null;a.db.commit(a,void 0,void 0)},1))} v.clear=function(){this.map.clear();this.ctx.clear();this.reg.clear();this.cache&&this.cache.clear();this.db&&(this.commit_timer&&clearTimeout(this.commit_timer),this.commit_timer=null,this.commit_task=[{clear:!0}]);return this};v.append=function(a,b){return this.add(a,b,!0)};v.contain=function(a){return this.db?this.db.has(a):this.reg.has(a)};v.update=function(a,b){var c=this,d=this.remove(a);return d&&d.then?d.then(function(){return c.add(a,b)}):this.add(a,b)}; -v.cleanup=function(){if(!this.fastupdate)return this;Sb(this.map);this.depth&&Sb(this.ctx);return this};v.searchCache=Rb;v.export=function(a,b,c,d){c=void 0===c?0:c;d=void 0===d?0:d;switch(d){case 0:var e="reg";var f=db(this.reg);break;case 1:e="cfg";f=null;break;case 2:e="map";f=$a(this.map,this.reg.size);break;case 3:e="ctx";f=bb(this.ctx,this.reg.size);break;default:return}return fb.call(this,a,b,e,f,c,d)}; -v.import=function(a,b){if(b)switch("string"===typeof b&&(b=JSON.parse(b)),a=a.split("."),"json"===a[a.length-1]&&a.pop(),3===a.length&&a.shift(),a=1=f.length)return[];if(!b&&!c)return f;f=f.slice(c,c+b);return d?e.enrich(f):f})}; v.enrich=function(a){"object"!==typeof a&&(a=[a]);for(var b=this.db.transaction("reg","readonly").objectStore("reg"),c=[],d=0;d= target; } - // cycle all instances from this point if (cycle) { const self = this; - // move the next microtask onto the next macrotask queue + return new Promise(resolve => { setTimeout(function () { resolve(self[key + "Async"].apply(self, args)); diff --git a/dist/module-debug/bundle.js b/dist/module-debug/bundle.js index 1319942..970d520 100644 --- a/dist/module-debug/bundle.js +++ b/dist/module-debug/bundle.js @@ -146,8 +146,8 @@ import { KeystoreMap, KeystoreArray, KeystoreSet } from "./keystore.js"; /** @export */IndexOptions.cache; /** @export */IndexOptions.resolve; /** @export */IndexOptions.db; -/** @export */IndexOptions.worker; // worker url -/** @export */IndexOptions.config; // config url +/** @export */IndexOptions.worker; +/** @export */IndexOptions.config; /** @export */IndexOptions.priority; /** @export */IndexOptions.export; /** @export */IndexOptions.import; @@ -304,32 +304,21 @@ const FlexSearch = { Language: {} }; -// Export as library (Bundle) -// -------------------------------- - { - // Legacy Browser: this refers to window - // ESM Browser: self refers to window - // NodeJS: global refers to the global scope const root = "undefined" != typeof self ? self : "undefined" != typeof global ? global : self; let prop; - // AMD (RequireJS) if ((prop = root.define) && prop.amd) { prop([], function () { return FlexSearch; }); + } else if ("object" == typeof root.exports) { + root.exports = FlexSearch; + } else { + /** @export */ + root.FlexSearch = FlexSearch; } - // CommonJS - else if ("object" == typeof root.exports) { - root.exports = FlexSearch; - } - // Global (window) - else { - /** @export */ - root.FlexSearch = FlexSearch; - } } diff --git a/dist/module-debug/charset.js b/dist/module-debug/charset.js index 659ce73..cecd70c 100644 --- a/dist/module-debug/charset.js +++ b/dist/module-debug/charset.js @@ -6,36 +6,35 @@ import charset_latin_extra from "./charset/latin/extra.js"; import charset_latin_soundex from "./charset/latin/soundex.js"; import charset_cjk from "./charset/cjk.js"; -// universal charset export const Exact = charset_exact; export const Default = charset_normalize; export const Normalize = charset_normalize; -// latin charset + export const LatinBalance = charset_latin_balance; export const LatinAdvanced = charset_latin_advanced; export const LatinExtra = charset_latin_extra; export const LatinSoundex = charset_latin_soundex; -// CJK + export const CJK = charset_cjk; -// deprecated + export const LatinExact = charset_exact; export const LatinDefault = charset_normalize; export const LatinSimple = charset_normalize; export default { - // universal charset - Exact: charset_exact, - Default: charset_normalize, - Normalize: charset_normalize, - // latin charset - LatinBalance: charset_latin_balance, - LatinAdvanced: charset_latin_advanced, - LatinExtra: charset_latin_extra, - LatinSoundex: charset_latin_soundex, - // CJK - CJK: charset_cjk, - // deprecated - LatinExact: charset_exact, - LatinDefault: charset_normalize, - LatinSimple: charset_normalize + + Exact: charset_exact, + Default: charset_normalize, + Normalize: charset_normalize, + + LatinBalance: charset_latin_balance, + LatinAdvanced: charset_latin_advanced, + LatinExtra: charset_latin_extra, + LatinSoundex: charset_latin_soundex, + + CJK: charset_cjk, + + LatinExact: charset_exact, + LatinDefault: charset_normalize, + LatinSimple: charset_normalize }; \ No newline at end of file diff --git a/dist/module-debug/charset/cjk.js b/dist/module-debug/charset/cjk.js index 0767906..f920a29 100644 --- a/dist/module-debug/charset/cjk.js +++ b/dist/module-debug/charset/cjk.js @@ -1,14 +1,8 @@ import { EncoderOptions } from "../type.js"; -// https://en.wikipedia.org/wiki/CJK_characters - /** @type EncoderOptions */ const options = { split: "" - //normalize: true - // normalize: function(str){ - // return str.toLowerCase(); - // }, - //dedupe: false + }; export default options; \ No newline at end of file diff --git a/dist/module-debug/charset/exact.js b/dist/module-debug/charset/exact.js index 29c26bb..9a79b28 100644 --- a/dist/module-debug/charset/exact.js +++ b/dist/module-debug/charset/exact.js @@ -5,8 +5,6 @@ const options = { normalize: !1, numeric: !1, dedupe: !1 - //split: /\s+/ - //normalize: false, - //dedupe: false + }; export default options; \ No newline at end of file diff --git a/dist/module-debug/charset/latin/advanced.js b/dist/module-debug/charset/latin/advanced.js index e20e3d9..3bb213c 100644 --- a/dist/module-debug/charset/latin/advanced.js +++ b/dist/module-debug/charset/latin/advanced.js @@ -1,26 +1,15 @@ import { EncoderOptions } from "../../type.js"; import { soundex } from "./balance.js"; -export const matcher = new Map([ -//["ai", "ei"], // before soundex -["ae", "a"], ["oe", "o"], -//["ue", "u"], // soundex map -["sh", "s"], // replacer "h" -//["ch", "c"], // before soundex -["kh", "k"], // after soundex -["th", "t"], // replacer "h" -["ph", "f"], // replacer "h" -["pf", "f"]]); +export const matcher = new Map([["ae", "a"], ["oe", "o"], ["sh", "s"], ["kh", "k"], ["th", "t"], ["ph", "f"], ["pf", "f"]]); -export const replacer = [/([^aeo])h(.)/g, "$1$2", /([aeo])h([^aeo]|$)/g, "$1$2", /(.)\1+/g, "$1" // /([^0-9])\1+/g, "$1" -]; +export const replacer = [/([^aeo])h(.)/g, "$1$2", /([aeo])h([^aeo]|$)/g, "$1$2", /(.)\1+/g, "$1"]; /** @type EncoderOptions */ const options = { - //normalize: true, - //dedupe: true, - mapper: soundex, - matcher: matcher, - replacer: replacer + + mapper: soundex, + matcher: matcher, + replacer: replacer }; export default options; \ No newline at end of file diff --git a/dist/module-debug/charset/latin/balance.js b/dist/module-debug/charset/latin/balance.js index 6eb1be8..970b584 100644 --- a/dist/module-debug/charset/latin/balance.js +++ b/dist/module-debug/charset/latin/balance.js @@ -1,37 +1,10 @@ import { EncoderOptions } from "../../type.js"; -export const soundex = new Map([["b", "p"], -//["p", "p"], - -//["f", "f"], -["v", "f"], ["w", "f"], - -//["s", "s"], -["z", "s"], ["x", "s"], ["d", "t"], -//["t", "t"], - -//["m", "m"], -["n", "m"], - -//["k", "k"], -["c", "k"], ["g", "k"], ["j", "k"], ["q", "k"], - -//["r", "r"], -//["h", "h"], -//["l", "l"], - -//["a", "a"], - -//["e", "e"], -["i", "e"], ["y", "e"], - -//["o", "o"], -["u", "o"]]); +export const soundex = new Map([["b", "p"], ["v", "f"], ["w", "f"], ["z", "s"], ["x", "s"], ["d", "t"], ["n", "m"], ["c", "k"], ["g", "k"], ["j", "k"], ["q", "k"], ["i", "e"], ["y", "e"], ["u", "o"]]); /** @type EncoderOptions */ const options = { - //normalize: true, - //dedupe: true, - mapper: soundex + + mapper: soundex }; export default options; \ No newline at end of file diff --git a/dist/module-debug/charset/latin/extra.js b/dist/module-debug/charset/latin/extra.js index 4498453..20a2038 100644 --- a/dist/module-debug/charset/latin/extra.js +++ b/dist/module-debug/charset/latin/extra.js @@ -2,13 +2,11 @@ import { EncoderOptions } from "../../type.js"; import { soundex } from "./balance.js"; import { matcher, replacer } from "./advanced.js"; -export const compact = [/(?!^)[aeo]/g, "" // before soundex: aeoy, old: aioy -]; +export const compact = [/(?!^)[aeo]/g, ""]; /** @type EncoderOptions */ const options = { - //normalize: true, - //dedupe: true, + mapper: soundex, replacer: replacer.concat(compact), matcher: matcher diff --git a/dist/module-debug/charset/latin/soundex.js b/dist/module-debug/charset/latin/soundex.js index c15547f..4ec93c9 100644 --- a/dist/module-debug/charset/latin/soundex.js +++ b/dist/module-debug/charset/latin/soundex.js @@ -2,7 +2,7 @@ import { EncoderOptions } from "../../type.js"; /** @type {EncoderOptions} */ const options = { - //normalize: true, + dedupe: !1, include: { letter: !0 @@ -31,13 +31,13 @@ function soundex(stringToEncode) { for (let i = 1, char; i < stringToEncode.length; i++) { char = stringToEncode.charAt(i); - // Remove all occurrences of "h" and "w" + if ("h" !== char && "w" !== char) { - // Replace all consonants with digits + char = codes[char]; - // Remove all occurrences of a,e,i,o,u,y except first letter + if (char) { - // Replace all adjacent same digits with one digit + if (char !== last) { encodedString += char; last = char; @@ -48,8 +48,6 @@ function soundex(stringToEncode) { } } } - // while(encodedString.length < 4){ - // encodedString += "0"; - // } + return encodedString; } \ No newline at end of file diff --git a/dist/module-debug/charset/normalize.js b/dist/module-debug/charset/normalize.js index 1c971e5..372f954 100644 --- a/dist/module-debug/charset/normalize.js +++ b/dist/module-debug/charset/normalize.js @@ -1,11 +1,5 @@ import { EncoderOptions } from "../type.js"; /** @type EncoderOptions */ -const options = { - //normalize: true - // normalize: function(str){ - // return str.toLowerCase(); - // }, - //dedupe: false -}; +const options = {}; export default options; \ No newline at end of file diff --git a/dist/module-debug/charset/polyfill.js b/dist/module-debug/charset/polyfill.js index 749d40b..c32cbde 100644 --- a/dist/module-debug/charset/polyfill.js +++ b/dist/module-debug/charset/polyfill.js @@ -1,29 +1 @@ -export default [ - -// Charset Normalization - -["ª", "a"], ["²", "2"], ["³", "3"], ["¹", "1"], ["º", "o"], ["¼", "1⁄4"], ["½", "1⁄2"], ["¾", "3⁄4"], ["à", "a"], ["á", "a"], ["â", "a"], ["ã", "a"], ["ä", "a"], ["å", "a"], ["ç", "c"], ["è", "e"], ["é", "e"], ["ê", "e"], ["ë", "e"], ["ì", "i"], ["í", "i"], ["î", "i"], ["ï", "i"], ["ñ", "n"], ["ò", "o"], ["ó", "o"], ["ô", "o"], ["õ", "o"], ["ö", "o"], ["ù", "u"], ["ú", "u"], ["û", "u"], ["ü", "u"], ["ý", "y"], ["ÿ", "y"], ["ā", "a"], ["ă", "a"], ["ą", "a"], ["ć", "c"], ["ĉ", "c"], ["ċ", "c"], ["č", "c"], ["ď", "d"], ["ē", "e"], ["ĕ", "e"], ["ė", "e"], ["ę", "e"], ["ě", "e"], ["ĝ", "g"], ["ğ", "g"], ["ġ", "g"], ["ģ", "g"], ["ĥ", "h"], ["ĩ", "i"], ["ī", "i"], ["ĭ", "i"], ["į", "i"], ["ij", "ij"], ["ĵ", "j"], ["ķ", "k"], ["ĺ", "l"], ["ļ", "l"], ["ľ", "l"], ["ŀ", "l"], ["ń", "n"], ["ņ", "n"], ["ň", "n"], ["ʼn", "n"], ["ō", "o"], ["ŏ", "o"], ["ő", "o"], ["ŕ", "r"], ["ŗ", "r"], ["ř", "r"], ["ś", "s"], ["ŝ", "s"], ["ş", "s"], ["š", "s"], ["ţ", "t"], ["ť", "t"], ["ũ", "u"], ["ū", "u"], ["ŭ", "u"], ["ů", "u"], ["ű", "u"], ["ų", "u"], ["ŵ", "w"], ["ŷ", "y"], ["ź", "z"], ["ż", "z"], ["ž", "z"], ["ſ", "s"], ["ơ", "o"], ["ư", "u"], ["dž", "dz"], ["lj", "lj"], ["nj", "nj"], ["ǎ", "a"], ["ǐ", "i"], ["ǒ", "o"], ["ǔ", "u"], ["ǖ", "u"], ["ǘ", "u"], ["ǚ", "u"], ["ǜ", "u"], ["ǟ", "a"], ["ǡ", "a"], ["ǣ", "ae"], ["æ", "ae"], ["ǽ", "ae"], ["ǧ", "g"], ["ǩ", "k"], ["ǫ", "o"], ["ǭ", "o"], ["ǯ", "ʒ"], ["ǰ", "j"], ["dz", "dz"], ["ǵ", "g"], ["ǹ", "n"], ["ǻ", "a"], ["ǿ", "ø"], ["ȁ", "a"], ["ȃ", "a"], ["ȅ", "e"], ["ȇ", "e"], ["ȉ", "i"], ["ȋ", "i"], ["ȍ", "o"], ["ȏ", "o"], ["ȑ", "r"], ["ȓ", "r"], ["ȕ", "u"], ["ȗ", "u"], ["ș", "s"], ["ț", "t"], ["ȟ", "h"], ["ȧ", "a"], ["ȩ", "e"], ["ȫ", "o"], ["ȭ", "o"], ["ȯ", "o"], ["ȱ", "o"], ["ȳ", "y"], ["ʰ", "h"], ["ʱ", "h"], ["ɦ", "h"], ["ʲ", "j"], ["ʳ", "r"], ["ʴ", "ɹ"], ["ʵ", "ɻ"], ["ʶ", "ʁ"], ["ʷ", "w"], ["ʸ", "y"], ["ˠ", "ɣ"], ["ˡ", "l"], ["ˢ", "s"], ["ˣ", "x"], ["ˤ", "ʕ"], ["ΐ", "ι"], ["ά", "α"], ["έ", "ε"], ["ή", "η"], ["ί", "ι"], ["ΰ", "υ"], ["ϊ", "ι"], ["ϋ", "υ"], ["ό", "ο"], ["ύ", "υ"], ["ώ", "ω"], ["ϐ", "β"], ["ϑ", "θ"], ["ϒ", "Υ"], ["ϓ", "Υ"], ["ϔ", "Υ"], ["ϕ", "φ"], ["ϖ", "π"], ["ϰ", "κ"], ["ϱ", "ρ"], ["ϲ", "ς"], ["ϵ", "ε"], ["й", "и"], ["ѐ", "е"], ["ё", "е"], ["ѓ", "г"], ["ї", "і"], ["ќ", "к"], ["ѝ", "и"], ["ў", "у"], ["ѷ", "ѵ"], ["ӂ", "ж"], ["ӑ", "а"], ["ӓ", "а"], ["ӗ", "е"], ["ӛ", "ә"], ["ӝ", "ж"], ["ӟ", "з"], ["ӣ", "и"], ["ӥ", "и"], ["ӧ", "о"], ["ӫ", "ө"], ["ӭ", "э"], ["ӯ", "у"], ["ӱ", "у"], ["ӳ", "у"], ["ӵ", "ч"] - -// Term Separators - -// ["'", ""], // it's -> its -// ["´", ""], -// ["`", ""], -// ["’", ""], -// ["ʼ", ""], - -// Numeric-Separators Chars Removal - -// [",", ""], -// [".", ""] - -// Non-Whitespace Separators - -// already was split by default via p{P} -// ["-", " "], -// [":", " "], -// ["_", " "], -// ["|", " "], -// ["/", " "], -// ["\\", " "] -]; \ No newline at end of file +export default [["ª", "a"], ["²", "2"], ["³", "3"], ["¹", "1"], ["º", "o"], ["¼", "1⁄4"], ["½", "1⁄2"], ["¾", "3⁄4"], ["à", "a"], ["á", "a"], ["â", "a"], ["ã", "a"], ["ä", "a"], ["å", "a"], ["ç", "c"], ["è", "e"], ["é", "e"], ["ê", "e"], ["ë", "e"], ["ì", "i"], ["í", "i"], ["î", "i"], ["ï", "i"], ["ñ", "n"], ["ò", "o"], ["ó", "o"], ["ô", "o"], ["õ", "o"], ["ö", "o"], ["ù", "u"], ["ú", "u"], ["û", "u"], ["ü", "u"], ["ý", "y"], ["ÿ", "y"], ["ā", "a"], ["ă", "a"], ["ą", "a"], ["ć", "c"], ["ĉ", "c"], ["ċ", "c"], ["č", "c"], ["ď", "d"], ["ē", "e"], ["ĕ", "e"], ["ė", "e"], ["ę", "e"], ["ě", "e"], ["ĝ", "g"], ["ğ", "g"], ["ġ", "g"], ["ģ", "g"], ["ĥ", "h"], ["ĩ", "i"], ["ī", "i"], ["ĭ", "i"], ["į", "i"], ["ij", "ij"], ["ĵ", "j"], ["ķ", "k"], ["ĺ", "l"], ["ļ", "l"], ["ľ", "l"], ["ŀ", "l"], ["ń", "n"], ["ņ", "n"], ["ň", "n"], ["ʼn", "n"], ["ō", "o"], ["ŏ", "o"], ["ő", "o"], ["ŕ", "r"], ["ŗ", "r"], ["ř", "r"], ["ś", "s"], ["ŝ", "s"], ["ş", "s"], ["š", "s"], ["ţ", "t"], ["ť", "t"], ["ũ", "u"], ["ū", "u"], ["ŭ", "u"], ["ů", "u"], ["ű", "u"], ["ų", "u"], ["ŵ", "w"], ["ŷ", "y"], ["ź", "z"], ["ż", "z"], ["ž", "z"], ["ſ", "s"], ["ơ", "o"], ["ư", "u"], ["dž", "dz"], ["lj", "lj"], ["nj", "nj"], ["ǎ", "a"], ["ǐ", "i"], ["ǒ", "o"], ["ǔ", "u"], ["ǖ", "u"], ["ǘ", "u"], ["ǚ", "u"], ["ǜ", "u"], ["ǟ", "a"], ["ǡ", "a"], ["ǣ", "ae"], ["æ", "ae"], ["ǽ", "ae"], ["ǧ", "g"], ["ǩ", "k"], ["ǫ", "o"], ["ǭ", "o"], ["ǯ", "ʒ"], ["ǰ", "j"], ["dz", "dz"], ["ǵ", "g"], ["ǹ", "n"], ["ǻ", "a"], ["ǿ", "ø"], ["ȁ", "a"], ["ȃ", "a"], ["ȅ", "e"], ["ȇ", "e"], ["ȉ", "i"], ["ȋ", "i"], ["ȍ", "o"], ["ȏ", "o"], ["ȑ", "r"], ["ȓ", "r"], ["ȕ", "u"], ["ȗ", "u"], ["ș", "s"], ["ț", "t"], ["ȟ", "h"], ["ȧ", "a"], ["ȩ", "e"], ["ȫ", "o"], ["ȭ", "o"], ["ȯ", "o"], ["ȱ", "o"], ["ȳ", "y"], ["ʰ", "h"], ["ʱ", "h"], ["ɦ", "h"], ["ʲ", "j"], ["ʳ", "r"], ["ʴ", "ɹ"], ["ʵ", "ɻ"], ["ʶ", "ʁ"], ["ʷ", "w"], ["ʸ", "y"], ["ˠ", "ɣ"], ["ˡ", "l"], ["ˢ", "s"], ["ˣ", "x"], ["ˤ", "ʕ"], ["ΐ", "ι"], ["ά", "α"], ["έ", "ε"], ["ή", "η"], ["ί", "ι"], ["ΰ", "υ"], ["ϊ", "ι"], ["ϋ", "υ"], ["ό", "ο"], ["ύ", "υ"], ["ώ", "ω"], ["ϐ", "β"], ["ϑ", "θ"], ["ϒ", "Υ"], ["ϓ", "Υ"], ["ϔ", "Υ"], ["ϕ", "φ"], ["ϖ", "π"], ["ϰ", "κ"], ["ϱ", "ρ"], ["ϲ", "ς"], ["ϵ", "ε"], ["й", "и"], ["ѐ", "е"], ["ё", "е"], ["ѓ", "г"], ["ї", "і"], ["ќ", "к"], ["ѝ", "и"], ["ў", "у"], ["ѷ", "ѵ"], ["ӂ", "ж"], ["ӑ", "а"], ["ӓ", "а"], ["ӗ", "е"], ["ӛ", "ә"], ["ӝ", "ж"], ["ӟ", "з"], ["ӣ", "и"], ["ӥ", "и"], ["ӧ", "о"], ["ӫ", "ө"], ["ӭ", "э"], ["ӯ", "у"], ["ӱ", "у"], ["ӳ", "у"], ["ӵ", "ч"]]; \ No newline at end of file diff --git a/dist/module-debug/common.js b/dist/module-debug/common.js index 24f7236..7ccc1da 100644 --- a/dist/module-debug/common.js +++ b/dist/module-debug/common.js @@ -4,7 +4,6 @@ * @param {*=} merge_value * @return {*} */ - export function merge_option(value, default_value, merge_value) { const type_merge = typeof merge_value, type_value = typeof value; @@ -62,6 +61,10 @@ export function merge_option(value, default_value, merge_value) { return "undefined" == type_value ? default_value : value; } +export function inherit(target_value, default_value) { + return "undefined" == typeof target_value ? default_value : target_value; +} + export function create_object() { return Object.create(null); } @@ -108,7 +111,6 @@ export function toArray(val, stringify) { return result; } -// TODO support generic function created from string when tree depth > 1 export function parse_simple(obj, tree) { if (is_string(tree)) { diff --git a/dist/module-debug/compress.js b/dist/module-debug/compress.js index 7da6af0..a47a3bb 100644 --- a/dist/module-debug/compress.js +++ b/dist/module-debug/compress.js @@ -1,4 +1,4 @@ -let table, timer; // = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz+/"; +let table, timer; const cache = new Map(); @@ -6,7 +6,7 @@ function toRadix(number, radix = 255) { if (!table) { table = Array(radix); - // the char code 0 could be a special marker + for (let i = 0; i < radix; i++) table[i] = i + 1; table = String.fromCharCode.apply(null, table); } @@ -35,7 +35,6 @@ export default function (str) { timer = setTimeout(clear, 1); } - /* 2 ** ((level + 1.5) * 1.6 | 0) */ const result = toRadix("number" == typeof str ? str : lcg(str)); @@ -55,7 +54,7 @@ function lcg(str) { for (let i = 0; i < str.length; i++) { crc = (crc * 33 ^ str.charCodeAt(i)) & range; } - // shift up from Int32 to UInt32 range 0xFFFFFFFF + return crc + 2147483648; } diff --git a/dist/module-debug/db/clickhouse/index.js b/dist/module-debug/db/clickhouse/index.js index 5d12d2f..c494dac 100644 --- a/dist/module-debug/db/clickhouse/index.js +++ b/dist/module-debug/db/clickhouse/index.js @@ -65,14 +65,13 @@ export default function ClickhouseDB(name, config = {}) { if (!name) { console.info("Default storage space was used, because a name was not passed."); } - //field = "Test-456"; + this.id = "flexsearch" + (name ? "_" + sanitize(name) : ""); this.field = config.field ? "_" + sanitize(config.field) : ""; - // Clickhouse does not support ALTER TABLE to upgrade - // the type of the ID when it is a part of the merge key + this.type = config.type ? types[config.type.toLowerCase()] : "String"; if (!this.type) throw new Error("Unknown type of ID '" + config.type + "'"); - //this.trx = false; + this.support_tag_search = !0; this.db = Index || (Index = config.db || null); Object.assign(defaults, config); @@ -81,7 +80,7 @@ export default function ClickhouseDB(name, config = {}) { } ClickhouseDB.prototype.mount = function (flexsearch) { - //if(flexsearch.constructor === Document){ + if (flexsearch.index) { return flexsearch.mount(this); } @@ -116,7 +115,7 @@ ClickhouseDB.prototype.open = async function () { id ${this.type} ) ENGINE = MergeTree - /*PRIMARY KEY (key)*/ + ORDER BY (key, id); `, { params: { name: this.id + ".map" + this.field } }).toPromise(); break; @@ -130,7 +129,7 @@ ClickhouseDB.prototype.open = async function () { id ${this.type} ) ENGINE = MergeTree - /*PRIMARY KEY (ctx, key)*/ + ORDER BY (ctx, key, id); `).toPromise(); break; @@ -142,7 +141,7 @@ ClickhouseDB.prototype.open = async function () { id ${this.type} ) ENGINE = MergeTree - /*PRIMARY KEY (ctx, key)*/ + ORDER BY (tag, id); `).toPromise(); break; @@ -173,7 +172,7 @@ ClickhouseDB.prototype.open = async function () { }; ClickhouseDB.prototype.close = function () { - //DB && DB.close(); + this.db = Index = null; return this; }; @@ -309,7 +308,7 @@ ClickhouseDB.prototype.has = async function (id) { const result = await this.db.query(` SELECT 1 FROM ${this.id}.reg - WHERE id = {id:${this.type /*=== "number" ? "Int32" : "String"*/}} + WHERE id = {id:${this.type}} LIMIT 1`, { params: { id } }).toPromise(); return !!(result && result[0] && result[0][1]); }; @@ -347,7 +346,7 @@ ClickhouseDB.prototype.search = function (flexsearch, query, limit = 100, offset ${enrich ? ", doc" : ""} FROM ( SELECT id, count(*) as count, - ${suggest ? "SUM" : "SUM" /*"MIN"*/}(res) as res + ${suggest ? "SUM" : "SUM"}(res) as res FROM ${this.id}.ctx${this.field} WHERE ${where} GROUP BY id @@ -360,32 +359,6 @@ ClickhouseDB.prototype.search = function (flexsearch, query, limit = 100, offset ${limit ? "LIMIT " + limit : ""} ${offset ? "OFFSET " + offset : ""} `, { params }).toPromise(); - - // for(let i = 1; i < query.length; i++){ - // where += (where ? " UNION ALL " : "") + ` - // SELECT id, res - // FROM ${this.id}.ctx${this.field} - // WHERE ctx = {ctx${i}:String} AND key = {key${i}:String} - // `; - // term = query[i]; - // const swap = flexsearch.bidirectional && (term > keyword); - // params["ctx" + i] = swap ? term : keyword; - // params["key" + i] = swap ? keyword : term; - // keyword = term; - // } - // - // rows = await this.db.query(` - // SELECT id, res - // FROM ( - // SELECT id, ${suggest ? "SUM" : "MIN"}(res) as res, count(*) as count - // FROM (${where}) as t - // GROUP BY id - // ORDER BY ${suggest ? "count DESC, res" : "res"} - // LIMIT ${limit} - // OFFSET ${offset} - // ) as r - // ${suggest ? "" : "WHERE count = " + (query.length - 1)} - // `, { params }).toPromise(); } else { let where = "", params = {}; @@ -412,7 +385,7 @@ ClickhouseDB.prototype.search = function (flexsearch, query, limit = 100, offset ${enrich ? ", doc" : ""} FROM ( SELECT id, count(*) as count, - ${suggest ? "SUM" : "SUM" /*"MIN"*/}(res) as res + ${suggest ? "SUM" : "SUM"}(res) as res FROM ${this.id}.map${this.field} WHERE ${where} GROUP BY id @@ -425,56 +398,31 @@ ClickhouseDB.prototype.search = function (flexsearch, query, limit = 100, offset ${limit ? "LIMIT " + limit : ""} ${offset ? "OFFSET " + offset : ""} `, { params }).toPromise(); - - // for(let i = 0; i < query.length; i++){ - // params["key" + i] = query[i]; - // where += (where ? " UNION ALL " : "") + ` - // SELECT id, res - // FROM ${ this.id }.map${ this.field } - // WHERE key = {key${i}:String} - // `; - // } - // rows = await this.db.query(` - // SELECT id, res - // FROM ( - // SELECT id, ${suggest ? "SUM" : "MIN"}(res) as res, count(*) as count - // FROM (${where}) as t - // GROUP BY id - // ORDER BY ${suggest ? "count DESC, res" : "res"} - // LIMIT ${limit} - // OFFSET ${offset} - // ) as r - // ${ suggest ? "" : "WHERE count = " + query.length } - // `, { params }).toPromise(); } return rows.then(function (rows) { return create_result(rows, resolve, enrich); }); }; -ClickhouseDB.prototype.info = function () { - // todo -}; +ClickhouseDB.prototype.info = function () {}; ClickhouseDB.prototype.transaction = function (task) { - // not supported return task.call(this); }; ClickhouseDB.prototype.commit = async function (flexsearch, _replace, _append) { - // process cleanup tasks if (_replace) { await this.clear(); - // there are just removals in the task queue + flexsearch.commit_task = []; } else { let tasks = flexsearch.commit_task; flexsearch.commit_task = []; for (let i = 0, task; i < tasks.length; i++) { task = tasks[i]; - // there are just removals in the task queue + if (task.clear) { await this.clear(); _replace = !0; @@ -504,7 +452,7 @@ ClickhouseDB.prototype.commit = async function (flexsearch, _replace, _append) { for (let i = 0, ids; i < arr.length; i++) { if ((ids = arr[i]) && ids.length) { - //this.type || (this.type = typeof ids[0]); + for (let j = 0; j < ids.length; j++) { data.push({ key: key, @@ -590,25 +538,6 @@ ClickhouseDB.prototype.commit = async function (flexsearch, _replace, _append) { } } - // TODO - // await this.db.insert(`INSERT INTO ${this.id}.cfg${this.field} (cfg)`, [{ - // cfg: JSON.stringify({ - // "encode": typeof flexsearch.encode === "string" ? flexsearch.encode : "", - // "charset": typeof flexsearch.charset === "string" ? flexsearch.charset : "", - // "tokenize": flexsearch.tokenize, - // "resolution": flexsearch.resolution, - // "minlength": flexsearch.minlength, - // "optimize": flexsearch.optimize, - // "fastupdate": flexsearch.fastupdate, - // "encoder": flexsearch.encoder, - // "context": { - // "depth": flexsearch.depth, - // "bidirectional": flexsearch.bidirectional, - // "resolution": flexsearch.resolution_ctx - // } - // }) - // }]).toPromise(); - promises.length && (await Promise.all(promises)); flexsearch.map.clear(); diff --git a/dist/module-debug/db/indexeddb/index.js b/dist/module-debug/db/indexeddb/index.js index 00c56e5..23e2493 100644 --- a/dist/module-debug/db/indexeddb/index.js +++ b/dist/module-debug/db/indexeddb/index.js @@ -48,7 +48,7 @@ export default function IdxDB(name, config = {}) { } IdxDB.prototype.mount = function (flexsearch) { - //if(flexsearch.constructor === Document){ + if (flexsearch.index) { return flexsearch.mount(this); } @@ -63,8 +63,6 @@ IdxDB.prototype.open = function () { navigator.storage && navigator.storage.persist(); - // return this.db = new Promise(function(resolve, reject){ - Index[self.id] || (Index[self.id] = []); Index[self.id].push(self.field); @@ -75,60 +73,22 @@ IdxDB.prototype.open = function () { const db = self.db = this.result; - // Using Indexes + IDBKeyRange on schema map => [key, res, id] performs - // too bad and blows up amazingly in size - // The schema map:key => [res][id] is currently used instead - // In fact that bypass the idea of a storage solution, - // IndexedDB is such a poor contribution :( for (let i = 0, ref; i < fields.length; i++) { ref = fields[i]; for (let j = 0, field; j < Index[self.id].length; j++) { field = Index[self.id][j]; - db.objectStoreNames.contains(ref + ("reg" !== ref ? field ? ":" + field : "" : "")) || db.createObjectStore(ref + ("reg" !== ref ? field ? ":" + field : "" : "")); //{ autoIncrement: true /*keyPath: "id"*/ } - //.createIndex("idx", "ids", { multiEntry: true, unique: false }); + db.objectStoreNames.contains(ref + ("reg" !== ref ? field ? ":" + field : "" : "")) || db.createObjectStore(ref + ("reg" !== ref ? field ? ":" + field : "" : "")); } } - - // switch(event.oldVersion){ // existing db version - // case 0: - // // version 0 means that the client had no database - // // perform initialization - // case 1: - // // client had version 1 - // // update - // } }; return self.db = promisfy(req, function (result) { - self.db = result; //event.target.result; + self.db = result; self.db.onversionchange = function () { - //database is outdated + self.close(); }; }); - - // req.onblocked = function(event) { - // // this event shouldn't trigger if we handle onversionchange correctly - // // it means that there's another open connection to the same database - // // and it wasn't closed after db.onversionchange triggered for it - // console.error("blocked", event); - // reject(); - // }; - // - // req.onerror = function(event){ - // console.error(this.error, event); - // reject(); - // }; - // - // req.onsuccess = function(event){ - // self.db = this.result; //event.target.result; - // self.db.onversionchange = function(){ - // //database is outdated - // self.close(); - // }; - // resolve(self); - // }; - // }); }; IdxDB.prototype.close = function () { @@ -144,20 +104,6 @@ IdxDB.prototype.destroy = function () { return promisfy(req); }; -// IdxDB.prototype.set = function(ref, key, ctx, data){ -// const transaction = this.db.transaction(ref, "readwrite"); -// const map = transaction.objectStore(ref); -// const req = map.put(data, ctx ? ctx + ":" + key : key); -// return transaction;//promisfy(req, callback); -// }; - -// IdxDB.prototype.delete = function(ref, key, ctx){ -// const transaction = this.db.transaction(ref, "readwrite"); -// const map = transaction.objectStore(ref); -// const req = map.delete(ctx ? ctx + ":" + key : key); -// return transaction;//promisfy(req, callback); -// }; - /** * @return {!Promise} */ @@ -190,7 +136,7 @@ IdxDB.prototype.clear = function () { * @param {boolean=} enrich * @return {!Promise} */ -IdxDB.prototype.get = function (key, ctx, limit = 0, offset = 0, resolve = /* tag? */!0, enrich = !1) { +IdxDB.prototype.get = function (key, ctx, limit = 0, offset = 0, resolve = !0, enrich = !1) { const transaction = this.db.transaction((ctx ? "ctx" : "map") + (this.field ? ":" + this.field : ""), "readonly"), map = transaction.objectStore((ctx ? "ctx" : "map") + (this.field ? ":" + this.field : "")), req = map.get(ctx ? ctx + ":" + key : key), @@ -290,16 +236,7 @@ IdxDB.prototype.has = function (id) { IdxDB.prototype.search = null; -// IdxDB.prototype.has = function(ref, key, ctx){ -// const transaction = this.db.transaction(ref, "readonly"); -// const map = transaction.objectStore(ref); -// const req = map.getKey(ctx ? ctx + ":" + key : key); -// return promisfy(req); -// }; - -IdxDB.prototype.info = function () { - // todo -}; +IdxDB.prototype.info = function () {}; /** * @param {!string} ref @@ -327,33 +264,13 @@ IdxDB.prototype.transaction = function (ref, modifier, task) { transaction = store = null; return promise; }); - - // return new Promise((resolve, reject) => { - // transaction.onerror = (err) => { - // transaction.abort(); - // transaction = store = null; - // reject(err); - // //db.close; - // }; - // transaction.oncomplete = (res) => { - // transaction = store = null; - // resolve(res || true); - // //db.close; - // }; - // const promise = task.call(this, store); - // // transactions can just be used within the same event loop - // // the indexeddb is such a stupid tool :( - // this.trx[key + ":" + modifier] = null; - // return promise; - // }); }; IdxDB.prototype.commit = async function (flexsearch, _replace, _append) { - // process cleanup tasks if (_replace) { await this.clear(); - // there are just removals in the task queue + flexsearch.commit_task = []; } else { let tasks = flexsearch.commit_task; @@ -361,7 +278,7 @@ IdxDB.prototype.commit = async function (flexsearch, _replace, _append) { for (let i = 0, task; i < tasks.length; i++) { /** @dict */ task = tasks[i]; - // there are just removals in the task queue + if (task.clear) { await this.clear(); _replace = !0; @@ -410,23 +327,15 @@ IdxDB.prototype.commit = async function (flexsearch, _replace, _append) { res.push(val[j]); } changed = 1; - //result[i] = res.concat(val); - //result[i] = new Set([...result[i], ...value[i]]); - //result[i] = result[i].union(new Set(value[i])); } else { result[i] = val; changed = 1; - //result[i] = new Set(value[i]) } } } } else { result = value; changed = 1; - //result = []; - //for(let i = 0; i < value.length; i++){ - // if(value[i]) result[i] = new Set(value[i]); - //} } changed && store.put(result, key); @@ -466,7 +375,7 @@ IdxDB.prototype.commit = async function (flexsearch, _replace, _append) { for (let j = 0; j < val.length; j++) { res.push(val[j]); } - //result[i] = res.concat(val); + changed = 1; } else { result[i] = val; @@ -519,25 +428,6 @@ IdxDB.prototype.commit = async function (flexsearch, _replace, _append) { }); } - // TODO - // await this.transaction("cfg", "readwrite", function(store){ - // store.put({ - // "charset": flexsearch.charset, - // "tokenize": flexsearch.tokenize, - // "resolution": flexsearch.resolution, - // "fastupdate": flexsearch.fastupdate, - // "compress": flexsearch.compress, - // "encoder": { - // "minlength": flexsearch.encoder.minlength - // }, - // "context": { - // "depth": flexsearch.depth, - // "bidirectional": flexsearch.bidirectional, - // "resolution": flexsearch.resolution_ctx - // } - // }, "current"); - // }); - flexsearch.map.clear(); flexsearch.ctx.clear(); @@ -562,7 +452,7 @@ function handle(cursor, ids, _tag) { for (let x = 0, result; x < arr.length; x++) { - // tags has no resolution layer + if (result = _tag ? arr : arr[x]) { for (let i = 0, pos, id; i < ids.length; i++) { id = ids[i]; @@ -585,11 +475,9 @@ function handle(cursor, ids, _tag) { if (!count) { cursor.delete(); - //store.delete(cursor.key); } else if (changed) { - //await new Promise(resolve => { - cursor.update(arr); //.onsuccess = resolve; - //}); + + cursor.update(arr); } cursor.continue(); @@ -622,31 +510,11 @@ IdxDB.prototype.remove = function (ids) { const cursor = this.result; cursor && handle(cursor, ids, !0); }; - }), - // let filtered = []; - self.transaction("reg", "readwrite", function (store) { + }), self.transaction("reg", "readwrite", function (store) { for (let i = 0; i < ids.length; i++) { store.delete(ids[i]); } - // return new Promise(resolve => { - // store.openCursor().onsuccess = function(){ - // const cursor = this.result; - // if(cursor){ - // const id = cursor.value; - // if(ids.includes(id)){ - // filtered.push(id); - // cursor.delete(); - // } - // cursor.continue(); - // } - // else{ - // resolve(); - // } - // }; - // }); - }) - // ids = filtered; - ]) + })]) ); }; @@ -658,7 +526,7 @@ IdxDB.prototype.remove = function (ids) { function promisfy(req, callback) { return new Promise((resolve, reject) => { - // oncomplete is used for transaction + /** @this {IDBRequest|IDBOpenDBRequest} */ req.onsuccess = req.oncomplete = function () { callback && callback(this.result); diff --git a/dist/module-debug/db/interface.js b/dist/module-debug/db/interface.js index 5c8ef90..cc9b8ae 100644 --- a/dist/module-debug/db/interface.js +++ b/dist/module-debug/db/interface.js @@ -5,22 +5,14 @@ */ export default function StorageInterface() {} -// Mandatory Initializer -// ------------------------------ - -// assign store to an index StorageInterface.prototype.mount = async function () {}; -// open connection + StorageInterface.prototype.open = async function () {}; -// close connection + StorageInterface.prototype.close = function () {}; -// drop the database (drop tables) + StorageInterface.prototype.destroy = async function () {}; -// Mandatory Query Tasks -// ------------------------------ - -// transfer all changes of an index to the database StorageInterface.prototype.commit = async function () {}; /** * get results of a term "key" with optional context "ctx" @@ -39,15 +31,12 @@ StorageInterface.prototype.get = async function () {}; * @return {!Promise} */ StorageInterface.prototype.enrich = async function () {}; -// check if id exists on a specific index -StorageInterface.prototype.has = async function () {}; -// delete one id or multiple ids on a specific index -StorageInterface.prototype.remove = async function () {}; -// clear all data (truncate) -StorageInterface.prototype.clear = async function () {}; -// Optional Methods -// ------------------------------ +StorageInterface.prototype.has = async function () {}; + +StorageInterface.prototype.remove = async function () {}; + +StorageInterface.prototype.clear = async function () {}; /** * Perform the query intersection on database side diff --git a/dist/module-debug/db/mongodb/index.js b/dist/module-debug/db/mongodb/index.js index 59d4259..79b65f9 100644 --- a/dist/module-debug/db/mongodb/index.js +++ b/dist/module-debug/db/mongodb/index.js @@ -40,17 +40,13 @@ export default function MongoDB(name, config = {}) { this.type = config.type || ""; this.db = config.db || Index[this.id] || CLIENT || null; this.trx = !1; - this.support_tag_search = /* tag? */!0 /*await rows.hasNext()*/ /*await rows.hasNext()*/ /*await rows.hasNext()*/; + this.support_tag_search = !0; Object.assign(defaults, config); this.db && delete defaults.db; } -// MongoDB.mount = function(flexsearch){ -// return new this().mount(flexsearch); -// }; - MongoDB.prototype.mount = function (flexsearch) { - //if(flexsearch.constructor === Document){ + if (flexsearch.index) { return flexsearch.mount(this); } @@ -124,7 +120,7 @@ MongoDB.prototype.open = async function () { }; MongoDB.prototype.close = function () { - //CLIENT && CLIENT.close(); + this.db = CLIENT = null; Index[this.id] = null; return this; @@ -291,7 +287,7 @@ MongoDB.prototype.search = async function (flexsearch, query, limit = 100, offse const stmt = [{ $match: { $or: params } }, { $group: { _id: "$id", count: { $sum: 1 }, - res: suggest ? { $sum: "$res" } : { $sum /*$min*/: "$res" } + res: suggest ? { $sum: "$res" } : { $sum: "$res" } } }]; suggest || stmt.push({ $match: { count: query.length - 1 } }); @@ -324,19 +320,11 @@ MongoDB.prototype.search = async function (flexsearch, query, limit = 100, offse count++; } - stmt.push( - //{ $project: project }, - { $match: match }); + stmt.push({ $match: match }); } stmt.push({ $sort: suggest ? { count: -1, res: 1 } : { res: 1 } }, { $skip: offset }, { $limit: limit }); - // if(tags){ - // project = { _id: 1 }; - // if(!resolve) project["res"] = 1; - // if(enrich) project["doc"] = 1; - // } - stmt.push({ $project: project }); rows = await this.db.collection("ctx" + this.field).aggregate(stmt); @@ -351,7 +339,7 @@ MongoDB.prototype.search = async function (flexsearch, query, limit = 100, offse } }, { $group: { _id: "$id", count: { $sum: 1 }, - res: suggest ? { $sum: "$res" } : { $sum /*$min*/: "$res" } + res: suggest ? { $sum: "$res" } : { $sum: "$res" } } }]; suggest || stmt.push({ $match: { count: query.length } }); @@ -384,19 +372,11 @@ MongoDB.prototype.search = async function (flexsearch, query, limit = 100, offse count++; } - stmt.push( - //{ $project: project }, - { $match: match }); + stmt.push({ $match: match }); } stmt.push({ $sort: suggest ? { count: -1, res: 1 } : { res: 1 } }, { $skip: offset }, { $limit: limit }); - // if(tags){ - // project = { _id: 1 }; - // if(!resolve) project["res"] = 1; - // if(enrich) project["doc"] = 1; - // } - stmt.push({ $project: project }); rows = await this.db.collection("map" + this.field).aggregate(stmt); @@ -422,28 +402,25 @@ MongoDB.prototype.search = async function (flexsearch, query, limit = 100, offse } }; -MongoDB.prototype.info = function () { - // todo -}; +MongoDB.prototype.info = function () {}; MongoDB.prototype.transaction = function (task) { - // not supported + return task.call(this); }; MongoDB.prototype.commit = async function (flexsearch, _replace, _append) { - // process cleanup tasks if (_replace) { await this.clear(); - // there are just removals in the task queue + flexsearch.commit_task = []; } else { let tasks = flexsearch.commit_task; flexsearch.commit_task = []; for (let i = 0, task; i < tasks.length; i++) { task = tasks[i]; - // there are just removals in the task queue + if (task.clear) { await this.clear(); _replace = !0; @@ -559,23 +536,6 @@ MongoDB.prototype.commit = async function (flexsearch, _replace, _append) { flexsearch.tag && flexsearch.tag.clear(); flexsearch.store && flexsearch.store.clear(); flexsearch.document || flexsearch.reg.clear(); - - // TODO - // await this.db.collection("cfg" + this.field).insertOne({ - // "encode": typeof flexsearch.encode === "string" ? flexsearch.encode : "", - // "charset": typeof flexsearch.charset === "string" ? flexsearch.charset : "", - // "tokenize": flexsearch.tokenize, - // "resolution": flexsearch.resolution, - // "minlength": flexsearch.minlength, - // "optimize": flexsearch.optimize, - // "fastupdate": flexsearch.fastupdate, - // "encoder": flexsearch.encoder, - // "context": { - // "depth": flexsearch.depth, - // "bidirectional": flexsearch.bidirectional, - // "resolution": flexsearch.resolution_ctx - // } - // }); }; MongoDB.prototype.remove = function (ids) { @@ -585,9 +545,5 @@ MongoDB.prototype.remove = function (ids) { ids = [ids]; } - // if(this.type !== "string" && typeof ids[0] !== "number"){ - // ids = ids.map(item => parseInt(item, 10)); - // } - return Promise.all([this.db.collection("map" + this.field).deleteMany({ id: { $in: ids } }), this.db.collection("ctx" + this.field).deleteMany({ id: { $in: ids } }), this.db.collection("tag" + this.field).deleteMany({ id: { $in: ids } }), this.db.collection("reg").deleteMany({ id: { $in: ids } })]); }; \ No newline at end of file diff --git a/dist/module-debug/db/postgres/index.js b/dist/module-debug/db/postgres/index.js index 5efc5ea..4582514 100644 --- a/dist/module-debug/db/postgres/index.js +++ b/dist/module-debug/db/postgres/index.js @@ -61,7 +61,7 @@ export default function PostgresDB(name, config = {}) { this.id = (config.schema ? sanitize(config.schema) : defaults.schema) + (name ? "_" + sanitize(name) : ""); this.field = config.field ? "_" + sanitize(config.field) : ""; this.type = config.type ? types[config.type.toLowerCase()] : "text"; - this.support_tag_search = /* tag? */!0 /*await rows.hasNext()*/ /*await rows.hasNext()*/ /*await rows.hasNext()*/; + this.support_tag_search = !0; if (!this.type) throw new Error("Unknown type of ID '" + config.type + "'"); this.db = DB || (DB = config.db || null); Object.assign(defaults, config); @@ -69,7 +69,7 @@ export default function PostgresDB(name, config = {}) { } PostgresDB.prototype.mount = function (flexsearch) { - //if(flexsearch.constructor === Document){ + if (flexsearch.index) { return flexsearch.mount(this); } @@ -156,10 +156,7 @@ PostgresDB.prototype.open = async function () { PRIMARY KEY, doc text DEFAULT NULL ); - `).catch(() => { - // document indexes will try to create same registry table - // and the "IF NOT EXISTS" did not apply on parallel - }); + `).catch(() => {}); break; case "cfg": @@ -176,8 +173,8 @@ PostgresDB.prototype.open = async function () { }; PostgresDB.prototype.close = function () { - //DB && DB.close && DB.close(); - this.db = /*DB =*/null; + + this.db = null; return this; }; @@ -332,7 +329,6 @@ PostgresDB.prototype.search = function (flexsearch, query, limit = 100, offset = term, count = 1; - // variant new for (let i = 1; i < query.length; i++) { term = query[i]; @@ -356,7 +352,7 @@ PostgresDB.prototype.search = function (flexsearch, query, limit = 100, offset = ${enrich ? ", doc" : ""} FROM ( SELECT id, count(*) as count, - ${suggest ? "SUM" : "SUM" /*"MIN"*/}(res) as res + ${suggest ? "SUM" : "SUM"}(res) as res FROM ${this.id}.ctx${this.field} WHERE ${where} GROUP BY id @@ -369,36 +365,6 @@ PostgresDB.prototype.search = function (flexsearch, query, limit = 100, offset = ${limit ? "LIMIT " + limit : ""} ${offset ? "OFFSET " + offset : ""} `, params); - - // variant 1 - - // for(let i = 1, count = 1; i < query.length; i++){ - // where += (where ? " UNION " : "") + ` - // SELECT id, res - // FROM ${this.id}.ctx${this.field} - // WHERE ctx = $${count++} AND key = $${count++} - // `; - // term = query[i]; - // const swap = flexsearch.bidirectional && (term > keyword); - // params.push( - // swap ? term : keyword, - // swap ? keyword : term - // ); - // keyword = term; - // } - // - // rows = await db.any(` - // SELECT id, res - // FROM ( - // SELECT id, ${suggest ? "SUM" : "MIN"}(res) as res, count(*) as count - // FROM (${where}) as t - // GROUP BY id - // ORDER BY ${suggest ? "count DESC, res" : "res"} - // LIMIT ${limit} - // OFFSET ${offset} - // ) as r - // ${suggest ? "" : "WHERE count = " + (query.length - 1)} - // `, params); } else { let where = "", count = 1, @@ -423,7 +389,7 @@ PostgresDB.prototype.search = function (flexsearch, query, limit = 100, offset = ${enrich ? ", doc" : ""} FROM ( SELECT id, count(*) as count, - ${suggest ? "SUM" : "SUM" /*"MIN"*/}(res) as res + ${suggest ? "SUM" : "SUM"}(res) as res FROM ${this.id}.map${this.field} WHERE ${where} GROUP BY id @@ -436,67 +402,6 @@ PostgresDB.prototype.search = function (flexsearch, query, limit = 100, offset = ${limit ? "LIMIT " + limit : ""} ${offset ? "OFFSET " + offset : ""} `, query); - - // variant 1 - // for(let i = 1; i <= query.length; i++){ - // where += (where ? " UNION " : "") + ` - // SELECT id, res - // FROM ${ this.id }.map${ this.field } - // WHERE key = $${i} - // `; - // } - // rows = await db.any(` - // SELECT id, res - // FROM ( - // SELECT id, ${suggest ? "SUM" : "MIN"}(res) as res, count(*) as count - // FROM (${where}) as t - // GROUP BY id - // ORDER BY ${suggest ? "count DESC, res" : "res"} - // LIMIT ${limit} - // OFFSET ${offset} - // ) as r - // ${ suggest ? "" : "WHERE count = " + query.length } - // `, query); - - // variant 2 - // for(let i = 1; i <= query.length; i++){ - // where += (where ? " AND EXISTS " : "") + `(SELECT FROM ${this.id}.map${this.field} as d WHERE d.id = t.id AND d.key = $` + i + ")"; - // } - // rows = await db.any(` - // SELECT t.id, min(t.res) - // FROM ${this.id}.map${this.field} AS t - // WHERE EXISTS ${where} - // GROUP BY t.id - // LIMIT ${limit || 100} - // OFFSET ${offset || 0} - // `, query); - - // variant 3 - // for(let i = 1; i <= query.length; i++){ - // where += (where ? " INTERSECT " : "") + `SELECT id FROM ${this.id}.map${this.field} WHERE key = $` + i; - // } - // rows = await db.any(` - // WITH filtering (id) AS(${where}) - // SELECT t.id, min(t.res) - // FROM ${this.id}.map${this.field} AS t - // JOIN filtering USING (id) - // GROUP BY t.id - // LIMIT ${limit || 100} - // OFFSET ${offset || 0} - // `, query); - - // variant 4 - // for(let i = 1; i <= query.length; i++){ - // where += (where ? " INTERSECT " : "") + `SELECT id FROM ${this.id}.map${this.field} WHERE key = $` + i; - // } - // rows = await db.any(` - // SELECT id, min(res) - // FROM ${this.id}.map${this.field} - // WHERE id IN (${where}) - // GROUP BY id - // LIMIT ${limit || 100} - // OFFSET ${offset || 0} - // `, query); } return rows.then(function (rows) { @@ -504,23 +409,7 @@ PostgresDB.prototype.search = function (flexsearch, query, limit = 100, offset = }); }; -PostgresDB.prototype.info = function () { - // todo -}; - -// PostgresDB.prototype.transaction = async function(task){ -// const self = this; -// if(TRX){ -// return TRX.then(function(){ -// return self.transaction(task); -// //task.call(self, TRX); -// }); -// } -// TRX = await this.db.tx(async function(trx){ -// await task.call(self, trx); -// }); -// TRX = null; -// }; +PostgresDB.prototype.info = function () {}; PostgresDB.prototype.transaction = function (task) { const self = this; @@ -529,30 +418,18 @@ PostgresDB.prototype.transaction = function (task) { }); }; -// PostgresDB.prototype.transaction = async function(task){ -// if(TRX){ -// return await task.call(this, TRX); -// } -// const self = this; -// return this.db.tx(async function(trx){ -// await task.call(self, TRX = trx); -// TRX = null; -// }); -// }; - PostgresDB.prototype.commit = async function (flexsearch, _replace, _append) { - // process cleanup tasks if (_replace) { await this.clear(); - // there are just removals in the task queue + flexsearch.commit_task = []; } else { let tasks = flexsearch.commit_task; flexsearch.commit_task = []; for (let i = 0, task; i < tasks.length; i++) { task = tasks[i]; - // there are just removals in the task queue + if (task.clear) { await this.clear(); _replace = !0; @@ -567,8 +444,6 @@ PostgresDB.prototype.commit = async function (flexsearch, _replace, _append) { } tasks.length && (await this.remove(tasks)); } - - //console.log("tasks:", tasks) } if (!flexsearch.reg.size) { @@ -579,8 +454,6 @@ PostgresDB.prototype.commit = async function (flexsearch, _replace, _append) { const batch = []; - // Datastore + Registry - if (flexsearch.store) { let data = [], stmt = new pgp.helpers.ColumnSet(["id", "doc"], { @@ -591,8 +464,7 @@ PostgresDB.prototype.commit = async function (flexsearch, _replace, _append) { const id = item[0], doc = item[1]; - // const migration = checkMigration.call(this, id); - // migration && await migration; + data.push({ id, doc: doc && JSON.stringify(doc) }); if (data.length === MAXIMUM_QUERY_VARS) { let insert = pgp.helpers.insert(data, stmt); @@ -604,44 +476,26 @@ PostgresDB.prototype.commit = async function (flexsearch, _replace, _append) { let insert = pgp.helpers.insert(data, stmt); batch.push(trx.none(insert.replace(/^(insert into )"([^"]+)"/, '$1 $2'))); } - // while(data.length){ - // let next; - // if(data.length > MAXIMUM_QUERY_VARS){ - // next = data.slice(MAXIMUM_QUERY_VARS); - // data = data.slice(0, MAXIMUM_QUERY_VARS); - // } - // let insert = pgp.helpers.insert(data, stmt); - // trx.none(insert.replace(/^(insert into )"([^"]+)"/, '$1 $2')); - // if(next) data = next; - // else break; - // } - } + } else if (!flexsearch.bypass) { + let data = [], + stmt = new pgp.helpers.ColumnSet(["id"], { + table: this.id + ".reg" + }); - // Registry Only + for (const id of flexsearch.reg.keys()) { - else if (!flexsearch.bypass) { - let data = [], - stmt = new pgp.helpers.ColumnSet(["id"], { - table: this.id + ".reg" - }); - - for (const id of flexsearch.reg.keys()) { - // const migration = checkMigration.call(this, id); - // migration && await migration; - data.push({ id }); - if (data.length === MAXIMUM_QUERY_VARS) { - let insert = pgp.helpers.insert(data, stmt); - batch.push(trx.none(insert.replace(/^(insert into )"([^"]+)"/, '$1 $2'))); - data = []; - } - } - if (data.length) { + data.push({ id }); + if (data.length === MAXIMUM_QUERY_VARS) { let insert = pgp.helpers.insert(data, stmt); batch.push(trx.none(insert.replace(/^(insert into )"([^"]+)"/, '$1 $2'))); + data = []; } } - - // Default Index + if (data.length) { + let insert = pgp.helpers.insert(data, stmt); + batch.push(trx.none(insert.replace(/^(insert into )"([^"]+)"/, '$1 $2'))); + } + } if (flexsearch.map.size) { let data = [], @@ -656,13 +510,9 @@ PostgresDB.prototype.commit = async function (flexsearch, _replace, _append) { for (let i = 0, ids; i < arr.length; i++) { if ((ids = arr[i]) && ids.length) { - //this.type || (this.type = typeof ids[0]); - // let stmt = "($1,$2,$3)"; - // let params = [key, i, ids[0]]; + for (let j = 0; j < ids.length; j++) { - // stmt += ",($1,$2,$3)"; - // params.push(key, i, ids[j]); - //trx.none(`INSERT INTO ${config.schema}.map${self.field} (key, res, id) VALUES ($1,$2,$3)`, [key, i, ids[j]]); + data.push({ key: key, res: i, @@ -683,8 +533,6 @@ PostgresDB.prototype.commit = async function (flexsearch, _replace, _append) { } } - // Context Index - if (flexsearch.ctx.size) { let data = [], stmt = new pgp.helpers.ColumnSet(["ctx", "key", "res", "id"], { @@ -703,12 +551,9 @@ PostgresDB.prototype.commit = async function (flexsearch, _replace, _append) { for (let i = 0, ids; i < arr.length; i++) { if ((ids = arr[i]) && ids.length) { - // let stmt = "(?,?,?)"; - // let params = [ctx_key + ":" + key, i, ids[0]]; + for (let j = 0; j < ids.length; j++) { - // stmt += ",(?,?,?)"; - // params.push(ctx_key + ":" + key, i, ids[j]); - //trx.none("INSERT INTO " + config.schema + ".ctx" + self.field + " (ctx, key, res, id) VALUES ($1,$2,$3,$4)", [ctx_key, key, i, ids[j]]); + data.push({ ctx: ctx_key, key: key, @@ -731,8 +576,6 @@ PostgresDB.prototype.commit = async function (flexsearch, _replace, _append) { } } - // Tag Index - if (flexsearch.tag) { let data = [], stmt = new pgp.helpers.ColumnSet(["tag", "id"], { @@ -759,29 +602,6 @@ PostgresDB.prototype.commit = async function (flexsearch, _replace, _append) { } } - // Field Configuration - - // TODO - // trx.none("INSERT INTO " + this.id + ".cfg" + this.field + " (cfg) VALUES ($1)", [ - // JSON.stringify({ - // "encode": typeof flexsearch.encode === "string" ? flexsearch.encode : "", - // "charset": typeof flexsearch.charset === "string" ? flexsearch.charset : "", - // "tokenize": flexsearch.tokenize, - // "resolution": flexsearch.resolution, - // "minlength": flexsearch.minlength, - // "optimize": flexsearch.optimize, - // "fastupdate": flexsearch.fastupdate, - // "encoder": flexsearch.encoder, - // "context": { - // "depth": flexsearch.depth, - // "bidirectional": flexsearch.bidirectional, - // "resolution": flexsearch.resolution_ctx - // } - // }) - // ]); - - //return Promise.all(batch); - if (batch.length) { return trx.batch(batch); } @@ -806,171 +626,9 @@ PostgresDB.prototype.remove = function (ids) { return; } - // ids = [ids]; - // return this.db.none( - // "DELETE FROM " + this.id + ".map" + this.field + " WHERE id = ANY ($1);" + - // "DELETE FROM " + this.id + ".ctx" + this.field + " WHERE id = ANY ($1);" + - // "DELETE FROM " + this.id + ".tag" + this.field + " WHERE id = ANY ($1);" + - // "DELETE FROM " + this.id + ".reg WHERE id = ANY ($1);", [ids] - // ); - - // ids = [ids]; - // return Promise.all([ - // this.db.none({ text: "DELETE FROM " + this.id + ".map" + this.field + " WHERE id = ANY ($1)", rowMode: "array" }, ids), - // this.db.none({ text: "DELETE FROM " + this.id + ".ctx" + this.field + " WHERE id = ANY ($1)", rowMode: "array" }, ids), - // this.db.none({ text: "DELETE FROM " + this.id + ".tag" + this.field + " WHERE id = ANY ($1)", rowMode: "array" }, ids), - // this.db.none({ text: "DELETE FROM " + this.id + ".reg WHERE id = ANY ($1)", rowMode: "array" }, ids) - // ]); - return this.transaction(function (trx) { - //console.log("remove:", ids); - - // ids = [ids]; - // trx.none({ text: "DELETE FROM " + this.id + ".map" + this.field + " WHERE id = ANY ($1)", rowMode: "array" }, ids); - // trx.none({ text: "DELETE FROM " + this.id + ".ctx" + this.field + " WHERE id = ANY ($1)", rowMode: "array" }, ids); - // trx.none({ text: "DELETE FROM " + this.id + ".tag" + this.field + " WHERE id = ANY ($1)", rowMode: "array" }, ids); - // trx.none({ text: "DELETE FROM " + this.id + ".reg WHERE id = ANY ($1)", rowMode: "array" }, ids); - - // ids = [ids]; - // trx.none("DELETE FROM " + this.id + ".map" + this.field + " WHERE id = ANY ($1)", ids); - // trx.none("DELETE FROM " + this.id + ".ctx" + this.field + " WHERE id = ANY ($1)", ids); - // trx.none("DELETE FROM " + this.id + ".tag" + this.field + " WHERE id = ANY ($1)", ids); - // trx.none("DELETE FROM " + this.id + ".reg WHERE id = ANY ($1)", ids); - // return; - - // return trx.none( - // "DELETE FROM " + this.id + ".map" + this.field + " WHERE id = ANY ($1);" + - // "DELETE FROM " + this.id + ".ctx" + this.field + " WHERE id = ANY ($1);" + - // "DELETE FROM " + this.id + ".tag" + this.field + " WHERE id = ANY ($1);" + - // "DELETE FROM " + this.id + ".reg WHERE id = ANY ($1);", [ids] - // ); - - // while(ids.length){ - // let next; - // let stmt = ""; - // let chunk = 0; - // let migration; - // for(let i = 0; i < ids.length; i++){ - // stmt += (stmt ? "," : "") + "$" + (i + 1); // + "::text"; - // // maximum count of variables supported - // if(++chunk === MAXIMUM_QUERY_VARS){ - // next = ids.slice(MAXIMUM_QUERY_VARS); - // ids = ids.slice(0, MAXIMUM_QUERY_VARS); - // break; - // } - // } - // - // trx.batch([ - // trx.none("DELETE FROM " + this.id + ".map" + this.field + " WHERE id IN (" + stmt + ")", ids), - // trx.none("DELETE FROM " + this.id + ".ctx" + this.field + " WHERE id IN (" + stmt + ")", ids), - // trx.none("DELETE FROM " + this.id + ".tag" + this.field + " WHERE id IN (" + stmt + ")", ids), - // trx.none("DELETE FROM " + this.id + ".reg WHERE id IN (" + stmt + ")", ids) - // ]); - // - // // trx.none( - // // "DELETE FROM " + this.id + ".map" + this.field + " WHERE id IN (" + stmt + ");" + - // // "DELETE FROM " + this.id + ".ctx" + this.field + " WHERE id IN (" + stmt + ");" + - // // "DELETE FROM " + this.id + ".tag" + this.field + " WHERE id IN (" + stmt + ");" + - // // "DELETE FROM " + this.id + ".reg WHERE id IN (" + stmt + ");", ids - // // ); - // - // if(next) ids = next; - // else break; - // } - ids = [ids]; return trx.batch([trx.none({ text: "DELETE FROM " + this.id + ".map" + this.field + " WHERE id = ANY ($1)", rowMode: "array" }, ids), trx.none({ text: "DELETE FROM " + this.id + ".ctx" + this.field + " WHERE id = ANY ($1)", rowMode: "array" }, ids), trx.none({ text: "DELETE FROM " + this.id + ".tag" + this.field + " WHERE id = ANY ($1)", rowMode: "array" }, ids), trx.none({ text: "DELETE FROM " + this.id + ".reg WHERE id = ANY ($1)", rowMode: "array" }, ids)]); - - // ids = [ids]; - // return trx.batch([ - // trx.none("DELETE FROM " + this.id + ".map" + this.field + " WHERE id = ANY ($1)", ids), - // trx.none("DELETE FROM " + this.id + ".ctx" + this.field + " WHERE id = ANY ($1)", ids), - // trx.none("DELETE FROM " + this.id + ".tag" + this.field + " WHERE id = ANY ($1)", ids), - // trx.none("DELETE FROM " + this.id + ".reg WHERE id = ANY ($1)", ids) - // ]); - - // return trx.batch([ - // trx.none("DELETE FROM " + this.id + ".map" + this.field + " WHERE id IN ($1:csv)", [ids]), - // trx.none("DELETE FROM " + this.id + ".ctx" + this.field + " WHERE id IN ($1:csv)", [ids]), - // trx.none("DELETE FROM " + this.id + ".tag" + this.field + " WHERE id IN ($1:csv)", [ids]), - // trx.none("DELETE FROM " + this.id + ".reg WHERE id IN ($1:csv)", [ids]) - // ]); - - // const type = self.type === "text" ? "text" : "int"; - // return trx.batch([ - // trx.none("DELETE FROM " + this.id + ".map" + self.field + " WHERE id = ANY($1::" + type + "[])", [ids]), - // trx.none("DELETE FROM " + this.id + ".ctx" + self.field + " WHERE id = ANY($1::" + type + "[])", [ids]), - // trx.none("DELETE FROM " + this.id + ".reg WHERE id = ANY($1::" + type + "[])", [ids]) - // ]); - - // return trx.batch([ - // trx.none("DELETE FROM " + this.id + ".map" + self.field + " WHERE id = ANY($1)", [ids]), - // trx.none("DELETE FROM " + this.id + ".ctx" + self.field + " WHERE id = ANY($1)", [ids]), - // trx.none("DELETE FROM " + this.id + ".reg WHERE id = ANY($1)", [ids]) - // ]); }); -}; - -// if(this.type === "int" && typeof ids[0] === "string"){ -// ids = ids.map(item => parseInt(item, 10)); -// } -// if(this.type === "bigint" && typeof ids[0] === "string"){ -// ids = ids.map(item => BigInt(item)); -// } -// if(this.type === "string" && typeof ids[0] === "number"){ -// ids = ids.map(item => item + ""); -// } -// this.type !== "string" && checkMigration.call(this, ids[0]); - -// function checkMigration(id){ -// if(this.type !== "string"){ -// if(typeof id === "object"){ -// id = id[0]; -// } -// if(typeof id === "string"){ -// this.type = "string"; -// return upgradeTextId.call(this); -// } -// if(this.type !== "bigint"){ -// if(id > 2 ** 31 - 1){ -// this.type = "bigint"; -// return upgradeBigIntId.call(this); -// } -// } -// } -// } -// -// function upgradeTextId(){ -// return this.db.none(` -// ALTER TABLE ${this.id}.map${this.field} -// ALTER COLUMN id type varchar(128) -// USING id::text; -// ALTER TABLE ${this.id}.ctx${this.field} -// ALTER COLUMN id type varchar(128) -// USING id::text; -// ALTER TABLE ${this.id}.tag${this.field} -// ALTER COLUMN id type varchar(128) -// USING id::text; -// ALTER TABLE ${this.id}.reg -// ALTER COLUMN id type varchar(128) -// USING id::text; -// `); -// } -// -// function upgradeBigIntId(){ -// return this.db.none(` -// ALTER TABLE ${this.id}.map${this.field} -// ALTER COLUMN id type bigint -// USING id::bigint; -// ALTER TABLE ${this.id}.ctx${this.field} -// ALTER COLUMN id type bigint -// USING id::bigint; -// ALTER TABLE ${this.id}.tag${this.field} -// ALTER COLUMN id type bigint -// USING id::bigint; -// ALTER TABLE ${this.id}.reg -// ALTER COLUMN id type bigint -// USING id::bigint; -// `); -// } \ No newline at end of file +}; \ No newline at end of file diff --git a/dist/module-debug/db/redis/index.js b/dist/module-debug/db/redis/index.js index 96d59c0..ba09779 100644 --- a/dist/module-debug/db/redis/index.js +++ b/dist/module-debug/db/redis/index.js @@ -36,30 +36,25 @@ export default function RedisDB(name, config = {}) { this.id = (name ? sanitize(name) : "flexsearch") + "|"; this.field = config.field ? "-" + sanitize(config.field) : ""; this.type = config.type || ""; - this.fastupdate = /* tag? */ /* stringify */ /* stringify */!0 /*await rows.hasNext()*/ /*await rows.hasNext()*/ /*await rows.hasNext()*/; + this.fastupdate = !0; this.db = config.db || DB || null; this.support_tag_search = !0; this.resolution = 9; this.resolution_ctx = 9; - //this.trx = false; + Object.assign(defaults, config); this.db && delete defaults.db; } -// RedisDB.mount = function(flexsearch){ -// return new this().mount(flexsearch); -// }; - RedisDB.prototype.mount = function (flexsearch) { - //if(flexsearch.constructor === Document){ + if (flexsearch.index) { return flexsearch.mount(this); } flexsearch.db = this; this.resolution = flexsearch.resolution; this.resolution_ctx = flexsearch.resolution_ctx; - // todo support - //this.fastupdate = flexsearch.fastupdate; + return this.open(); }; @@ -78,7 +73,7 @@ RedisDB.prototype.open = async function () { }; RedisDB.prototype.close = async function () { - DB && (await this.db.disconnect()); // this.db.client.disconnect(); + DB && (await this.db.disconnect()); this.db = DB = null; return this; }; @@ -114,12 +109,11 @@ function create_result(range, type, resolve, enrich, resolution) { } } -RedisDB.prototype.get = function (key, ctx, limit = 0, offset = 0, resolve = !0, enrich = /* suggest */!1, tags) { +RedisDB.prototype.get = function (key, ctx, limit = 0, offset = 0, resolve = !0, enrich = !1, tags) { if (tags) { - // flexsearch dummy const query = ctx ? [ctx, key] : [key]; - // keyword first + return this.search({ depth: !!ctx }, query, limit, offset, !1, resolve, enrich, tags); } @@ -209,28 +203,19 @@ RedisDB.prototype.search = function (flexsearch, query, limit = 100, offset = 0, if (suggest) { const multi = this.db.multi(); - // The zStore implementation lacks of ordering by match count (occurrences). - // Unfortunately, I couldn't find an elegant way to overcome this issue completely. - // For this reason it needs additionally a zInterStore to boost at least matches - // when all terms were found + multi.zInterStore(key, query, { AGGREGATE: "SUM" }); query.push(key); weights.push(query.length); multi.zUnionStore(key, query, { WEIGHTS: weights, AGGREGATE: "SUM" }); - // Strict Tag Intersection: it does not put tags into union, instead it calculates the - // intersection against the term match union. This was the default behavior - // of Tag-Search. But putting everything into union will also provide suggestions derived - // from tags when no term was matched. + if (tags) { - // copy over zInterStore into the same destination surprisingly works fine - // const key2 = key + ":2"; + query = [key]; for (let i = 0; i < tags.length; i += 2) { query.push(this.id + "tag-" + sanitize(tags[i]) + ":" + tags[i + 1]); } multi.zInterStore(key, query, { AGGREGATE: "MAX" }); - // .unlink(key) - // key = key2; } result = multi[resolve ? "zRange" : "zRangeWithScores"](key, "" + offset, "" + (offset + limit - 1), { REV: !0 }).unlink(key).exec(); @@ -243,20 +228,14 @@ RedisDB.prototype.search = function (flexsearch, query, limit = 100, offset = 0, const self = this; return result.then(async function (range) { - range = suggest && tags - // take the 3rd result from batch return - ? range[3] - // take the 2nd result from batch return - : range[suggest ? 2 : 1]; + range = suggest && tags ? range[3] : range[suggest ? 2 : 1]; if (!range.length) return range; if (enrich) range = await self.enrich(range); return create_result(range, type, resolve, enrich, ctx ? self.resolution_ctx : self.resolution); }); }; -RedisDB.prototype.info = function () { - // todo -}; +RedisDB.prototype.info = function () {}; RedisDB.prototype.transaction = function (task, callback) { @@ -265,7 +244,7 @@ RedisDB.prototype.transaction = function (task, callback) { } TRX = this.db.multi(); - let promise1 = /*await*/task.call(this, TRX), + let promise1 = task.call(this, TRX), promise2 = TRX.exec(); TRX = null; @@ -276,17 +255,16 @@ RedisDB.prototype.transaction = function (task, callback) { RedisDB.prototype.commit = async function (flexsearch, _replace, _append) { - // process cleanup tasks if (_replace) { await this.clear(); - // there are just removals in the task queue + flexsearch.commit_task = []; } else { let tasks = flexsearch.commit_task; flexsearch.commit_task = []; for (let i = 0, task; i < tasks.length; i++) { task = tasks[i]; - // there are just removals in the task queue + if (task.clear) { await this.clear(); _replace = !0; @@ -330,15 +308,9 @@ RedisDB.prototype.commit = async function (flexsearch, _replace, _append) { const ref = this.id + "map" + this.field + ":" + key; trx.zAdd(ref, result); - // if(this.fastupdate) for(let j = 0; j < ids.length; j++){ - // trx.sAdd("ref" + this.field + ":" + ids[j], ref); - // } + if (this.fastupdate) for (let j = 0, id; j < ids.length; j++) { - // Map performs bad when pushing numeric-like values as key - // id = ids[j]; - // let tmp = refs.get(id); - // tmp || refs.set(id, tmp = []); - // tmp.push(ref); + id = ids[j]; let tmp = refs.get(id); tmp || refs.set(id, tmp = []); @@ -347,11 +319,7 @@ RedisDB.prototype.commit = async function (flexsearch, _replace, _append) { } } } - // if(this.fastupdate) for(let item of refs){ - // const key = item[0]; - // const value = item[1]; - // trx.sAdd("ref" + this.field + ":" + key, value); - // } + if (this.fastupdate) for (const item of refs) { const key = item[0], value = item[1]; @@ -382,15 +350,9 @@ RedisDB.prototype.commit = async function (flexsearch, _replace, _append) { } const ref = this.id + "ctx" + this.field + ":" + ctx_key + ":" + key; trx.zAdd(ref, result); - // if(this.fastupdate) for(let j = 0; j < ids.length; j++){ - // trx.sAdd("ref" + this.field + ":" + ids[j], ref); - // } + if (this.fastupdate) for (let j = 0, id; j < ids.length; j++) { - // Map performs bad when pushing numeric-like values as key - // id = ids[j]; - // let tmp = refs.get(id); - // tmp || refs.set(id, tmp = []); - // tmp.push(ref); + id = ids[j]; let tmp = refs.get(id); tmp || refs.set(id, tmp = []); @@ -430,12 +392,7 @@ RedisDB.prototype.commit = async function (flexsearch, _replace, _append) { if (!ids.length) continue; let result = []; - // for(let i = 0; i < ids.length; i++){ - // result.push({ - // score: 0, - // value: "" + ids[i] - // }); - // } + if ("number" == typeof ids[0]) { for (let i = 0; i < ids.length; i++) { result[i] = "" + ids[i]; @@ -446,23 +403,6 @@ RedisDB.prototype.commit = async function (flexsearch, _replace, _append) { trx.sAdd(this.id + "tag" + this.field + ":" + tag, result); } } - - // TODO - // trx.set(this.id + "cfg" + this.field, JSON.stringify({ - // "encode": typeof flexsearch.encode === "string" ? flexsearch.encode : "", - // "charset": typeof flexsearch.charset === "string" ? flexsearch.charset : "", - // "tokenize": flexsearch.tokenize, - // "resolution": flexsearch.resolution, - // "minlength": flexsearch.minlength, - // "optimize": flexsearch.optimize, - // "fastupdate": flexsearch.fastupdate, - // "encoder": flexsearch.encoder, - // "context": { - // "depth": flexsearch.depth, - // "bidirectional": flexsearch.bidirectional, - // "resolution": flexsearch.resolution_ctx - // } - // })); }); flexsearch.map.clear(); @@ -506,21 +446,15 @@ RedisDB.prototype.remove = function (ids) { id = "" + ids[i]; if (this.fastupdate) { - // const refs = new Map(); + const ref = await this.db.sMembers(this.id + "ref" + this.field + ":" + id); if (ref) { for (let j = 0; j < ref.length; j++) { - // let tmp = refs.get(ref[j]); - // tmp || refs.set(ref[j], tmp = []); - // tmp.push(id); + trx.zRem(ref[j], id); } trx.unlink(this.id + "ref" + this.field + ":" + id); } - // for(let item of refs){ - // //console.log(item[0], item[1]) - // trx.zRem(item[0], item[1]); - // } } trx.hDel(this.id + "doc", id); diff --git a/dist/module-debug/db/sqlite/index.js b/dist/module-debug/db/sqlite/index.js index d5faa29..702a302 100644 --- a/dist/module-debug/db/sqlite/index.js +++ b/dist/module-debug/db/sqlite/index.js @@ -1,4 +1,4 @@ -//const sqlite3 = require("sqlite3").verbose(); + import sqlite3 from "sqlite3"; import path from "path"; import StorageInterface from "../interface.js"; @@ -34,7 +34,6 @@ function sanitize(str) { return str.toLowerCase().replace(/[^a-z0-9_]/g, ""); } -// global transaction to keep track of database lock const TRX = Object.create(null), Index = Object.create(null); @@ -55,18 +54,17 @@ export default function SqliteDB(name, config = {}) { if (!name) { console.info("Default storage space was used, because a name was not passed."); } - //field = "Test-456"; + this.id = config.path || (":memory:" === name ? name : "flexsearch" + (name ? "-" + sanitize(name) : "") + ".sqlite"); this.field = config.field ? "_" + sanitize(config.field) : ""; - this.support_tag_search = /* tag? */ /* stringify */ /* stringify */ /* single param */!0 /*await rows.hasNext()*/ - /*await rows.hasNext()*/ /*await rows.hasNext()*/; + this.support_tag_search = !0; this.db = config.db || Index[this.id] || null; this.type = config.type ? types[config.type.toLowerCase()] : "string"; if (!this.type) throw new Error("Unknown type of ID '" + config.type + "'"); } SqliteDB.prototype.mount = function (flexsearch) { - //if(flexsearch.constructor === Document){ + if (flexsearch.index) { return flexsearch.mount(this); } @@ -82,9 +80,9 @@ SqliteDB.prototype.open = async function () { let filepath = this.id; if (":memory:" !== filepath) { - // skip absolute path + if ("/" !== filepath[0] && "\\" !== filepath[0]) { - // current working directory + const dir = process.cwd(); filepath = path.join(dir, this.id); } @@ -246,7 +244,7 @@ function create_result(rows, resolve, enrich) { } } -SqliteDB.prototype.get = function (key, ctx, limit = 0, offset = 0, resolve = !0, enrich = /* suggest */!1, tags) { +SqliteDB.prototype.get = function (key, ctx, limit = 0, offset = 0, resolve = !0, enrich = !1, tags) { let result, stmt = '', params = ctx ? [ctx, key] : [key], @@ -352,12 +350,6 @@ SqliteDB.prototype.enrich = function (ids) { const chunk = ids.length - count > MAXIMUM_QUERY_VARS ? ids.slice(count, count + MAXIMUM_QUERY_VARS) : count ? ids.slice(count) : ids; count += chunk.length; - // let stmt = "?"; - // for(let i = 1; i < chunk.length; i++){ - // stmt += ",?"; - // } - - // 10x faster string concatenation let stmt = build_params(chunk.length); promises.push(this.promisfy({ @@ -430,7 +422,7 @@ SqliteDB.prototype.search = function (flexsearch, query, limit = 100, offset = 0 ${enrich ? ", doc" : ""} FROM ( SELECT id, count(*) as count, - ${suggest ? "SUM" : "SUM" /*"MIN"*/}(res) as res + ${suggest ? "SUM" : "SUM"}(res) as res FROM main.ctx${this.field} WHERE ${stmt} GROUP BY id @@ -445,36 +437,6 @@ SqliteDB.prototype.search = function (flexsearch, query, limit = 100, offset = 0 `, params }); - - // variant 1 - // for(let i = 1; i < query.length; i++){ - // stmt += (stmt ? " UNION ALL " : "") + ` - // SELECT id, res - // FROM main.ctx${this.field} - // WHERE ctx = ? AND key = ? - // `; - // term = query[i]; - // const swap = flexsearch.bidirectional && (term > keyword); - // params.push(swap ? term : keyword, swap ? keyword : term); - // keyword = term; - // } - // - // rows = await this.promisfy({ - // method: "all", - // stmt: ` - // SELECT id/*, res */ - // FROM ( - // SELECT id, ${suggest ? "SUM" : "MIN"}(res) as res, count(*) as count - // FROM (${stmt}) as t - // GROUP BY id - // ORDER BY ${suggest ? "count DESC, res" : "res"} - // LIMIT ${limit} - // OFFSET ${offset} - // ) as r - // ${suggest ? "" : "WHERE count = " + (query.length - 1)} - // `, - // params - // }); } else { let stmt = "", query_length = query.length; @@ -499,7 +461,7 @@ SqliteDB.prototype.search = function (flexsearch, query, limit = 100, offset = 0 ${enrich ? ", doc" : ""} FROM ( SELECT id, count(*) as count, - ${suggest ? "SUM" : "SUM" /*"MIN"*/}(res) as res + ${suggest ? "SUM" : "SUM"}(res) as res FROM main.map${this.field} WHERE ${stmt} GROUP BY id @@ -514,32 +476,6 @@ SqliteDB.prototype.search = function (flexsearch, query, limit = 100, offset = 0 `, params: query }); - - // variant 1 - // for(let i = 0; i < query.length; i++){ - // stmt += (stmt ? " UNION ALL " : "") + ` - // SELECT id, res - // FROM main.map${ this.field } - // WHERE key = ? - // `; - // } - // - // rows = await this.promisfy({ - // method: "all", - // stmt: ` - // SELECT id/*, res*/ - // FROM ( - // SELECT id, ${suggest ? "SUM" : "MIN"}(res) as res, count(*) as count - // FROM (${stmt}) as t - // GROUP BY id - // ORDER BY ${suggest ? "count DESC, res" : "res"} - // LIMIT ${limit} - // OFFSET ${offset} - // ) as r - // ${ suggest ? "" : "WHERE count = " + query.length } - // `, - // params: query - // }); } return rows.then(function (rows) { @@ -547,9 +483,7 @@ SqliteDB.prototype.search = function (flexsearch, query, limit = 100, offset = 0 }); }; -SqliteDB.prototype.info = function () { - // todo -}; +SqliteDB.prototype.info = function () {}; SqliteDB.prototype.transaction = async function (task, callback) { @@ -580,17 +514,16 @@ SqliteDB.prototype.transaction = async function (task, callback) { SqliteDB.prototype.commit = async function (flexsearch, _replace, _append) { - // process cleanup tasks if (_replace) { await this.clear(); - // there are just removals in the task queue + flexsearch.commit_task = []; } else { let tasks = flexsearch.commit_task; flexsearch.commit_task = []; for (let i = 0, task; i < tasks.length; i++) { task = tasks[i]; - // there are just removals in the task queue + if (task.clear) { await this.clear(); _replace = !0; @@ -627,21 +560,17 @@ SqliteDB.prototype.commit = async function (flexsearch, _replace, _append) { for (let j = 0; j < ids.length; j++) { stmt += (stmt ? "," : "") + "(?,?,?)"; params.push(key, i, ids[j]); - // maximum count of variables supported + if (j === ids.length - 1 || params.length + 3 > MAXIMUM_QUERY_VARS) { this.db.run("INSERT INTO main.map" + this.field + " (key, res, id) VALUES " + stmt, params); stmt = ""; params = []; } - //this.db.run("INSERT INTO map (key, res, id) VALUES (?, ?, ?) ON CONFLICT DO NOTHING", [key, i, ids[j]]); } } } } - //}); - //await this.transaction(function(){ - for (const ctx of flexsearch.ctx) { const ctx_key = ctx[0], ctx_value = ctx[1]; @@ -661,7 +590,7 @@ SqliteDB.prototype.commit = async function (flexsearch, _replace, _append) { for (let j = 0; j < ids.length; j++) { stmt += (stmt ? "," : "") + "(?,?,?,?)"; params.push(ctx_key, key, i, ids[j]); - // maximum count of variables supported + if (j === ids.length - 1 || params.length + 4 > MAXIMUM_QUERY_VARS) { this.db.run("INSERT INTO main.ctx" + this.field + " (ctx, key, res, id) VALUES " + stmt, params); stmt = ""; @@ -672,8 +601,6 @@ SqliteDB.prototype.commit = async function (flexsearch, _replace, _append) { } } } - //}); - //await this.transaction(function(){ if (flexsearch.store) { let stmt = "", @@ -703,8 +630,6 @@ SqliteDB.prototype.commit = async function (flexsearch, _replace, _append) { this.db.run("INSERT INTO main.reg (id) VALUES " + stmt, chunk); } } - //}); - //await this.transaction(function(){ if (flexsearch.tag) { let stmt = "", @@ -731,25 +656,6 @@ SqliteDB.prototype.commit = async function (flexsearch, _replace, _append) { } }); - // TODO - //await this.transaction(function(){ - // this.db.run("INSERT INTO main.cfg" + this.field + " (cfg) VALUES (?)", [JSON.stringify({ - // "charset": flexsearch.charset, - // "tokenize": flexsearch.tokenize, - // "resolution": flexsearch.resolution, - // "fastupdate": flexsearch.fastupdate, - // "compress": flexsearch.compress, - // "encoder": { - // "minlength": flexsearch.encoder.minlength - // }, - // "context": { - // "depth": flexsearch.depth, - // "bidirectional": flexsearch.bidirectional, - // "resolution": flexsearch.resolution_ctx - // } - // })]); - //}); - flexsearch.map.clear(); flexsearch.ctx.clear(); flexsearch.tag && flexsearch.tag.clear(); @@ -764,7 +670,7 @@ SqliteDB.prototype.remove = function (ids) { } let next; - // maximum count of variables supported + if (ids.length > MAXIMUM_QUERY_VARS) { next = ids.slice(MAXIMUM_QUERY_VARS); ids = ids.slice(0, MAXIMUM_QUERY_VARS); diff --git a/dist/module-debug/document.js b/dist/module-debug/document.js index 3115e0a..b8e48fd 100644 --- a/dist/module-debug/document.js +++ b/dist/module-debug/document.js @@ -44,17 +44,15 @@ export default function Document(options) { keystore = options.keystore || 0; keystore && (this.keystore = keystore); this.fastupdate = !!options.fastupdate; - // Shared Registry - this.reg = this.fastupdate && !options.worker && !options.db ? keystore && /* tag? */ /* stringify */ /* stringify */ /* single param */ /* skip update: */ /* append: */ /* skip update: */ /* skip_update: */ /* skip deletion */!0 /*await rows.hasNext()*/ /*await rows.hasNext()*/ /*await rows.hasNext()*/ ? new KeystoreMap(keystore) : new Map() : keystore && !0 ? new KeystoreSet(keystore) : new Set(); - // todo support custom filter function + this.reg = this.fastupdate && !options.worker && !options.db ? keystore && !0 ? new KeystoreMap(keystore) : new Map() : keystore && !0 ? new KeystoreSet(keystore) : new Set(); + this.storetree = (tmp = document.store || null) && tmp && !0 !== tmp && []; this.store = tmp && (keystore && !0 ? new KeystoreMap(keystore) : new Map()); this.cache = (tmp = options.cache || null) && new Cache(tmp); - // do not apply cache again for the indexes since .searchCache() - // is just a wrapper over .search() - options.cache = /* suggest */ /* append: */ /* enrich */!1; + + options.cache = !1; this.worker = options.worker || !1; @@ -66,7 +64,7 @@ export default function Document(options) { this.index = parse_descriptor.call(this, options, document); this.tag = null; - // TODO case-insensitive tags? + if (tmp = document.tag) { if ("string" == typeof tmp) { tmp = [tmp]; @@ -87,20 +85,20 @@ export default function Document(options) { this.tagtree[i] = parse_tree(field, this.marker); if (params.filter) { if ("string" == typeof this.tagtree[i]) { - // it needs an object to put a property to it + this.tagtree[i] = new String(this.tagtree[i]); } this.tagtree[i]._filter = params.filter; } } - // the tag fields need to be hold by indices + this.tagfield[i] = field; this.tag.set(field, new Map()); } } } - // resolve worker promises and swap instances + if (this.worker) { this.fastupdate = !1; const promises = []; @@ -110,38 +108,15 @@ export default function Document(options) { if (promises.length) { const self = this; return Promise.all(promises).then(function (result) { - new Map(); - let count = 0; for (const item of self.index.entries()) { const key = /** @type {string} */item[0]; let index = /** @type {Index|WorkerIndex | Promise} */item[1]; - // let encoder; - // if(SUPPORT_HIGHLIGHTING && SUPPORT_STORE){ - // // make encoder available for result highlighting - // let opt = promises[count].encoder || {}; - // // handle shared encoders - // let encoder = encoder_last.get(opt); - // if(!encoder){ - // encoder = opt.encode - // ? opt - // : SUPPORT_ENCODER - // ? new Encoder( - // SUPPORT_CHARSET && typeof opt === "string" - // ? Charset[opt] - // : opt) - // : { encode: fallback_encoder }; - // encoder_last.set(opt, encoder); - // } - // } if (index.then) { index = result[count]; self.index.set(key, index); count++; } - // if(encoder){ - // index.encoder = encoder; - // } } return self; }); @@ -149,8 +124,7 @@ export default function Document(options) { } else { if (options.db) { this.fastupdate = !1; - // a constructor should not return a promise - // it can be awaited on "await index.db" + this.mount(options.db); } } @@ -169,22 +143,19 @@ Document.prototype.mount = function (db) { let fields = this.field; if (this.tag) { - // tag indexes are referenced by field - // move tags to their field indexes respectively + for (let i = 0, field; i < this.tagfield.length; i++) { field = this.tagfield[i]; - let index; // = this.index.get(field); - //if(!index){ - // create raw index when not exists + let index; + this.index.set(field, index = new Index( /** @type IndexOptions */{}, this.reg)); - // copy and push to the field selection + if (fields === this.field) { fields = fields.slice(0); } - // tag indexes also needs to be upgraded to db instances + fields.push(field); - //} - // assign reference + index.tag = this.tag.get(field); } } @@ -197,22 +168,20 @@ Document.prototype.mount = function (db) { }; - // upgrade all indexes to db instances for (let i = 0, index, field; i < fields.length; i++) { config.field = field = fields[i]; index = this.index.get(field); const dbi = new db.constructor(db.id, config); - // take over the storage id + dbi.id = db.id; promises[i] = dbi.mount(index); - // add an identification property + index.document = !0; if (i) { - // the register has to export just one time - // also it's needed by the index for ID contain check + index.bypass = !0; } else { - // the datastore has to export one time + index.store = this.store; } } @@ -224,18 +193,13 @@ Document.prototype.mount = function (db) { }; Document.prototype.commit = async function (replace, append) { - // parallel: + const promises = []; for (const index of this.index.values()) { promises.push(index.commit(replace, append)); } await Promise.all(promises); this.reg.clear(); - // queued: - // for(const index of this.index.values()){ - // await index.db.commit(index, replace, append); - // } - // this.reg.clear(); }; Document.prototype.destroy = function () { @@ -274,17 +238,15 @@ function parse_descriptor(options, document) { if (this.worker) { let encoder = opt.encoder; - // assign encoder for result highlighting encoder = encoder && encoder.encode ? encoder : new Encoder("string" == typeof encoder ? Charset[encoder] : encoder); const worker = new WorkerIndex(opt, /** @type {Encoder} */encoder); if (worker) { - // worker could be a promise - // it needs to be resolved and swapped later + index.set(key, worker); } else { - // fallback when not supported + this.worker = !1; } } @@ -299,7 +261,7 @@ function parse_descriptor(options, document) { this.tree[i] = parse_tree(key, this.marker); if (opt.filter) { if ("string" == typeof this.tree[i]) { - // it needs an object to put a property to it + this.tree[i] = new String(this.tree[i]); } this.tree[i]._filter = opt.filter; @@ -324,7 +286,7 @@ function parse_descriptor(options, document) { this.storetree[i] = parse_tree(field, this.marker); if (store.filter) { if ("string" == typeof this.storetree[i]) { - // it needs an object to put a property to it + this.storetree[i] = new String(this.storetree[i]); } this.storetree[i]._filter = store.filter; @@ -343,7 +305,7 @@ function parse_tree(key, marker) { for (let i = 0; i < tree.length; i++) { key = tree[i]; - // todo apply some indexes e.g. [0], [-1], [0-2] + if ("]" === key[key.length - 1]) { key = key.substring(0, key.length - 2); if (key) { @@ -397,7 +359,7 @@ Document.prototype.remove = function (id) { if (this.reg.has(id)) { if (this.tag) { - // when fastupdate was enabled all ids are already removed + if (!this.fastupdate) { for (let field of this.tag.values()) { for (let item of field) { @@ -420,7 +382,6 @@ Document.prototype.remove = function (id) { this.reg.delete(id); } - // the cache could be used outside the InMemory store if (this.cache) { this.cache.remove(id); } @@ -433,9 +394,9 @@ Document.prototype.clear = function () { const promises = []; for (const index of this.index.values()) { - // db index will add clear task + const promise = index.clear(); - // worker indexes will return promises + if (promise.then) { promises.push(promise); } @@ -511,7 +472,7 @@ Document.prototype.set = function (id, data) { return this; }; -// todo mo + Document.prototype.searchCache = searchCache; diff --git a/dist/module-debug/document/add.js b/dist/module-debug/document/add.js index bf00deb..ebd39d6 100644 --- a/dist/module-debug/document/add.js +++ b/dist/module-debug/document/add.js @@ -25,7 +25,6 @@ Document.prototype.add = function (id, content, _append) { return this.update(id, content); } - // this.field does not include db tag indexes for (let i = 0, tree; i < this.field.length; i++) { tree = this.tree[i]; @@ -34,7 +33,7 @@ Document.prototype.add = function (id, content, _append) { if ("function" == typeof tree) { const tmp = tree(content); if (tmp) { - index.add(id, tmp, /* suggest */ /* append: */!1, /* tag? */ /* stringify */ /* stringify */ /* single param */ /* skip update: */ /* append: */ /* skip update: */ /* skip_update: */!0 /*await rows.hasNext()*/ /*await rows.hasNext()*/ /*await rows.hasNext()*/); + index.add(id, tmp, !0); } } else { const filter = tree._filter; @@ -52,8 +51,6 @@ Document.prototype.add = function (id, content, _append) { if (this.tag) { - //console.log(this.tag, this.tagtree) - for (let x = 0; x < this.tagtree.length; x++) { let tree = this.tagtree[x], field = this.tagfield[x], @@ -88,7 +85,6 @@ Document.prototype.add = function (id, content, _append) { for (let i = 0, tag, arr; i < tags.length; i++) { tag = tags[i]; - //console.log(this.tag, tag, key, field) if (!dupes[tag]) { dupes[tag] = 1; @@ -98,24 +94,21 @@ Document.prototype.add = function (id, content, _append) { tmp ? arr = tmp : ref.set(tag, arr = []); if (!_append || ! /** @type {!Array|KeystoreArray} */arr.includes(id)) { - - // auto-upgrade to keystore array if max size exceeded - if (2147483647 === arr.length /*|| !(arr instanceof KeystoreArray)*/) { - const keystore = new KeystoreArray(arr); - if (this.fastupdate) { - for (let value of this.reg.values()) { - if (value.includes(arr)) { - value[value.indexOf(arr)] = keystore; - } + if (2147483647 === arr.length) { + const keystore = new KeystoreArray(arr); + if (this.fastupdate) { + for (let value of this.reg.values()) { + if (value.includes(arr)) { + value[value.indexOf(arr)] = keystore; } } - ref.set(tag, arr = keystore); } + ref.set(tag, arr = keystore); + } arr.push(id); - // add a reference to the register for fast updates if (this.fastupdate) { const tmp = this.reg.get(id); tmp ? tmp.push(arr) : this.reg.set(id, [arr]); @@ -166,8 +159,6 @@ Document.prototype.add = function (id, content, _append) { return this; }; -// TODO support generic function created from string when tree depth > 1 - /** * @param obj * @param store @@ -181,10 +172,8 @@ function store_value(obj, store, tree, pos, key, custom) { obj = obj[key]; - // reached target field if (pos === tree.length - 1) { - // store target value store[key] = custom || obj; } else if (obj) { @@ -193,7 +182,7 @@ function store_value(obj, store, tree, pos, key, custom) { store = store[key] = Array(obj.length); for (let i = 0; i < obj.length; i++) { - // do not increase pos (an array is not a field) + store_value(obj, store, tree, pos, i); } } else { @@ -209,21 +198,17 @@ function add_index(obj, tree, marker, pos, index, id, key, _append) { if (obj = obj[key]) { - // reached target field if (pos === tree.length - 1) { - // handle target value if (is_array(obj)) { - // append array contents so each entry gets a new scoring context if (marker[pos]) { for (let i = 0; i < obj.length; i++) { - index.add(id, obj[i], !0, !0); + index.add(id, obj[i], !0); } return; } - // or join array contents and use one scoring context obj = obj.join(" "); } @@ -232,7 +217,7 @@ function add_index(obj, tree, marker, pos, index, id, key, _append) { if (is_array(obj)) { for (let i = 0; i < obj.length; i++) { - // do not increase index, an array is not a field + add_index(obj, tree, marker, pos, index, id, i, _append); } } else { diff --git a/dist/module-debug/document/highlight.js b/dist/module-debug/document/highlight.js index 8b9c7a1..30e767c 100644 --- a/dist/module-debug/document/highlight.js +++ b/dist/module-debug/document/highlight.js @@ -13,9 +13,6 @@ import { EnrichedDocumentSearchResults, EnrichedSearchResults, HighlightOptions */ export function highlight_fields(query, result, index, pluck, config) { - // The biggest issue is dealing with custom encoders, for this reason - // a combined regular expression can't apply as a template - let template, markup_open, markup_close; if ("string" == typeof config) { @@ -41,7 +38,7 @@ export function highlight_fields(query, result, index, pluck, config) { markup_open = template.substring(0, markup_open); let boundary = config && config.boundary, - clip = !config || /* suggest */ /* append: */!1 !== config.clip, + clip = !config || !1 !== config.clip, merge = config && config.merge && markup_close && markup_open && new RegExp(markup_close + " " + markup_open, "g"), ellipsis = config && config.ellipsis, ellipsis_markup_length = 0, @@ -72,28 +69,23 @@ export function highlight_fields(query, result, index, pluck, config) { boundary = boundary.total || 9e5; } - // cache shared encoders across fields let encoder = new Map(), query_enc; - // todo remove this loop and pass in the field data directly - // todo support field-specific configuration - - // for every field for (let i = 0, enc, idx, path; i < result.length; i++) { /** @type {EnrichedSearchResults} */ let res; if (pluck) { - //res = result[0].result; + res = result; path = pluck; } else { const tmp = result[i]; path = tmp.field; - // skip when not a field entry (e.g. tags) + if (!path) continue; res = tmp.result; } @@ -103,20 +95,18 @@ export function highlight_fields(query, result, index, pluck, config) { idx.tokenize; query_enc = encoder.get(enc); - // re-encode query when encoder has changed or take cache from shared encoders if ("string" != typeof query_enc) { query_enc = enc.encode(query); encoder.set(enc, query_enc); } - // for every doc in results for (let j = 0; j < res.length; j++) { const doc = res[j].doc; if (!doc) continue; const content = parse_simple(doc, path); if (!content) continue; - // just split on whitespace and keep original string (encoder split can't apply) + const doc_org = content.trim().split(/\s+/); if (!doc_org.length) continue; @@ -128,7 +118,6 @@ export function highlight_fields(query, result, index, pluck, config) { length_matches_all = 0; - // loop terms of encoded doc content for (let k = 0; k < doc_org.length; k++) { let doc_org_cur = doc_org[k], doc_enc_cur = enc.encode(doc_org_cur); @@ -144,48 +133,37 @@ export function highlight_fields(query, result, index, pluck, config) { match_length = 0; - // loop terms of encoded query content and determine the longest match for (let l = 0, query_enc_cur; l < query_enc.length; l++) { query_enc_cur = query_enc[l]; if (!query_enc_cur) continue; let query_enc_cur_len = query_enc_cur.length; - // add length from shrinking phonetic transformations (todo: add tests) + query_enc_cur_len += doc_org_diff; - // skip query token when match length can't exceed previously highest found match + if (match_length && query_enc_cur_len <= match_length) { continue; } const position = doc_enc_cur.indexOf(query_enc_cur); if (-1 < position) { - match = - // prefix - (position ? doc_org_cur.substring(0, position) : "") + - // match - markup_open + doc_org_cur.substring(position, position + query_enc_cur_len) + markup_close + ( - // suffix - position + query_enc_cur_len < doc_org_cur_len ? doc_org_cur.substring(position + query_enc_cur_len) : ""); + match = (position ? doc_org_cur.substring(0, position) : "") + markup_open + doc_org_cur.substring(position, position + query_enc_cur_len) + markup_close + (position + query_enc_cur_len < doc_org_cur_len ? doc_org_cur.substring(position + query_enc_cur_len) : ""); match_length = query_enc_cur_len; - found = /* tag? */ /* stringify */ /* stringify */ /* single param */ /* skip update: */ /* append: */ /* skip update: */ /* skip_update: */!0 /*await rows.hasNext()*/ /*await rows.hasNext()*/ /*await rows.hasNext()*/; + found = !0; } - //console.log(doc_org_cur, doc_enc_cur, query_enc_cur, position, match) } - // apply the longest match if (match) { if (boundary) { - // the outer boundary is used to check if all matches are within the total boundary - // if so, it can apply a simpler alignment + if (0 > pos_first_match) { pos_first_match = str.length + (str ? 1 : 0); } pos_last_match = str.length + (str ? 1 : 0) + match.length; - // the overall length of all matches is used to check if matches exceeds the total boundary - // if so, it can early stop further processing + length_matches_all += doc_org_cur_len; - // the match positions are used to pick items for the final result more quickly + pos_matches.push(str_arr.length); - // collect every term as match or text + str_arr.push({ match }); } str += (str ? " " : "") + match; @@ -195,23 +173,19 @@ export function highlight_fields(query, result, index, pluck, config) { if (!found) { const text = doc_org[k]; str += (str ? " " : "") + text; - // collect every term as match or text + boundary && str_arr.push({ text }); } else if (boundary) { if (length_matches_all >= boundary) { - // matches has reached total boundary + break; } } } - // the markup length does not apply to the total boundary let markup_length = pos_matches.length * (template.length - 2); - // apply boundaries and align highlights if (boundary_before || boundary_after || boundary && str.length - markup_length > boundary) { - - // also reduce ellipsis length from boundary let boundary_length = boundary + markup_length - 2 * ellipsis_length, length = pos_last_match - pos_first_match, start, @@ -225,13 +199,11 @@ export function highlight_fields(query, result, index, pluck, config) { length += boundary_after; } - // 1. all matches are withing the overall boundary (apply simple alignment) if (length <= boundary_length) { start = boundary_before ? pos_first_match - (0 < boundary_before ? boundary_before : 0) : pos_first_match - (0 | (boundary_length - length) / 2); end = boundary_after ? pos_last_match + (0 < boundary_after ? boundary_after : 0) : start + boundary_length; - // do not clip terms if (!clip) { if (0 < start) { if (" " === str.charAt(start)) {} else if (" " !== str.charAt(start - 1)) { @@ -248,253 +220,227 @@ export function highlight_fields(query, result, index, pluck, config) { } str = (start ? ellipsis : "") + str.substring(start, end) + (end < str.length ? ellipsis : ""); - } - // 2. matches needs to be split by surrounded terms to fit into the boundary - else { - const final = [], - check = {}, - seamless = {}, - finished = {}, - before = {}, - after = {}; - let final_length = 0, - shift_left = 0, - shift_right = 0, - loop_left = 1, - loop_right = 1; + } else { + const final = [], + check = {}, + seamless = {}, + finished = {}, + before = {}, + after = {}; + let final_length = 0, + shift_left = 0, + shift_right = 0, + loop_left = 1, + loop_right = 1; - while (!0) { + while (!0) { - let loop; + let loop; - for (let k = 0, pos; k < pos_matches.length; k++) { + for (let k = 0, pos; k < pos_matches.length; k++) { - pos = pos_matches[k]; + pos = pos_matches[k]; - // 1. add matches to the result - if (!shift_right) { - str = str_arr[pos].match; + if (!shift_right) { + str = str_arr[pos].match; - // initialize custom boundaries for each slot - if (boundary_before) { - before[k] = boundary_before; - } - if (boundary_after) { - after[k] = boundary_after; - } - - // count whitespaces between each term - if (k) { - final_length++; - } - - let close; - - // close left side when first term was matched - if (!pos) { - // it can be set before content was added, - // because the first term match is always added - seamless[k] = 1; - finished[k] = 1; - } - // initial ellipsis - else if (!k && ellipsis_length) { - final_length += ellipsis_length; - } - - // close right side when last term was matched - if (pos >= doc_org.length - 1) { - close = 1; - } - // close right side when next term was a match - else if (pos < str_arr.length - 1 && str_arr[pos + 1].match) { - close = 1; - } else if (ellipsis_length) { - final_length += ellipsis_length; - } - - // reduce template length on matches - final_length -= template.length - 2; - - // at least add one match - if (!k || final_length + str.length <= boundary) { - final[k] = str; - } else { - seamless[k] = 0; - loop = loop_left = loop_right = 0; - break; - } - - // update state when term was added - if (close) { - seamless[k + 1] = 1; - finished[k + 1] = 1; - } + if (boundary_before) { + before[k] = boundary_before; + } + if (boundary_after) { + after[k] = boundary_after; } - // 2. add surrounded text to the result - else { - // alternate direction term by term - // 2.1. extend to right first (index: k + 1) - if (shift_left != shift_right) { - if (finished[k + 1]) continue; - pos += shift_right; - // overlap with other slot - if (check[pos]) { - final_length -= ellipsis_length; - seamless[k + 1] = 1; - finished[k + 1] = 1; - continue; - } - // end reached - if (pos >= str_arr.length - 1) { - if (pos >= str_arr.length) { - finished[k + 1] = 1; - if (pos >= doc_org.length) { - seamless[k + 1] = 1; - } - continue; - } - final_length -= ellipsis_length; - } + if (k) { + final_length++; + } - str = str_arr[pos].text; + let close; - let current_after = boundary_after && after[k]; - if (current_after) { - if (0 < current_after) { - if (str.length > current_after) { - finished[k + 1] = 1; - if (clip) { - str = str.substring(0, current_after); - } else { - continue; - } - } - current_after -= str.length; - if (!current_after) current_after = -1; - after[k] = current_after; - } else { - finished[k + 1] = 1; - continue; - } - } + if (!pos) { - // count whitespaces between each term - if (final_length + str.length + 1 <= boundary) { - str = " " + str; - final[k] += str; - } else if (clip) { - const diff = boundary - final_length - 1; - if (0 < diff) { - str = " " + str.substring(0, diff); - final[k] += str; - } - finished[k + 1] = 1; - } else { - finished[k + 1] = 1; - continue; - } - } - // 2.2. extend to left (index: k) - else { - if (finished[k]) continue; - pos -= shift_left; + seamless[k] = 1; + finished[k] = 1; + } else if (!k && ellipsis_length) { + final_length += ellipsis_length; + } - // overlap with other slot - if (check[pos]) { - final_length -= ellipsis_length; - finished[k] = 1; - seamless[k] = 1; - continue; - } - // start reached - if (0 >= pos) { - if (0 > pos) { - finished[k] = 1; - seamless[k] = 1; - continue; - } - final_length -= ellipsis_length; - } + if (pos >= doc_org.length - 1) { + close = 1; + } else if (pos < str_arr.length - 1 && str_arr[pos + 1].match) { + close = 1; + } else if (ellipsis_length) { + final_length += ellipsis_length; + } - str = str_arr[pos].text; + final_length -= template.length - 2; - let current_before = boundary_before && before[k]; - if (current_before) { - if (0 < current_before) { - if (str.length > current_before) { - finished[k] = 1; - if (clip) { - str = str.substring(str.length - current_before); - } else { - continue; - } - } - current_before -= str.length; - if (!current_before) current_before = -1; - before[k] = current_before; - } else { - finished[k] = 1; - continue; - } - } - - // count whitespaces between each term - if (final_length + str.length + 1 <= boundary) { - str += " "; - final[k] = str + final[k]; - } else if (clip) { - const diff = str.length + 1 - (boundary - final_length); - if (0 <= diff && diff < str.length) { - str = str.substring(diff) + " "; - final[k] = str + final[k]; - } - finished[k] = 1; - } else { - finished[k] = 1; - continue; - } - } - } - - // update state when term was added - final_length += str.length; - check[pos] = 1; - loop = 1; - } - - if (loop) { - // alternate shift direction - shift_left == shift_right ? shift_right++ : shift_left++; - } else { - // check finish state - shift_left == shift_right ? loop_left = 0 : loop_right = 0; - // break process when both directions are done - if (!loop_left && !loop_right) { + if (!k || final_length + str.length <= boundary) { + final[k] = str; + } else { + seamless[k] = 0; + loop = loop_left = loop_right = 0; break; } - // continue with opposite direction - if (loop_left) { - shift_left++; - shift_right = shift_left; + + if (close) { + seamless[k + 1] = 1; + finished[k + 1] = 1; + } + } else { + + if (shift_left != shift_right) { + if (finished[k + 1]) continue; + pos += shift_right; + + if (check[pos]) { + final_length -= ellipsis_length; + seamless[k + 1] = 1; + finished[k + 1] = 1; + continue; + } + + if (pos >= str_arr.length - 1) { + if (pos >= str_arr.length) { + finished[k + 1] = 1; + if (pos >= doc_org.length) { + seamless[k + 1] = 1; + } + continue; + } + final_length -= ellipsis_length; + } + + str = str_arr[pos].text; + + let current_after = boundary_after && after[k]; + if (current_after) { + if (0 < current_after) { + if (str.length > current_after) { + finished[k + 1] = 1; + if (clip) { + str = str.substring(0, current_after); + } else { + continue; + } + } + current_after -= str.length; + if (!current_after) current_after = -1; + after[k] = current_after; + } else { + finished[k + 1] = 1; + continue; + } + } + + if (final_length + str.length + 1 <= boundary) { + str = " " + str; + final[k] += str; + } else if (clip) { + const diff = boundary - final_length - 1; + if (0 < diff) { + str = " " + str.substring(0, diff); + final[k] += str; + } + finished[k + 1] = 1; + } else { + finished[k + 1] = 1; + continue; + } } else { - shift_right++; + if (finished[k]) continue; + pos -= shift_left; + + if (check[pos]) { + final_length -= ellipsis_length; + finished[k] = 1; + seamless[k] = 1; + continue; + } + + if (0 >= pos) { + if (0 > pos) { + finished[k] = 1; + seamless[k] = 1; + continue; + } + final_length -= ellipsis_length; + } + + str = str_arr[pos].text; + + let current_before = boundary_before && before[k]; + if (current_before) { + if (0 < current_before) { + if (str.length > current_before) { + finished[k] = 1; + if (clip) { + str = str.substring(str.length - current_before); + } else { + continue; + } + } + current_before -= str.length; + if (!current_before) current_before = -1; + before[k] = current_before; + } else { + finished[k] = 1; + continue; + } + } + + if (final_length + str.length + 1 <= boundary) { + str += " "; + final[k] = str + final[k]; + } else if (clip) { + const diff = str.length + 1 - (boundary - final_length); + if (0 <= diff && diff < str.length) { + str = str.substring(diff) + " "; + final[k] = str + final[k]; + } + finished[k] = 1; + } else { + finished[k] = 1; + continue; + } } } + + final_length += str.length; + check[pos] = 1; + loop = 1; } - str = ""; - for (let k = 0, tmp; k < final.length; k++) { - tmp = (k && seamless[k] ? " " : (k && !ellipsis ? " " : "") + ellipsis) + final[k]; - str += tmp; + if (loop) { + + shift_left == shift_right ? shift_right++ : shift_left++; + } else { + + shift_left == shift_right ? loop_left = 0 : loop_right = 0; + + if (!loop_left && !loop_right) { + break; + } + + if (loop_left) { + shift_left++; + shift_right = shift_left; + } else { + shift_right++; + } } - if (ellipsis && !seamless[final.length]) { - str += ellipsis; - } - //console.log(query, seamless, final) } + + str = ""; + for (let k = 0, tmp; k < final.length; k++) { + tmp = (k && seamless[k] ? " " : (k && !ellipsis ? " " : "") + ellipsis) + final[k]; + str += tmp; + } + if (ellipsis && !seamless[final.length]) { + str += ellipsis; + } + } } if (merge) { @@ -510,303 +456,4 @@ export function highlight_fields(query, result, index, pluck, config) { } return result; -} - -// /** -// * @param {string} query -// * @param {EnrichedDocumentSearchResults|EnrichedSearchResults} result -// * @param {Map} index -// * @param {string} pluck -// * @param {HighlightOptions|string} config -// * @return {EnrichedDocumentSearchResults|EnrichedSearchResults} -// */ -// export function highlight_fields(query, result, index, pluck, config){ -// -// // The biggest issue is dealing with custom encoders, for this reason -// // a combined regular expression can't apply as a template -// -// let template, markup_open, markup_close; -// -// if(typeof config === "string"){ -// template = config; -// config = ""; -// } -// else{ -// template = config.template; -// } -// -// if(DEBUG){ -// if(!template){ -// throw new Error('No template pattern was specified by the search option "highlight"'); -// } -// } -// -// markup_open = template.indexOf("$1"); -// -// if(DEBUG){ -// if(markup_open === -1){ -// throw new Error('Invalid highlight template. The replacement pattern "$1" was not found in template: ' + template); -// } -// } -// -// markup_close = template.substring(markup_open + 2); -// markup_open = template.substring(0, markup_open); -// -// let boundary = config && config.boundary; -// let clip = !config || config.clip !== false; -// let merge = config && config.merge && markup_close && markup_open && new RegExp(markup_close + " " + markup_open, "g"); -// let ellipsis = config && config.ellipsis; -// if(typeof ellipsis !== "string"){ -// ellipsis = "..."; -// } -// -// let boundary_before, boundary_after; -// -// if(typeof boundary === "object"){ -// boundary_before = boundary.before; -// if(boundary_before === 0) boundary_before = -1; -// boundary_after = boundary.after; -// if(boundary_after === 0) boundary_after = -1; -// boundary = boundary.total || 9e5; -// } -// -// // cache shared encoders across fields -// let encoder = new Map(); -// let query_enc; -// let tokenize; -// -// // todo remove this loop and pass in the field data directly -// // todo support field-specific configuration -// -// // for every field -// for(let i = 0, enc, idx, path; i < result.length; i++){ -// -// /** @type {EnrichedSearchResults} */ -// let res; -// -// if(pluck){ -// res = result; -// path = pluck; -// } -// else{ -// const tmp = result[i]; -// path = tmp.field; -// // skip when not a field entry (e.g. tags) -// if(!path) continue; -// res = tmp.result; -// } -// -// idx = index.get(path); -// enc = idx.encoder; -// tokenize = idx.tokenize; -// query_enc = encoder.get(enc); -// -// // re-encode query when encoder has changed or take cache from shared encoders -// if(typeof query_enc !== "string"){ -// query_enc = enc.encode(query); -// encoder.set(enc, query_enc); -// } -// -// // for every doc in results -// for(let j = 0; j < res.length; j++){ -// -// const doc = res[j]["doc"]; -// if(!doc) continue; -// const content = parse_simple(doc, path); -// if(!content) continue; -// const doc_org = content.trim().split(/\s+/); -// if(!doc_org.length) continue; -// -// let str = ""; -// let pos_matches = []; -// let length_matches_all = 0; -// -// // loop terms of encoded doc content -// for(let k = 0; k < doc_org.length; k++){ -// let doc_org_cur = doc_org[k]; -// let doc_org_cur_len = doc_org_cur.length; -// let doc_enc_cur = enc.encode(doc_org_cur); -// doc_enc_cur = doc_enc_cur.length > 1 -// ? doc_enc_cur.join(" ") -// : doc_enc_cur[0]; -// -// let found; -// -// if(doc_enc_cur && doc_org_cur){ -// -// let match = ""; -// let match_length = 0; -// -// // loop terms of encoded query content and determine the longest match -// for(let l = 0; l < query_enc.length; l++){ -// let query_enc_cur = query_enc[l]; -// if(!query_enc_cur) continue; -// let query_enc_cur_len = query_enc_cur.length; -// // add length from shrinking phonetic transformations (todo: add tests) -// query_enc_cur_len += doc_org_cur.length - doc_enc_cur.length; -// // skip query token when match length can't exceed previously highest found match -// if(match_length && query_enc_cur_len <= match_length){ -// continue; -// } -// const position = doc_enc_cur.indexOf(query_enc_cur); -// //console.log(doc_org_cur, doc_enc_cur, query_enc_cur, position) -// if(position > -1){ -// match = -// // prefix -// (position ? doc_org_cur.substring(0, position) : "") + -// // match -// markup_open + doc_org_cur.substring(position, position + query_enc_cur_len) + markup_close + -// // suffix -// (position + query_enc_cur_len < doc_org_cur_len ? doc_org_cur.substring(position + query_enc_cur_len) : ""); -// match_length = query_enc_cur_len; -// found = true; -// } -// } -// -// // apply the longest match -// if(match){ -// if(boundary){ -// if(!pos_matches.length && k) length_matches_all += ellipsis.length; -// // the overall length of all matches is used to check if matches exceeds the total boundary -// // if so, it can early stop further processing -// length_matches_all += match.length;//doc_org_cur_len + (str ? 1 : 0) + (k < doc_org.length - 1 ? ellipsis.length : 0); -// // the match positions are used to pick items for the final result more quickly -// pos_matches.push([ -// str.length + (str ? 1 : 0), -// str.length + (str ? 1 : 0) + match.length, -// k -// ]); -// } -// str += (str ? " " : "") + match; -// } -// } -// -// if(!found){ -// const text = doc_org[k]; -// str += (str ? " " : "") + text; -// } -// else if(boundary){ -// if(length_matches_all >= boundary){ -// // matches has reached total boundary -// break; -// } -// } -// } -// -// // the markup length does not apply to the total boundary -// let markup_length = pos_matches.length * (template.length - 2); -// -// // apply boundaries and align highlights -// if(boundary_before || boundary_after || (boundary && (str.length - markup_length) > boundary)){ -// -// let final = ""; -// let surrounded_length = (((((boundary + markup_length) - length_matches_all) / pos_matches.length) - ellipsis.length) / 2); -// //if(surrounded_length < 0) surrounded_length = 0; -// -// let before = boundary_before || ( -// surrounded_length > 0 -// ? Math.floor(surrounded_length + -// (boundary_after -// ? surrounded_length - boundary_after -// : 0)) -// : 0 -// ); -// let after = boundary_after || ( -// surrounded_length > 0 -// ? Math.ceil(surrounded_length + -// (boundary_before -// ? surrounded_length - boundary_before -// : 0)) -// : 0 -// ); -// -// //console.log(surrounded_length, before, after) -// -// for(let k = 0, cur, prev, next; k < pos_matches.length; k++){ -// -// prev = cur; -// cur = next || pos_matches[k]; -// next = pos_matches[k + 1]; -// -// let start = cur[0] - before; -// let end = cur[1] + after; -// let closed_left; -// let closed_right; -// -// // if(k){ -// // closed_left = 1; -// // } -// -// // apply right limit -// if(next && (end >= next[0] - before)){ -// end = cur[1] + (next[0] - cur[1]) / 2 | 0; -// start -= ellipsis.length + 1; -// closed_right = 1; -// } -// // apply left limit -// if(prev && (start <= prev[1] + after)){ -// start = cur[0] - (cur[0] - prev[1]) / 2 | 0; -// end += ellipsis.length + 1; -// closed_left = 1; -// -// // repeat right limit -// if(next && (end >= next[0] - before)){ -// end = cur[1] + (next[0] - cur[1]) / 2 | 0; -// closed_right = 1; -// } -// } -// -// //console.log(start, end, prev, cur, next); -// -// // do not clip terms -// if(!clip){ -// if(start){ -// if(str.charAt(start) === " "){ -// //start++; -// } -// else if(str.charAt(start - 1) !== " "){ -// start = str.indexOf(" ", start); -// start < 0 -// ? start = cur[0] -// : start;//++; -// } -// } -// if(end < str.length){ -// if(str.charAt(end - 1) === " "){ -// //end--; -// } -// else if(str.charAt(end) !== " "){ -// end = str.lastIndexOf(" ", end); -// end < cur[1] -// ? end = cur[1] -// : end++; -// } -// } -// } -// -// final += -// /*(final ? " " : "") +*/ -// (!closed_left && start > 0 ? ellipsis : "") + -// str.substring(start, end) + -// (!closed_right && cur[2] < doc_org.length - 1 ? ellipsis : ""); -// -// //console.log(final) -// } -// -// str = final; -// } -// -// if(merge){ -// str = str.replace(merge, " "); -// } -// -// res[j]["highlight"] = str; -// } -// -// if(pluck){ -// break; -// } -// } -// -// return result; -// } \ No newline at end of file +} \ No newline at end of file diff --git a/dist/module-debug/document/search.js b/dist/module-debug/document/search.js index e497ebc..0fb7e1d 100644 --- a/dist/module-debug/document/search.js +++ b/dist/module-debug/document/search.js @@ -1,6 +1,6 @@ import { DocumentSearchOptions, DocumentSearchResults, EnrichedDocumentSearchResults, MergedDocumentSearchResults, MergedDocumentSearchEntry, EnrichedSearchResults, SearchResults, IntermediateSearchResults } from "../type.js"; -import { create_object, is_array, is_object, is_string } from "../common.js"; +import { create_object, is_array, is_object, is_string, inherit } from "../common.js"; import { intersect, intersect_union } from "../intersect.js"; import Document from "../document.js"; import Index from "../index.js"; @@ -46,10 +46,9 @@ Document.prototype.search = function (query, limit, options, _promises) { } if (options && options.cache) { - options.cache = /* suggest */ /* append: */ /* enrich */!1; + options.cache = !1; const res = this.searchCache(query, limit, options); - options.cache = /* tag? */ /* stringify */ /* stringify */ /* single param */ /* skip update: */ /* append: */ /* skip update: */ /* skip_update: */!0 /*await rows.hasNext()*/ /*await rows.hasNext()*/ - /*await rows.hasNext()*/; + options.cache = !0; return res; } @@ -112,10 +111,6 @@ Document.prototype.search = function (query, limit, options, _promises) { tag = [tag]; } - // ----------------------------- - // Tag-Search - // ----------------------------- - let pairs = []; for (let i = 0, field; i < tag.length; i++) { @@ -123,7 +118,7 @@ Document.prototype.search = function (query, limit, options, _promises) { if (is_string(field)) { throw new Error("A tag option can't be a string, instead it needs a { field: tag } format."); } - // default array notation + if (field.field && field.tag) { const value = field.tag; if (value.constructor === Array) { @@ -133,33 +128,28 @@ Document.prototype.search = function (query, limit, options, _promises) { } else { pairs.push(field.field, value); } - } - // shorter object notation - else { - const keys = Object.keys(field); - for (let j = 0, key, value; j < keys.length; j++) { - key = keys[j]; - value = field[key]; - if (value.constructor === Array) { - for (let k = 0; k < value.length; k++) { - pairs.push(key, value[k]); - } - } else { - pairs.push(key, value); + } else { + const keys = Object.keys(field); + for (let j = 0, key, value; j < keys.length; j++) { + key = keys[j]; + value = field[key]; + if (value.constructor === Array) { + for (let k = 0; k < value.length; k++) { + pairs.push(key, value[k]); } + } else { + pairs.push(key, value); } } + } } if (!pairs.length) { throw new Error("Your tag definition within the search options is probably wrong. No valid tags found."); } - // tag used as pairs from this point tag = pairs; - // when tags is used and no query was set, - // then just return the tag indexes if (!query) { let promises = []; @@ -194,15 +184,14 @@ Document.prototype.search = function (query, limit, options, _promises) { result[j] = promises[j]; } } - return resolve || !!0 ? result : new Resolver(1 < result.length ? intersect(result, 1, 0, 0, suggest, boost) : result[0], self); + return resolve ? result : new Resolver(1 < result.length ? intersect( /** @type {!Array} */result, 1, 0, 0, suggest, boost) : result[0], self); }); } - return resolve || !!0 ? result : new Resolver(1 < result.length ? intersect(result, 1, 0, 0, suggest, boost) : result[0], this); + return resolve ? result : new Resolver(1 < result.length ? intersect( /** @type {!Array} */result, 1, 0, 0, suggest, boost) : result[0], this); } } - // upgrade pluck when missing if (!resolve && !pluck) { field = field || this.field; if (field) { @@ -220,7 +209,6 @@ Document.prototype.search = function (query, limit, options, _promises) { } } - // extend to multi field search by default if (field && field.constructor !== Array) { field = [field]; } @@ -234,15 +222,12 @@ Document.prototype.search = function (query, limit, options, _promises) { ) && !_promises && []; - // multi field search - // field could be a custom set of selected fields by this query - // db tag indexes are also included in this field list for (let i = 0, res, key, len; i < field.length; i++) { key = field[i]; if (this.db && this.tag) { - // tree is missing when it is a tag-only index (db) + if (!this.tree[i]) { continue; } @@ -279,32 +264,28 @@ Document.prototype.search = function (query, limit, options, _promises) { } } if (promises) { - promises[i] = index.search /*Async*/(query, limit, opt); - // restore enrich state + promises[i] = index.search(query, limit, opt); + opt && enrich && (opt.enrich = enrich); - // just collect and continue + continue; } else { res = index.search(query, limit, opt); - // restore enrich state + opt && enrich && (opt.enrich = enrich); } } len = res && (resolve ? res.length : res.result.length); - // todo when no term was matched but tag was retrieved extend suggestion to tags - // every field has to intersect against all selected tag fields if (tag && len) { const arr = []; let count = 0; - // tags are only applied in resolve phase when it's a db if (this.db && _promises) { if (!db_tag_search) { - // retrieve tag results assigned to it's field for (let y = field.length; y < _promises.length; y++) { let ids = _promises[y], len = ids && ids.length; @@ -314,14 +295,13 @@ Document.prototype.search = function (query, limit, options, _promises) { count++; arr.push(ids); } else if (!suggest) { - // no tags found - return resolve || !!0 ? result : new Resolver(result, this); + + return resolve ? result : new Resolver(result, this); } } } } else { - // tag[] are pairs at this line for (let y = 0, ids, len; y < tag.length; y += 2) { ids = this.tag.get(tag[y]); @@ -331,7 +311,7 @@ Document.prototype.search = function (query, limit, options, _promises) { if (suggest) { continue; } else { - return resolve || !!0 ? result : new Resolver(result, this); + return resolve ? result : new Resolver(result, this); } } @@ -342,20 +322,20 @@ Document.prototype.search = function (query, limit, options, _promises) { count++; arr.push(ids); } else if (!suggest) { - // no tags found - return resolve || !!0 ? result : new Resolver(result, this); + + return resolve ? result : new Resolver(result, this); } } } if (count) { - res = intersect_union(res, arr, resolve); // intersect(arr, limit, offset) + res = intersect_union(res, arr, resolve); len = res.length; if (!len && !suggest) { - // nothing matched - return resolve || !!0 ? res : new Resolver( /** @type {IntermediateSearchResults} */res, this); + + return resolve ? res : new Resolver( /** @type {IntermediateSearchResults} */res, this); } - // move counter back by 1 + count--; } } @@ -365,18 +345,17 @@ Document.prototype.search = function (query, limit, options, _promises) { result.push(res); count++; } else if (1 === field.length) { - // fast path: nothing matched - return resolve || !!0 ? result : new Resolver(result, this); + + return resolve ? result : new Resolver(result, this); } } if (promises) { if (this.db) { - // todo when a tag index is never a search index this could be extracted - // push tag promises to the end + if (tag && tag.length && !db_tag_search) { for (let y = 0; y < tag.length; y += 2) { - // it needs to retrieve data from tag pairs + const index = this.index.get(tag[y]); if (!index) { console.warn("Tag '" + tag[y] + ":" + tag[y + 1] + "' was not found because there is no field '" + tag[y] + "'."); @@ -384,7 +363,7 @@ Document.prototype.search = function (query, limit, options, _promises) { if (suggest) { continue; } else { - return resolve || !!0 ? result : new Resolver(result, this); + return resolve ? result : new Resolver(result, this); } } @@ -395,14 +374,13 @@ Document.prototype.search = function (query, limit, options, _promises) { const self = this; - // TODO unroll this recursion return Promise.all(promises).then(function (result) { - return result.length ? self.search(query, limit, options, /* promises: */result) : result; + return result.length ? self.search(query, limit, options, result) : result; }); } if (!count) { - return resolve || !!0 ? result : new Resolver(result, this); + return resolve ? result : new Resolver(result, this); } if (pluck && (!enrich || !this.store)) { result = result[0]; @@ -421,18 +399,16 @@ Document.prototype.search = function (query, limit, options, _promises) { if (enrich && res.length && "undefined" == typeof res[0].doc) { if (!this.db) { - // if(res.length){ + res = apply_enrich.call(this, res); - // } } else { - // todo - // the documents are stored on the first field + promises.push(res = this.index.get(this.field[0]).db.enrich(res)); } } if (pluck) { - return resolve || !!0 ? highlight ? highlight_fields( /** @type {string} */query, res, this.index, pluck, highlight) : /** @type {SearchResults|EnrichedSearchResults} */res : new Resolver( /** @type {IntermediateSearchResults} */res, this); + return resolve ? highlight ? highlight_fields( /** @type {string} */query, res, this.index, pluck, highlight) : /** @type {SearchResults|EnrichedSearchResults} */res : new Resolver( /** @type {IntermediateSearchResults} */res, this); } result[i] = { @@ -447,22 +423,19 @@ Document.prototype.search = function (query, limit, options, _promises) { for (let j = 0; j < promises.length; j++) { result[j].result = promises[j]; } - return merge ? merge_fields(result) : highlight ? highlight_fields( /** @type {string} */query, result, self.index, pluck, highlight) : /** @type {DocumentSearchResults} */result; + if (highlight) { + result = highlight_fields( /** @type {string} */query, result, self.index, pluck, highlight); + } + return merge ? merge_fields(result) : /** @type {DocumentSearchResults} */result; }); } - return merge ? merge_fields(result) : highlight ? highlight_fields( /** @type {string} */query, result, this.index, pluck, highlight) : /** @type {DocumentSearchResults} */result; + if (highlight) { + result = highlight_fields( /** @type {string} */query, result, this.index, pluck, highlight); + } + return merge ? merge_fields(result) : /** @type {DocumentSearchResults} */result; }; -function inherit(target_value, default_value) { - return "undefined" == typeof target_value ? default_value : target_value; -} - -// todo support Resolver -// todo when searching through multiple fields each term should -// be found at least by one field to get a valid match without -// using suggestion explicitly - /** * @param {DocumentSearchResults} fields * @return {MergedDocumentSearchResults} @@ -470,24 +443,31 @@ function inherit(target_value, default_value) { function merge_fields(fields) { /** @type {MergedDocumentSearchResults} */ const final = [], - set = create_object(); + group_field = create_object(), + group_highlight = create_object(); - for (let i = 0, field, res; i < fields.length; i++) { + for (let i = 0, field, key, res, id, entry, tmp, highlight; i < fields.length; i++) { field = fields[i]; + key = field.field; res = field.result; - for (let j = 0, id, entry, tmp; j < res.length; j++) { + for (let j = 0; j < res.length; j++) { entry = res[j]; - // upgrade flat results - if ("object" != typeof entry) { - entry = { id: entry }; - } - id = entry.id; - tmp = set[id]; + + "object" != typeof entry ? entry = { id: id = entry } : id = entry.id; + tmp = group_field[id]; if (!tmp) { - entry.field = set[id] = [field.field]; + entry.field = group_field[id] = [key]; final.push( /** @type {MergedDocumentSearchEntry} */entry); } else { - tmp.push(field.field); + tmp.push(key); + } + if (highlight = entry.highlight) { + tmp = group_highlight[id]; + if (!tmp) { + group_highlight[id] = tmp = {}; + entry.highlight = tmp; + } + tmp[key] = highlight; } } } @@ -498,14 +478,24 @@ function merge_fields(fields) { * @this {Document} */ -function get_tag(tag, key, limit, offset) { +function get_tag(tag, key, limit, offset, enrich) { + let res = this.tag.get(tag); - if (!res) { - console.warn("Tag-Field '" + tag + "' was not found"); - return []; + if (!res) return []; + res = res.get(key); + if (!res) return []; + let len = res.length - offset; + + if (0 < len) { + if (limit && len > limit || offset) { + res = res.slice(offset, offset + limit); + } + if (enrich) { + res = apply_enrich.call(this, res); + } } - res = res && res.get(key); - res && res.length - offset; + + return res; } /** diff --git a/dist/module-debug/encoder.js b/dist/module-debug/encoder.js index 4bcd871..c4eb3dc 100644 --- a/dist/module-debug/encoder.js +++ b/dist/module-debug/encoder.js @@ -3,74 +3,62 @@ import { create_object, merge_option } from "./common.js"; import normalize_polyfill from "./charset/polyfill.js"; import { EncoderOptions } from "./type.js"; -/* - -Custom Encoder ----------------- - -// Split a passed string into an Array of words: -function englishEncoder(string){ - return string.toLowerCase().split(/[^a-z]+/) -} - -// For CJK split a passed string into an Array of chars: -function chineseEncoder(string){ - return string.replace(/\s+/, "").split("") -} - -// Alternatively do not split the input: -function fixedEncoder(string){ - return [string] -} - -Built-in Encoder ----------------------------- -The main workflow follows an increasing strategy, -starting from a simple .toLowerCase() to full RegExp -Pipeline: - 1. apply this.normalize (charset normalization) - applied on the whole input string e.g. lowercase, - everything you put later into (filter, matcher, stemmer, mapper, etc.) - has to be normalized by definition, because it won't apply to them automatically - 2. apply this.prepare (custom function, string in - string out) - 3 split numerics into triplets - 4. split input into terms (by one of them: split/include/exclude) - 5. pre-encoded term deduplication - 6. apply this.filter (stop-words) - 7. apply this.stemmer (replace term endings) - 8. apply this.mapper (replace chars) - 9. apply this.dedupe (letter deduplication) - 10. apply this.matcher (replace terms) - 11. apply this.replacer (custom regex) - 12. post-encoded term deduplication - 13. apply this.finalize (custom function, array in - array out) +/* + +Custom Encoder +---------------- + +function englishEncoder(string){ + return string.toLowerCase().split(/[^a-z]+/) +} + +function chineseEncoder(string){ + return string.replace(/\s+/, "").split("") +} + +function fixedEncoder(string){ + return [string] +} + +Built-in Encoder +---------------------------- +The main workflow follows an increasing strategy, +starting from a simple .toLowerCase() to full RegExp +Pipeline: + 1. apply this.normalize (charset normalization) + applied on the whole input string e.g. lowercase, + everything you put later into (filter, matcher, stemmer, mapper, etc.) + has to be normalized by definition, because it won't apply to them automatically + 2. apply this.prepare (custom function, string in - string out) + 3 split numerics into triplets + 4. split input into terms (by one of them: split/include/exclude) + 5. pre-encoded term deduplication + 6. apply this.filter (stop-words) + 7. apply this.stemmer (replace term endings) + 8. apply this.mapper (replace chars) + 9. apply this.dedupe (letter deduplication) + 10. apply this.matcher (replace terms) + 11. apply this.replacer (custom regex) + 12. post-encoded term deduplication + 13. apply this.finalize (custom function, array in - array out) */ const whitespace = /[^\p{L}\p{N}]+/u, numeric_split_length = /(\d{3})/g, numeric_split_prev_char = /(\D)(\d{3})/g, numeric_split_next_char = /(\d{3})(\D)/g, - normalize = /*"".normalize &&*//[\u0300-\u036f]/g; // /[\p{Z}\p{S}\p{P}\p{C}]+/u; -//const numeric_split = /(\d{3})/g; + normalize = /[\u0300-\u036f]/g; -//.replace(/(\d{3})/g, "$1 ") -//.replace(/([^\d])([\d])/g, "$1 $2") -//.replace(/([\d])([^\d])/g, "$1 $2") -// '´`’ʼ., -//const normalize_mapper = SUPPORT_CHARSET && !normalize && normalize_polyfill; - -/** - * @param {EncoderOptions=} options - * @constructor +/** + * @param {EncoderOptions=} options + * @constructor */ export default function Encoder(options = {}) { if (!this || this.constructor !== Encoder) { - // let args = Array.prototype.slice.call(arguments); - // args.unshift(Encoder); - // return new (Encoder.bind.apply(Encoder, args)); + return new Encoder(...arguments); } @@ -83,27 +71,16 @@ export default function Encoder(options = {}) { } } -/** - * @param {!EncoderOptions} options +/** + * @param {!EncoderOptions} options */ Encoder.prototype.assign = function (options) { - /** - * pre-processing string input - * @type {Function|boolean} + /** + * pre-processing string input + * @type {Function|boolean} */ - this.normalize = /** @type {Function|boolean} */merge_option(options.normalize, /* tag? */ /* stringify */ /* stringify */ /* single param */ /* skip update: */ /* append: */ /* skip update: */ /* skip_update: */ /* skip deletion */!0 /*await rows.hasNext()*/ - /*await rows.hasNext()*/ /*await rows.hasNext()*/, this.normalize); - - // { - // letter: true, - // number: true, - // whitespace: true, - // symbol: true, - // punctuation: true, - // control: true, - // char: "" - // } + this.normalize = /** @type {Function|boolean} */merge_option(options.normalize, !0, this.normalize); let include = options.include, tmp = include || options.exclude || options.split, @@ -114,7 +91,7 @@ Encoder.prototype.assign = function (options) { if ("object" == typeof tmp && tmp.constructor !== RegExp) { let regex = ""; numeric = !include; - // split on whitespace by default + include || (regex += "\\p{Z}"); if (tmp.letter) { regex += "\\p{L}"; @@ -137,57 +114,50 @@ Encoder.prototype.assign = function (options) { } try { - // https://github.com/nextapps-de/flexsearch/issues/410 - /** - * split string input into terms - * @type {string|RegExp|boolean|null} + + /** + * split string input into terms + * @type {string|RegExp|boolean|null} */ this.split = new RegExp("[" + (include ? "^" : "") + regex + "]+", "u"); } catch (e) { console.error("Your split configuration:", tmp, "is not supported on this platform. It falls back to using simple whitespace splitter instead: /\s+/."); - // fallback to a simple whitespace splitter + + this.split = /\s+/; } } else { this.split = /** @type {string|RegExp|boolean} */tmp; - // determine numeric encoding - numeric = /* suggest */ /* append: */ /* enrich */!1 === tmp || 2 > "a1a".split(tmp).length; + + numeric = !1 === tmp || 2 > "a1a".split(tmp).length; } this.numeric = merge_option(options.numeric, numeric); } else { try { - // https://github.com/nextapps-de/flexsearch/issues/410 + this.split = /** @type {string|RegExp|boolean} */merge_option(this.split, whitespace); } catch (e) { console.warn("This platform does not support unicode regex. It falls back to using simple whitespace splitter instead: /\s+/."); - // fallback to a simple whitespace splitter + + this.split = /\s+/; } this.numeric = merge_option(options.numeric, merge_option(this.numeric, !0)); } - /** - * post-processing terms - * @type {Function|null} + /** + * post-processing terms + * @type {Function|null} */ this.prepare = /** @type {Function|null} */merge_option(options.prepare, null, this.prepare); - /** - * final processing - * @type {Function|null} + /** + * final processing + * @type {Function|null} */ this.finalize = /** @type {Function|null} */merge_option(options.finalize, null, this.finalize); - // assign the normalization fallback to the mapper - // if(SUPPORT_CHARSET && !normalize){ - // this.mapper = new Map( - // /** @type {Array>} */ ( - // normalize_polyfill - // ) - // ); - // } - tmp = options.filter; this.filter = "function" == typeof tmp ? tmp : merge_option(tmp && new Set(tmp), null, this.filter); this.dedupe = merge_option(options.dedupe, !0, this.dedupe); @@ -199,32 +169,21 @@ Encoder.prototype.assign = function (options) { this.maxlength = merge_option(options.maxlength, 1024, this.maxlength); this.rtl = merge_option(options.rtl, !1, this.rtl); - // auto-balanced cache this.cache = tmp = merge_option(options.cache, !0, this.cache); if (tmp) { - this.timer = null;this.cache_size = "number" == typeof tmp ? tmp : 2e5; + this.timer = null; + this.cache_size = "number" == typeof tmp ? tmp : 2e5; this.cache_enc = new Map(); this.cache_term = new Map(); this.cache_enc_length = 128; this.cache_term_length = 128; } - // regex temporary state this.matcher_str = ""; this.matcher_test = null; this.stemmer_str = ""; this.stemmer_test = null; - // prebuilt - // if(this.filter && this.split){ - // for(const key of this.filter){ - // const tmp = key.replace(this.split, ""); - // if(key !== tmp){ - // this.filter.delete(key); - // this.filter.add(tmp); - // } - // } - // } if (this.matcher) { for (const key of this.matcher.keys()) { this.matcher_str += (this.matcher_str ? "|" : "") + key; @@ -236,15 +195,6 @@ Encoder.prototype.assign = function (options) { } } - // if(SUPPORT_COMPRESSION){ - // this.compression = merge_option(options.compress || options.compression, 0, this.compression); - // if(this.compression && !table){ - // table = new Array(radix); - // for(let i = 0; i < radix; i++) table[i] = i + 33; - // table = String.fromCharCode.apply(null, table); - // } - // } - return this; }; @@ -259,8 +209,8 @@ Encoder.prototype.addStemmer = function (match, replace) { Encoder.prototype.addFilter = function (term) { if ("function" == typeof term) { - // does not support merge yet - this.filter = term; //merge_option(term, term, this.filter); + + this.filter = term; } else { this.filter || (this.filter = new Set()); this.filter.add(term); @@ -269,19 +219,19 @@ Encoder.prototype.addFilter = function (term) { return this; }; -/** - * Replace a single char - * @param {string} char_match - * @param {string} char_replace - * @return {Encoder} - * @suppress {invalidCasts} +/** + * Replace a single char + * @param {string} char_match + * @param {string} char_replace + * @return {Encoder} + * @suppress {invalidCasts} */ Encoder.prototype.addMapper = function (char_match, char_replace) { - // regex: + if ("object" == typeof char_match) { return this.addReplacer( /** @type {RegExp} */char_match, char_replace); } - // not a char: + if (1 < char_match.length) { return this.addMatcher(char_match, char_replace); } @@ -291,20 +241,19 @@ Encoder.prototype.addMapper = function (char_match, char_replace) { return this; }; -/** - * Replace a string - * @param {string} match - * @param {string} replace - * @return {Encoder} - * @suppress {invalidCasts} +/** + * Replace a string + * @param {string} match + * @param {string} replace + * @return {Encoder} + * @suppress {invalidCasts} */ Encoder.prototype.addMatcher = function (match, replace) { - // regex: + if ("object" == typeof match) { return this.addReplacer( /** @type {RegExp} */match, replace); } - // a single char: - // only downgrade when dedupe is on or mapper already was filled + if (2 > match.length && (this.dedupe || this.mapper)) { return this.addMapper(match, replace); } @@ -316,11 +265,11 @@ Encoder.prototype.addMatcher = function (match, replace) { return this; }; -/** - * @param {RegExp} regex - * @param {string} replace - * @return {Encoder} - * @suppress {invalidCasts} +/** + * @param {RegExp} regex + * @param {string} replace + * @return {Encoder} + * @suppress {invalidCasts} */ Encoder.prototype.addReplacer = function (regex, replace) { if ("string" == typeof regex) { @@ -332,10 +281,10 @@ Encoder.prototype.addReplacer = function (regex, replace) { return this; }; -/** - * @param {!string} str - * @param {boolean=} dedupe_terms Note: term deduplication will break the context chain - * @return {!Array} +/** + * @param {!string} str + * @param {boolean=} dedupe_terms Note: term deduplication will break the context chain + * @return {!Array} */ Encoder.prototype.encode = function (str, dedupe_terms) { @@ -349,7 +298,6 @@ Encoder.prototype.encode = function (str, dedupe_terms) { } } - // apply charset normalization if (this.normalize) { if ("function" == typeof this.normalize) { str = this.normalize(str); @@ -360,37 +308,21 @@ Encoder.prototype.encode = function (str, dedupe_terms) { } } - // apply custom encoder (can replace split) if (this.prepare) { str = this.prepare(str); } - // split numbers into triplets if (this.numeric && 3 < str.length) { str = str.replace(numeric_split_prev_char, "$1 $2").replace(numeric_split_next_char, "$1 $2").replace(numeric_split_length, "$1 "); } - // if(this.matcher && (str.length > 1)){ - // this.matcher_test || ( - // this.matcher_test = new RegExp("(" + this.matcher_str + ")", "g") - // ); - // str = str.replace(this.matcher_test, match => this.matcher.get(match)); - // } - - // if(this.stemmer){ - // this.stemmer_test || ( - // this.stemmer_test = new RegExp("(?!\\b)(" + this.stemmer_str + ")(\\b|_)", "g") - // ); - // str = str.replace(this.stemmer_test, match => this.stemmer.get(match)); - // } - const skip = !(this.dedupe || this.mapper || this.filter || this.matcher || this.stemmer || this.replacer); let final = [], dupes = create_object(), last_term, last_term_enc, words = this.split || "" === this.split ? str.split( /** @type {string|RegExp} */this.split) : [str]; - // str; + for (let i = 0, word, base; i < words.length; i++) { @@ -435,41 +367,18 @@ Encoder.prototype.encode = function (str, dedupe_terms) { } } - // from here minlength should not apply again - // when the input string is further shrinking - - // it needs to apply stemmer before bigger transformations - // it needs to apply stemmer after filter (user -> us -> filter out) if (this.stemmer) { - // for(const item of this.stemmer){ - // const key = item[0]; - // const value = item[1]; - // if(word.length > key.length && word.endsWith(key)){ - // word = word.substring(0, word.length - key.length) + value; - // break; - // } - // // const position = word.length - key.length; - // // if(position > 0 && word.substring(position) === key){ - // // word = word.substring(0, position) + value; - // // break; - // // } - // } - // todo compare advantages when filter/stemmer are also encoded this.stemmer_test || (this.stemmer_test = new RegExp("(?!^)(" + this.stemmer_str + ")$")); let old; - // loop stemmer as long as anything has matched - // just terms with length > 2 should need a stemmer (its -> it) - // the minlength also prevents stemmer looping to cut off everything while (old !== word && 2 < word.length) { old = word; word = word.replace(this.stemmer_test, match => this.stemmer.get(match)); } } - // apply mapper and collapsing if (word && (this.mapper || this.dedupe && 1 < word.length)) { let final = ""; for (let i = 0, prev = "", char, tmp; i < word.length; i++) { @@ -482,24 +391,17 @@ Encoder.prototype.encode = function (str, dedupe_terms) { word = final; } - // apply matcher if (this.matcher && 1 < word.length) { this.matcher_test || (this.matcher_test = new RegExp("(" + this.matcher_str + ")", "g")); word = word.replace(this.matcher_test, match => this.matcher.get(match)); } - // apply custom regex if (word && this.replacer) { for (let i = 0; word && i < this.replacer.length; i += 2) { word = word.replace(this.replacer[i], this.replacer[i + 1]); } } - // slower variants for removing same chars in a row: - //word = word.replace(/([^0-9])\1+/g, "$1"); - //word = word.replace(/(.)\1+/g, "$1"); - //word = word.replace(/(?<=(.))\1+/g, ""); - if (this.cache && base.length <= this.cache_term_length) { this.cache_term.set(base, word); if (this.cache_term.size > this.cache_size) { @@ -545,41 +447,8 @@ export function fallback_encoder(str) { return str.normalize("NFKD").replace(normalize, "").toLowerCase().trim().split(/\s+/); } -// Encoder.prototype.compress = function(str) { -// -// //return str; -// //if(!str) return str; -// -// if(SUPPORT_CACHE && this.cache && str.length <= this.cache_term_length){ -// if(this.timer){ -// if(this.cache_cmp.has(str)){ -// return this.cache_cmp.get(str); -// } -// } -// else{ -// this.timer = setTimeout(clear, 0, this); -// } -// } -// -// const result = typeof this.compression === "function" -// ? this.compression(str) -// : hash(str); //window.hash(str); -// -// if(SUPPORT_CACHE && this.cache && str.length <= this.cache_term_length){ -// this.cache_cmp.set(str, result); -// this.cache_cmp.size > this.cache_size && -// this.cache_cmp.clear(); -// } -// -// return result; -// }; - -// function hash(str){ -// return str; -// } - -/** - * @param {Encoder} self +/** + * @param {Encoder} self */ function clear(self) { self.timer = null; diff --git a/dist/module-debug/index.js b/dist/module-debug/index.js index 01e9286..b126295 100644 --- a/dist/module-debug/index.js +++ b/dist/module-debug/index.js @@ -14,7 +14,7 @@ import { KeystoreMap, KeystoreSet } from "./keystore.js"; import { is_array, is_string } from "./common.js"; import { exportIndex, importIndex, serialize } from "./serialize.js"; import { remove_index } from "./index/remove.js"; -//import default_encoder from "./charset/latin/default.js"; + import apply_preset from "./preset.js"; import apply_async from "./async.js"; import tick from "./profiler.js"; @@ -39,13 +39,13 @@ export default function Index(options, _register) { /** @type {*} */ let tmp = options.context; /** @type ContextOptions */ - const context = /** @type ContextOptions */ /* tag? */ /* stringify */ /* stringify */ /* single param */ /* skip update: */ /* append: */ /* skip update: */ /* skip_update: */ /* skip deletion */!0 /*await rows.hasNext()*/ /*await rows.hasNext()*/ /*await rows.hasNext()*/ === tmp ? { depth: 1 } : tmp || {}, - encoder = is_string(options.encoder) ? Charset[options.encoder] : options.encode || options.encoder || {} /*default_encoder*/; + const context = /** @type ContextOptions */!0 === tmp ? { depth: 1 } : tmp || {}, + encoder = is_string(options.encoder) ? Charset[options.encoder] : options.encode || options.encoder || {}; /** @type Encoder */ this.encoder = encoder.encode ? encoder : "object" == typeof encoder ? new Encoder( /** @type {EncoderOptions} */encoder) : { encode: encoder }; - this.compress = options.compress || options.compression || /* suggest */ /* append: */ /* enrich */!1; + this.compress = options.compress || options.compression || !1; this.resolution = options.resolution || 9; @@ -161,32 +161,6 @@ Index.prototype.update = function (id, content) { return res && res.then ? res.then(() => self.add(id, content)) : this.add(id, content); }; -// /** -// * @param map -// * @return {number} -// */ -// -// function cleanup_index(map){ -// -// let count = 0; -// -// if(is_array(map)){ -// for(let i = 0, arr; i < map.length; i++){ -// (arr = map[i]) && -// (count += arr.length); -// } -// } -// else for(const item of map.entries()){ -// const key = item[0]; -// const value = item[1]; -// const tmp = cleanup_index(value); -// tmp ? count += tmp -// : map.delete(key); -// } -// -// return count; -// } - Index.prototype.cleanup = function () { if (!this.fastupdate) { @@ -195,10 +169,8 @@ Index.prototype.cleanup = function () { } remove_index(this.map); - //cleanup_index(this.map); - this.depth && - //cleanup_index(this.ctx); - remove_index(this.ctx); + + this.depth && remove_index(this.ctx); return this; }; diff --git a/dist/module-debug/index/add.js b/dist/module-debug/index/add.js index 03a7634..cc6cdc6 100644 --- a/dist/module-debug/index/add.js +++ b/dist/module-debug/index/add.js @@ -4,11 +4,6 @@ import Index, { autoCommit } from "../index.js"; import default_compress from "../compress.js"; import { KeystoreArray } from "../keystore.js"; -// TODO: -// string + number as text -// boolean, null, undefined as ? - - /** * @param {!number|string} id * @param {!string} content @@ -20,9 +15,6 @@ Index.prototype.add = function (id, content, _append, _skip_update) { if (content && (id || 0 === id)) { - // todo check skip_update - //_skip_update = false; - if (!_skip_update && !_append) { if (this.reg.has(id)) { return this.update(id, content); @@ -30,15 +22,11 @@ Index.prototype.add = function (id, content, _append, _skip_update) { } const depth = this.depth; - // do not force a string as input - // https://github.com/nextapps-de/flexsearch/issues/432 + content = this.encoder.encode(content, !depth); const word_length = content.length; if (word_length) { - - // check context dupes to skip all contextual redundancy along a document - const dupes_ctx = create_object(), dupes = create_object(), resolution = this.resolution; @@ -49,9 +37,6 @@ Index.prototype.add = function (id, content, _append, _skip_update) { term_length = term.length; - // todo check context search - // this check also wasn't applied on search, so it's useless here - // skip dupes will break the context chain if (term_length && (depth || !dupes[term])) { let score = this.score ? this.score(content, term, i, null, 0) : get_score(resolution, word_length, i), token = ""; @@ -71,10 +56,10 @@ Index.prototype.add = function (id, content, _append, _skip_update) { } break; } - // fallthrough to next case when term length < 3 + case "bidirectional": case "reverse": - // skip last round (this token exist already in "forward") + if (1 < term_length) { for (let x = term_length - 1; 0 < x; x--) { token = term[this.rtl ? term_length - 1 - x : x] + token; @@ -84,7 +69,6 @@ Index.prototype.add = function (id, content, _append, _skip_update) { token = ""; } - // fallthrough to next case to apply forward also case "forward": if (1 < term_length) { for (let x = 0; x < term_length; x++) { @@ -94,16 +78,12 @@ Index.prototype.add = function (id, content, _append, _skip_update) { break; } - // fallthrough to next case when token has a length of 1 default: - // "strict": this.push_index(dupes, term, score, id, _append); - // context is just supported by tokenizer "strict" + if (depth) { if (1 < word_length && i < word_length - 1) { - - // check inner dupes to skip repeating words in the current context const dupes_inner = create_object(), resolution = this.resolution_ctx, keyword = term, @@ -138,8 +118,7 @@ Index.prototype.add = function (id, content, _append, _skip_update) { } if (this.db) { - // when the term has no valid content (e.g. empty), - // then it was not added to the ID registry for removal + content || this.commit_task.push({ del: id }); this.commit_auto && autoCommit(this); } @@ -186,28 +165,25 @@ Index.prototype.push_index = function (dupes, term, score, id, append, keyword) tmp = arr.get(term); tmp ? arr = tmp : arr.set(term, arr = tmp = []); - // the ID array will be upgraded dynamically + arr = arr[score] || (arr[score] = []); if (!append || !arr.includes(id)) { - - // auto-upgrade to keystore array if max size exceeded - if (2147483647 === arr.length /*|| !(arr instanceof KeystoreArray)*/) { - const keystore = new KeystoreArray(arr); - if (this.fastupdate) { - for (let value of this.reg.values()) { - if (value.includes(arr)) { - value[value.indexOf(arr)] = keystore; - } + if (2147483647 === arr.length) { + const keystore = new KeystoreArray(arr); + if (this.fastupdate) { + for (let value of this.reg.values()) { + if (value.includes(arr)) { + value[value.indexOf(arr)] = keystore; } } - tmp[score] = arr = keystore; } + tmp[score] = arr = keystore; + } arr.push(id); - // add a reference to the register for fast updates if (this.fastupdate) { const tmp = this.reg.get(id); tmp ? tmp.push(arr) : this.reg.set(id, [arr]); @@ -227,23 +203,5 @@ Index.prototype.push_index = function (dupes, term, score, id, append, keyword) function get_score(resolution, length, i, term_length, x) { - // console.log("resolution", resolution); - // console.log("length", length); - // console.log("term_length", term_length); - // console.log("i", i); - // console.log("x", x); - // console.log((resolution - 1) / (length + (term_length || 0)) * (i + (x || 0)) + 1); - - // the first resolution slot is reserved for the best match, - // when a query matches the first word(s). - - // also to stretch score to the whole range of resolution, the - // calculation is shift by one and cut the floating point. - // this needs the resolution "1" to be handled additionally. - - // do not stretch the resolution more than the term length will - // improve performance and memory, also it improves scoring in - // most cases between a short document and a long document - return i && 1 < resolution ? length + (term_length || 0) <= resolution ? i + (x || 0) : 0 | (resolution - 1) / (length + (term_length || 0)) * (i + (x || 0)) + 1 : 0; } \ No newline at end of file diff --git a/dist/module-debug/index/remove.js b/dist/module-debug/index/remove.js index 2675be2..63cf421 100644 --- a/dist/module-debug/index/remove.js +++ b/dist/module-debug/index/remove.js @@ -14,13 +14,9 @@ Index.prototype.remove = function (id, _skip_deletion) { if (this.fastupdate) { - // fast updates did not fully clean up the key entries - for (let i = 0, tmp; i < refs.length; i++) { if (tmp = refs[i]) { - // todo check - //if(tmp.length < 1) throw new Error("invalid length"); - //if(tmp.indexOf(id) < 0) throw new Error("invalid id"); + if (2 > tmp.length) { tmp.pop(); } else { @@ -29,51 +25,10 @@ Index.prototype.remove = function (id, _skip_deletion) { } } } - - // todo variation which cleans up, requires to push [ctx, key] instead of arr to the index.reg - // for(let i = 0, arr, term, keyword; i < refs.length; i++){ - // arr = refs[i]; - // if(typeof arr === "string"){ - // arr = this.map.get(term = arr); - // } - // else{ - // arr = this.ctx.get(keyword = arr[0]); - // arr && (arr = arr.get(arr[1])); - // } - // let counter = 0, found; - // if(arr && arr.length){ - // for(let j = 0, tmp; j < arr.length; j++){ - // if((tmp = arr[j])){ - // if(!found && tmp.length){ - // const index = tmp.indexOf(id); - // if(index >= 0){ - // tmp.splice(index, 1); - // // the index [ctx, key]:[res, id] is unique - // found = 1; - // } - // } - // if(tmp.length){ - // counter++; - // if(found){ - // break; - // } - // } - // else{ - // delete arr[j]; - // } - // } - // } - // } - // if(!counter){ - // keyword - // ? this.ctx.delete(keyword) - // : this.map.delete(term); - // } - // } } else { - remove_index(this.map, id /*, this.resolution*/); - this.depth && remove_index(this.ctx, id /*, this.resolution_ctx*/); + remove_index(this.map, id); + this.depth && remove_index(this.ctx, id); } _skip_deletion || this.reg.delete(id); @@ -82,10 +37,8 @@ Index.prototype.remove = function (id, _skip_deletion) { if (this.db) { this.commit_task.push({ del: id }); this.commit_auto && autoCommit(this); - //return this.db.remove(id); } - // the cache could be used outside the InMemory store if (this.cache) { this.cache.remove(id); } @@ -101,9 +54,6 @@ Index.prototype.remove = function (id, _skip_deletion) { */ export function remove_index(map, id) { - - // a check counter of filled resolution slots - // to prevent removing the field let count = 0; @@ -111,7 +61,7 @@ export function remove_index(map, id) { for (let x = 0, arr, index; x < map.length; x++) { if ((arr = map[x]) && arr.length) { if ("undefined" == typeof id) { - //count += arr.length; + count++; } else { index = arr.indexOf(id); @@ -120,10 +70,10 @@ export function remove_index(map, id) { arr.splice(index, 1); count++; } else { - // remove resolution slot + delete map[x]; } - // the index key:[res, id] is unique + break; } else { count++; diff --git a/dist/module-debug/index/search.js b/dist/module-debug/index/search.js index d9c8921..5fb6c4e 100644 --- a/dist/module-debug/index/search.js +++ b/dist/module-debug/index/search.js @@ -30,9 +30,9 @@ Index.prototype.search = function (query, limit, options) { } if (options && options.cache) { - options.cache = /* suggest */ /* append: */ /* enrich */!1; + options.cache = !1; const res = this.searchCache(query, limit, options); - options.cache = /* tag? */ /* stringify */ /* stringify */ /* single param */ /* skip update: */ /* append: */ /* skip update: */ /* skip_update: */ /* skip deletion */!0 /*await rows.hasNext()*/ /*await rows.hasNext()*/ /*await rows.hasNext()*/; + options.cache = !0; return res; } @@ -46,10 +46,7 @@ Index.prototype.search = function (query, limit, options) { tag, boost, resolution, - - // enrich is internally used just - // for the persistent indexes - enrich; + enrich; if (options) { @@ -70,146 +67,39 @@ Index.prototype.search = function (query, limit, options) { } context = this.depth && !1 !== context; - // do not force a string as input - // https://github.com/nextapps-de/flexsearch/issues/432 + /** @type {Array} */ let query_terms = this.encoder.encode(query, !context); length = query_terms.length; limit = /** @type {!number} */limit || (resolve ? 100 : 0); - // fast path single term if (1 === length) { - return single_term_query.call(this, query_terms[0], // term - "", // ctx - limit, offset, resolve, enrich, tag); + return single_term_query.call(this, query_terms[0], "", limit, offset, resolve, enrich, tag); } - // fast path single context if (2 === length && context && !suggest) { - return single_term_query.call(this, query_terms[1], // term - query_terms[0], // ctx - limit, offset, resolve, enrich, tag); + return single_term_query.call(this, query_terms[1], query_terms[0], limit, offset, resolve, enrich, tag); } - // let maxlength = 0; - // let minlength = 0; - // - // if(length > 1){ - // - // // term deduplication will break the context chain - // // todo add context to dupe check - // const dupes = create_object(); - // const query_new = []; - // - // // if(context){ - // // keyword = query_terms[0]; - // // dupes[keyword] = 1; - // // query_new.push(keyword); - // // maxlength = minlength = keyword.length; - // // i = 1; - // // } - // - // for(let i = 0, term; i < length; i++){ - // - // term = query_terms[i]; - // - // if(term && !dupes[term]){ - // - // // todo add keyword check - // // this fast path can't apply to persistent indexes - // if(!suggest && !(SUPPORT_PERSISTENT && this.db) && !this.get_array(term/*, keyword*/)){ - // - // // fast path "not found" - // return !SUPPORT_RESOLVER || resolve - // ? result - // : new Resolver(result); - // } - // else{ - // - // query_new.push(term); - // dupes[term] = 1; - // } - // - // const term_length = term.length; - // maxlength = Math.max(maxlength, term_length); - // minlength = minlength ? Math.min(minlength, term_length) : term_length; - // } - // // else if(term && (!this.depth || context === false)){ - // // query_new.push(term); - // // } - // } - // - // query_terms = query_new; - // length = query_terms.length; - // } - // - // // the term length could be changed after deduplication - // - // if(!length){ - // return !SUPPORT_RESOLVER || resolve - // ? result - // : new Resolver(result); - // } - // - // // fast path single term - // if(length === 1){ - // return single_term_query.call( - // this, - // query_terms[0], // term - // "", // ctx - // limit, - // offset, - // resolve, - // enrich, - // tag - // ); - // } - // - // // fast path single context - // if(length === 2 && context && !suggest){ - // return single_term_query.call( - // this, - // query_terms[0], // term - // query_terms[1], // ctx - // limit, - // offset, - // resolve, - // enrich, - // tag - // ); - // } - let dupes = create_object(), index = 0, keyword; - //if(length > 1){ if (context) { - // start with context right away + keyword = query_terms[0]; index = 1; } - // todo - // else if(maxlength > 9 && (maxlength / minlength) > 3){ - // // sorting terms will break the context chain - // // bigger terms has less occurrence - // // this might also reduce the intersection task - // // todo check intersection order - // query_terms.sort(sort_by_length_down); - // } - //} if (!resolution && 0 !== resolution) { resolution = keyword ? this.resolution_ctx : this.resolution; } - // from this point there are just multi-term queries - if (this.db) { if (this.db.search) { - // when the configuration is not supported it returns false + const result = this.db.search(this, query_terms, limit, offset, suggest, resolve, enrich, tag); if (!1 !== result) return result; } @@ -234,16 +124,12 @@ Index.prototype.search = function (query, limit, options) { if (keyword) { - // the context is a moving window where the keyword is going forward like a cursor - // 1. when suggestion enabled just forward keyword if term was found - // 2. as long as the result is empty forward the pointer also if (!suggest || !arr || !result.length) { keyword = term; } } } - // fallback to non-contextual search when no result was found if (suggest && keyword && index == length - 1) { if (!result.length) { resolution = self.resolution; @@ -263,7 +149,6 @@ Index.prototype.search = function (query, limit, options) { term = query_terms[index]; - // todo should the dupe check applied on [keyword:term]? if (term && !dupes[term]) { dupes[term] = 1; @@ -276,16 +161,13 @@ Index.prototype.search = function (query, limit, options) { } if (keyword) { - // the context is a moving window where the keyword is going forward like a cursor - // 1. when suggestion enabled just forward keyword if term was found - // 2. as long as the result is empty forward the pointer also + if (!suggest || !arr || !result.length) { keyword = term; } } } - // fallback to non-contextual search when no result was found if (suggest && keyword && index == length - 1) { if (!result.length) { resolution = this.resolution; @@ -375,14 +257,12 @@ function add_result(arr, result, suggest, resolution) { if (arr && arr.length) { - // short when resolution does not exceed: if (arr.length <= resolution) { result.push(arr); - // return nothing will continue the query + return; } - // apply reduced resolution for queries for (let x = 0, tmp; x < resolution; x++) { if (tmp = arr[x]) { word_arr[x] = tmp; @@ -391,13 +271,11 @@ function add_result(arr, result, suggest, resolution) { if (word_arr.length) { result.push(word_arr); - // return nothing will continue the query + return; } } - // 1. return an empty array will stop the loop - // 2. return a false value to prevent stop when using suggestions if (!suggest) return word_arr; } @@ -437,9 +315,7 @@ Index.prototype.get_array = function (term, keyword, limit, offset, resolve, enr } if (keyword) { - // the frequency of the starting letter is slightly less - // on the last half of the alphabet (m-z) in almost every latin language, - // so we sort downwards (https://en.wikipedia.org/wiki/Letter_frequency) + arr = this.ctx.get(keyword); arr = arr && arr.get(term); } else { diff --git a/dist/module-debug/intersect.js b/dist/module-debug/intersect.js index c77a41e..0b74fb3 100644 --- a/dist/module-debug/intersect.js +++ b/dist/module-debug/intersect.js @@ -34,9 +34,6 @@ export function intersect(arrays, resolution, limit, offset, suggest, boost, res count; - // alternatively the results could be sorted by length up - //arrays.sort(sort_by_length_up); - check = create_object(); for (let y = 0, ids, id, res_arr, tmp; y < resolution; y++) { @@ -51,35 +48,23 @@ export function intersect(arrays, resolution, limit, offset, suggest, boost, res id = ids[z]; - // todo the persistent implementation will count term matches - // and also aggregate the score (group by id) - // min(score): suggestions off (already covered) - // sum(score): suggestions on (actually not covered) - if (count = check[id]) { check[id]++; - // tmp.count++; - // tmp.sum += y; } else { count = 0; check[id] = 1; - // check[id] = { - // count: 1, - // sum: y - // }; } tmp = result[count] || (result[count] = []); if (!resolve) { - // boost everything after first result + let score = y + (x || !suggest ? 0 : boost || 0); tmp = tmp[score] || (tmp[score] = []); } tmp.push(id); - // fast path early result when limit was set if (resolve) { if (limit && count === length - 1) { if (tmp.length - offset === limit) { @@ -87,16 +72,11 @@ export function intersect(arrays, resolution, limit, offset, suggest, boost, res } } } - // todo break early on suggest: true } } } } - // result.sort(function(a, b){ - // return check[a] - check[b]; - // }); - const result_len = result.length; if (result_len) { @@ -115,8 +95,7 @@ export function intersect(arrays, resolution, limit, offset, suggest, boost, res result = result.slice(offset, limit + offset); } } else { - // todo this is doing the same as Resolver.resolve({limit}) ? - // todo check limit + offset when resolve = false + const final = []; for (let i = 0, arr; i < result.length; i++) { arr = result[i]; @@ -136,14 +115,7 @@ export function intersect(arrays, resolution, limit, offset, suggest, boost, res } } result = final; - // result = final.length > 1 - // ? concat(final) - // : final[0]; } - - // return /** @type {SearchResults|IntermediateSearchResults} */ ( - // result - // ); } } else { @@ -174,8 +146,6 @@ export function union(arrays, limit, offset, resolve, boost) { arr_len = arrays.length, ids_len; - //let maxres = get_max_len(arrays); - if (!resolve) { for (let i = arr_len - 1, res, count = 0; 0 <= i; i--) { @@ -196,11 +166,6 @@ export function union(arrays, limit, offset, resolve, boost) { if (offset) { offset--; } else { - // adjust score to reduce resolution of suggestions - // todo: instead of applying the resolve task directly it could - // be added to the chain and resolved later, that will keep - // the original score but also can't resolve early when - // nothing was found let score = 0 | (k + (i < arr_len - 1 ? boost || 0 : 0)) / (i + 1), arr = result[score] || (result[score] = []); @@ -282,222 +247,6 @@ export function intersect_union(arrays, mandatory, resolve) { return result; } -// export function intersect_union(mandatory, arrays, resolution) { -// -// const check = create_object(); -// const union = create_object(); -// const result = []; -// -// for(let x = 0; x < mandatory.length; x++){ -// check[mandatory[x]] = 1; -// } -// -// -// for(let y = 0, ids, id; y < resolution; y++){ -// for(let x = 0; x < arrays.length; x++){ -// -// ids = arrays[x]; -// -// if(y < ids.length){ -// -// id = ids[y]; -// -// if(check[id]){ -// -// if(!union[id]){ -// -// union[id] = 1; -// result.push(id); -// } -// } -// } -// } -// } -// -// return result; -// } - -// -// /** -// * Implementation based on Object[key] provides better suggestions -// * capabilities and has less performance scaling issues on large indexes. -// * -// * @param arrays -// * @param limit -// * @param offset -// * @param {boolean|Array=} suggest -// * @param {boolean=} resolve -// * @returns {Array} -// */ -// -// export function intersect(arrays, limit, offset, suggest, resolve) { -// -// const length = arrays.length; -// -// // todo remove -// // if(length < 2){ -// // throw new Error("Not optimized intersect"); -// // } -// -// let result = []; -// let size = 0; -// let check; -// let check_suggest; -// let check_new; -// let res_arr; -// -// if(suggest){ -// suggest = []; -// } -// -// // 1. a reversed order prioritize the order of words from a query -// // because it ends with the first term. -// // 2. process terms in reversed order often has advantage for -// // the fast path "end reached". -// -// // alternatively the results could be sorted by length up -// //arrays.sort(sort_by_length_up); -// -// // todo the outer loop should be the res array instead of term array, -// // this isn't just simple because the intersection calculation needs to reflect this -// //const maxlen = get_max_len(arrays); -// -// for(let x = length - 1, found; x >= 0; x--){ -// //for(let x = 0, found; x < length; x++){ -// -// res_arr = arrays[x]; -// check_new = create_object(); -// found = !check; -// -// // process relevance in forward order (direction is -// // important for adding IDs during the last round) -// -// for(let y = 0, ids; y < res_arr.length; y++){ -// -// ids = res_arr[y]; -// if(!ids || !ids.length) continue; -// -// for(let z = 0, id; z < ids.length; z++){ -// -// id = ids[z]; -// -// // check exists starting from the 2nd slot -// if(check){ -// if(check[id]){ -// -// // check if in last round -// if(!x){ -// //if(x === length - 1){ -// -// if(offset){ -// offset--; -// } -// else{ -// -// result[size++] = id; -// -// if(size === limit){ -// // fast path "end reached" -// return result /*resolve === false -// ? { result, suggest } -// :*/ -// } -// } -// } -// -// if(x || suggest){ -// //if((x < length - 1) || suggest){ -// check_new[id] = 1; -// } -// -// found = true; -// } -// -// if(suggest){ -// -// if(!check_suggest[id]){ -// check_suggest[id] = 1; -// const arr = suggest[y] || (suggest[y] = []); -// arr.push(id); -// } -// -// // OLD: -// // -// // check_idx = (check_suggest[id] || 0) + 1; -// // check_suggest[id] = check_idx; -// // -// // // do not adding IDs which are already included in the result (saves one loop) -// // // the first intersection match has the check index 2, so shift by -2 -// // -// // if(check_idx < length){ -// // -// // const tmp = suggest[check_idx - 2] || (suggest[check_idx - 2] = []); -// // tmp[tmp.length] = id; -// // } -// } -// } -// else{ -// -// // pre-fill in first round -// check_new[id] = 1; -// } -// } -// } -// -// if(suggest){ -// -// // re-use the first pre-filled check for suggestions -// check || (check_suggest = check_new); -// } -// else if(!found){ -// -// return []; -// } -// -// check = check_new; -// } -// -// // return intermediate result -// // if(resolve === false){ -// // return { result, suggest }; -// // } -// -// if(suggest){ -// -// // needs to iterate in reverse direction -// for(let x = suggest.length - 1, ids, len; x >= 0; x--){ -// -// ids = suggest[x]; -// len = ids.length; -// -// for(let y = 0, id; y < len; y++){ -// -// id = ids[y]; -// -// if(!check[id]){ -// -// if(offset){ -// offset--; -// } -// else{ -// -// result[size++] = id; -// -// if(size === limit){ -// // fast path "end reached" -// return result; -// } -// } -// -// check[id] = 1; -// } -// } -// } -// } -// -// return result; -// } - /** * Implementation based on Array.includes() provides better performance, * but it needs at least one word in the query which is less frequent. @@ -509,185 +258,4 @@ export function intersect_union(arrays, mandatory, resolve) { * @param offset * @param {boolean|Array=} suggest * @returns {Array} - */ - -// export function intersect(arrays, limit, offset, suggest) { -// -// const length = arrays.length; -// let result = []; -// let check; -// -// // determine shortest array and collect results -// // from the sparse relevance arrays -// -// let smallest_size; -// let smallest_arr; -// let smallest_index; -// -// for(let x = 0; x < length; x++){ -// -// const arr = arrays[x]; -// const len = arr.length; -// -// let size = 0; -// -// for(let y = 0, tmp; y < len; y++){ -// -// tmp = arr[y]; -// -// if(tmp){ -// -// size += tmp.length; -// } -// } -// -// if(!smallest_size || (size < smallest_size)){ -// -// smallest_size = size; -// smallest_arr = arr; -// smallest_index = x; -// } -// } -// -// smallest_arr = smallest_arr.length === 1 ? -// -// smallest_arr[0] -// : -// concat(smallest_arr); -// -// if(suggest){ -// -// suggest = [smallest_arr]; -// check = create_object(); -// } -// -// let size = 0; -// let steps = 0; -// -// // process terms in reversed order often results in better performance. -// // the outer loop must be the words array, using the -// // smallest array here disables the "fast fail" optimization. -// -// for(let x = length - 1; x >= 0; x--){ -// -// if(x !== smallest_index){ -// -// steps++; -// -// const word_arr = arrays[x]; -// const word_arr_len = word_arr.length; -// const new_arr = []; -// -// let count = 0; -// -// for(let z = 0, id; z < smallest_arr.length; z++){ -// -// id = smallest_arr[z]; -// -// let found; -// -// // process relevance in forward order (direction is -// // important for adding IDs during the last round) -// -// for(let y = 0; y < word_arr_len; y++){ -// -// const arr = word_arr[y]; -// -// if(arr.length){ -// -// found = arr.includes(id); -// -// if(found){ -// -// // check if in last round -// -// if(steps === length - 1){ -// -// if(offset){ -// -// offset--; -// } -// else{ -// -// result[size++] = id; -// -// if(size === limit){ -// -// // fast path "end reached" -// -// return result; -// } -// } -// -// if(suggest){ -// -// check[id] = 1; -// } -// } -// -// break; -// } -// } -// } -// -// if(found){ -// -// new_arr[count++] = id; -// } -// } -// -// if(suggest){ -// -// suggest[steps] = new_arr; -// } -// else if(!count){ -// -// return []; -// } -// -// smallest_arr = new_arr; -// } -// } -// -// if(suggest){ -// -// // needs to iterate in reverse direction -// -// for(let x = suggest.length - 1, arr, len; x >= 0; x--){ -// -// arr = suggest[x]; -// len = arr && arr.length; -// -// if(len){ -// -// for(let y = 0, id; y < len; y++){ -// -// id = arr[y]; -// -// if(!check[id]){ -// -// check[id] = 1; -// -// if(offset){ -// -// offset--; -// } -// else{ -// -// result[size++] = id; -// -// if(size === limit){ -// -// // fast path "end reached" -// -// return result; -// } -// } -// } -// } -// } -// } -// } -// -// return result; -// } \ No newline at end of file + */ \ No newline at end of file diff --git a/dist/module-debug/keystore.js b/dist/module-debug/keystore.js index 40cbd39..cfd76db 100644 --- a/dist/module-debug/keystore.js +++ b/dist/module-debug/keystore.js @@ -1,64 +1,5 @@ import { create_object } from "./common.js"; -// /** -// * @param bitlength -// * @constructor -// */ -// -// export function KeystoreObj(bitlength = 8){ -// -// if(!this || this.constructor !== KeystoreObj){ -// return new KeystoreObj(bitlength); -// } -// -// this.index = create_object(); -// this.keys = []; -// -// if(bitlength > 32){ -// this.crc = lcg64; -// this.bit = BigInt(bitlength); -// } -// else { -// this.crc = lcg; -// this.bit = bitlength; -// } -// -// return /*this.proxy =*/ new Proxy(this, { -// get(target, key) { -// const address = target.crc(key); -// const obj = target.index[address]; -// return obj && obj[key]; -// }, -// set(target, key, value){ -// const address = target.crc(key); -// let obj = target.index[address]; -// if(!obj){ -// target.index[address] = obj = create_object(); -// target.keys.push(address); -// } -// obj[key] = value; -// return true; -// }, -// delete(target, key){ -// const address = target.crc(key); -// const obj = target.index[address]; -// obj && delete obj[key]; -// return true; -// } -// }); -// } -// -// KeystoreObj.prototype.clear = function(){ -// this.index = create_object(); -// this.keys = []; -// }; - -// KeystoreObj.prototype.destroy = function(){ -// this.index = null; -// this.keys = null; -// this.proxy = null; -// }; - function _slice(self, start, end, splice) { let arr = []; for (let i = 0, index; i < self.index.length; i++) { @@ -96,83 +37,78 @@ export function KeystoreArray(arr) { this.length = arr ? arr.length : 0; const self = this; - return (/*this.proxy =*/new Proxy([], { - get(target, key) { - if ("length" === key) { - return self.length; - } - if ("push" === key) { - return function (value) { - self.index[self.index.length - 1].push(value); - self.length++; - }; - } - if ("pop" === key) { - return function () { - if (self.length) { - self.length--; - return self.index[self.index.length - 1].pop(); - } - }; - } - if ("indexOf" === key) { - return function (key) { - let index = 0; - for (let i = 0, arr, tmp; i < self.index.length; i++) { - arr = self.index[i]; - //if(!arr.includes(key)) continue; - tmp = arr.indexOf(key); - if (0 <= tmp) return index + tmp; - index += arr.length; - } - return -1; - }; - } - if ("includes" === key) { - return function (key) { - for (let i = 0; i < self.index.length; i++) { - if (self.index[i].includes(key)) { - return (/* tag? */ /* stringify */ /* stringify */ /* single param */ /* skip update: */ /* append: */ /* skip update: */ /* skip_update: */ /* skip deletion */ - // splice: - !0 /*await rows.hasNext()*/ /*await rows.hasNext()*/ /*await rows.hasNext()*/ - ); - } - } - return (/* suggest */ /* append: */ /* enrich */!1 - ); - }; - } - if ("slice" === key) { - return function (start, end) { - return _slice(self, start || 0, end || self.length, !1); - }; - } - if ("splice" === key) { - return function (start, end) { - return _slice(self, start || 0, end || self.length, !0); - }; - } - if ("constructor" === key) { - return Array; - } - if ("symbol" == typeof key /*|| isNaN(key)*/) { - // not supported - return; - } - const arr = self.index[0 | key / 2147483648]; - - return arr && arr[key]; - }, - set(target, key, value) { - const index = 0 | key / 2147483648, - arr = self.index[index] || (self.index[index] = []); - - arr[key] = value; - self.length++; - return !0; + return new Proxy([], { + get(target, key) { + if ("length" === key) { + return self.length; } - }) - ); + if ("push" === key) { + return function (value) { + self.index[self.index.length - 1].push(value); + self.length++; + }; + } + if ("pop" === key) { + return function () { + if (self.length) { + self.length--; + return self.index[self.index.length - 1].pop(); + } + }; + } + if ("indexOf" === key) { + return function (key) { + let index = 0; + for (let i = 0, arr, tmp; i < self.index.length; i++) { + arr = self.index[i]; + + tmp = arr.indexOf(key); + if (0 <= tmp) return index + tmp; + index += arr.length; + } + return -1; + }; + } + if ("includes" === key) { + return function (key) { + for (let i = 0; i < self.index.length; i++) { + if (self.index[i].includes(key)) { + return !0; + } + } + return !1; + }; + } + if ("slice" === key) { + return function (start, end) { + return _slice(self, start || 0, end || self.length, !1); + }; + } + if ("splice" === key) { + return function (start, end) { + return _slice(self, start || 0, end || self.length, !0); + }; + } + if ("constructor" === key) { + return Array; + } + if ("symbol" == typeof key) { + + return; + } + const arr = self.index[0 | key / 2147483648]; + + return arr && arr[key]; + }, + set(target, key, value) { + const index = 0 | key / 2147483648, + arr = self.index[index] || (self.index[index] = []); + + arr[key] = value; + self.length++; + return !0; + } + }); } KeystoreArray.prototype.clear = function () { @@ -328,9 +264,7 @@ KeystoreSet.prototype.delete = function (key) { const address = this.crc(key), map_or_set = this.index[address]; - // set && (set.size === 1 - // ? this.index.delete(address) - // : set.delete(key)); + map_or_set && map_or_set.delete(key) && this.size--; }; @@ -340,19 +274,11 @@ KeystoreMap.prototype.clear = KeystoreSet.prototype.clear = function () { this.size = 0; }; -// KeystoreMap.prototype.destroy = -// KeystoreSet.prototype.destroy = function(){ -// this.index = null; -// this.refs = null; -// this.proxy = null; -// }; - /** * @return Iterable */ KeystoreMap.prototype.values = KeystoreSet.prototype.values = function* () { - // alternatively iterate through this.keys[] - //const refs = Object.values(this.index); + for (let i = 0; i < this.refs.length; i++) { for (let value of this.refs[i].values()) { yield value; @@ -364,7 +290,7 @@ KeystoreMap.prototype.values = KeystoreSet.prototype.values = function* () { * @return Iterable */ KeystoreMap.prototype.keys = KeystoreSet.prototype.keys = function* () { - //const values = Object.values(this.index); + for (let i = 0; i < this.refs.length; i++) { for (let key of this.refs[i].keys()) { yield key; @@ -376,7 +302,7 @@ KeystoreMap.prototype.keys = KeystoreSet.prototype.keys = function* () { * @return Iterable */ KeystoreMap.prototype.entries = KeystoreSet.prototype.entries = function* () { - //const values = Object.values(this.index); + for (let i = 0; i < this.refs.length; i++) { for (let entry of this.refs[i].entries()) { yield entry; @@ -400,9 +326,8 @@ function lcg(str) { for (let i = 0; i < str.length; i++) { crc = (crc * bit ^ str.charCodeAt(i)) & range; } - // shift Int32 to UInt32 because negative numbers - // extremely slows down key lookup - return 32 === this.bit ? crc + 2147483648 : crc; // & 0xFFFF; + + return 32 === this.bit ? crc + 2147483648 : crc; } /** @@ -426,5 +351,5 @@ function lcg64(str) { for (let i = 0; i < str.length; i++) { crc = (crc * bit ^ BigInt(str.charCodeAt(i))) & range; } - return crc; // & 0xFFFFFFFFFFFFFFFF; + return crc; } \ No newline at end of file diff --git a/dist/module-debug/lang/de.js b/dist/module-debug/lang/de.js index 6559526..2f74ae0 100644 --- a/dist/module-debug/lang/de.js +++ b/dist/module-debug/lang/de.js @@ -26,14 +26,14 @@ export const stemmer = new Map([["niss", ""], ["isch", ""], ["lich", ""], ["heit */ const map = new Map([["_", " "], ["ä", "ae"], ["ö", "oe"], ["ü", "ue"], ["ß", "ss"], ["&", " und "], ["€", " EUR "]]), options = { - prepare: function (str) { - // normalization - if (/[_äöüß&€]/.test(str)) str = str.replace(/[_äöüß&€]/g, match => map.get(match)); - // street names - return str.replace(/str\b/g, "strasse").replace(/(?!\b)strasse\b/g, " strasse"); - }, - filter: filter, - stemmer: stemmer + prepare: function (str) { + + if (/[_äöüß&€]/.test(str)) str = str.replace(/[_äöüß&€]/g, match => map.get(match)); + + return str.replace(/str\b/g, "strasse").replace(/(?!\b)strasse\b/g, " strasse"); + }, + filter: filter, + stemmer: stemmer }; /** diff --git a/dist/module-debug/lang/en.js b/dist/module-debug/lang/en.js index 17afe21..959e0ec 100644 --- a/dist/module-debug/lang/en.js +++ b/dist/module-debug/lang/en.js @@ -1,53 +1,16 @@ import { EncoderOptions } from "../type.js"; -// todo filter out minlength - /** * http://www.ranks.nl/stopwords * @type {Set} */ -export const filter = new Set(["a", "about", "above", "after", "again", "against", "all", "also", "am", "an", "and", "any", "are", "arent", "as", "at", "back", "be", "because", "been", "before", "being", "below", "between", "both", "but", "by", "can", "cannot", "cant", "come", "could", "couldnt", -//"day", -"did", "didnt", "do", "does", "doesnt", "doing", "dont", "down", "during", "each", "even", "few", -//"first", -"for", "from", "further", "get", -//"give", -"go", "good", "had", "hadnt", "has", "hasnt", "have", "havent", "having", "he", "hed", -//"hell", -"her", "here", "heres", "hers", "herself", "hes", "him", "himself", "his", "how", "hows", "i", "id", "if", "ill", "im", "in", "into", "is", "isnt", "it", "its", "itself", "ive", "just", "know", "lets", "like", -//"look", -"lot", "make", "made", "me", "more", "most", "mustnt", "my", "myself", "new", "no", "nor", "not", "now", "of", "off", "on", "once", "one", "only", "or", "other", "ought", "our", "ours", "ourselves", "out", "over", "own", -//"people", -"same", "say", "see", "shant", "she", "shed", "shell", "shes", "should", "shouldnt", "so", "some", "such", "take", "than", "that", "thats", "the", "their", "theirs", "them", "themselves", "then", "there", "theres", "these", "they", "theyd", "theyll", "theyre", "theyve", "think", "this", "those", "through", "time", "times", "to", "too", -//"two", -"under", "until", "up", "us", "use", "very", "want", "was", "wasnt", "way", "we", "wed", "well", "were", "werent", "weve", "what", "whats", "when", "whens", "where", "wheres", "which", "while", "who", "whom", "whos", "why", "whys", "will", "with", "wont", "work", "would", "wouldnt", -//"year", -"ya", "you", "youd", "youll", "your", "youre", "yours", "yourself", "yourselves", "youve"]); +export const filter = new Set(["a", "about", "above", "after", "again", "against", "all", "also", "am", "an", "and", "any", "are", "arent", "as", "at", "back", "be", "because", "been", "before", "being", "below", "between", "both", "but", "by", "can", "cannot", "cant", "come", "could", "couldnt", "did", "didnt", "do", "does", "doesnt", "doing", "dont", "down", "during", "each", "even", "few", "for", "from", "further", "get", "go", "good", "had", "hadnt", "has", "hasnt", "have", "havent", "having", "he", "hed", "her", "here", "heres", "hers", "herself", "hes", "him", "himself", "his", "how", "hows", "i", "id", "if", "ill", "im", "in", "into", "is", "isnt", "it", "its", "itself", "ive", "just", "know", "lets", "like", "lot", "make", "made", "me", "more", "most", "mustnt", "my", "myself", "new", "no", "nor", "not", "now", "of", "off", "on", "once", "one", "only", "or", "other", "ought", "our", "ours", "ourselves", "out", "over", "own", "same", "say", "see", "shant", "she", "shed", "shell", "shes", "should", "shouldnt", "so", "some", "such", "take", "than", "that", "thats", "the", "their", "theirs", "them", "themselves", "then", "there", "theres", "these", "they", "theyd", "theyll", "theyre", "theyve", "think", "this", "those", "through", "time", "times", "to", "too", "under", "until", "up", "us", "use", "very", "want", "was", "wasnt", "way", "we", "wed", "well", "were", "werent", "weve", "what", "whats", "when", "whens", "where", "wheres", "which", "while", "who", "whom", "whos", "why", "whys", "will", "with", "wont", "work", "would", "wouldnt", "ya", "you", "youd", "youll", "your", "youre", "yours", "yourself", "yourselves", "youve"]); /** * @type {Map} */ -export const stemmer = new Map([ -//["ational", "ate"], -//["iveness", ""], -//["fulness", ""], -//["ousness", ""], -["ization", ""], -//["tional", "tion"], -["biliti", ""], ["icate", ""], ["ative", ""], -//["alize", ""], -//["iciti", ""], -//["entli", ""], -//["ousli", ""], -//["alism", ""], -["ation", ""], -//["aliti", ""], -["iviti", ""], ["ement", ""], ["izer", ""], ["able", ""], ["ible", ""], ["alli", ""], ["ator", ""], ["less", ""], ["logi", ""], ["ical", ""], ["ance", ""], ["ence", ""], ["ness", ""], ["ble", ""], ["ment", ""], -//["nal", "n"], -["eli", ""], ["bli", ""], ["ful", ""], ["ant", ""], ["ent", ""], ["ism", ""], ["ate", ""], ["iti", ""], ["ous", ""], ["ive", ""], ["ize", ""], ["ing", ""], ["ion", ""], ["ies", "y"], ["al", ""], ["ou", ""], ["er", ""], ["ed", ""], -//["es", "e"], -["ic", ""], ["ly", ""], ["li", ""], ["s", ""]]); +export const stemmer = new Map([["ization", ""], ["biliti", ""], ["icate", ""], ["ative", ""], ["ation", ""], ["iviti", ""], ["ement", ""], ["izer", ""], ["able", ""], ["ible", ""], ["alli", ""], ["ator", ""], ["less", ""], ["logi", ""], ["ical", ""], ["ance", ""], ["ence", ""], ["ness", ""], ["ble", ""], ["ment", ""], ["eli", ""], ["bli", ""], ["ful", ""], ["ant", ""], ["ent", ""], ["ism", ""], ["ate", ""], ["iti", ""], ["ous", ""], ["ive", ""], ["ize", ""], ["ing", ""], ["ion", ""], ["ies", "y"], ["al", ""], ["ou", ""], ["er", ""], ["ed", ""], ["ic", ""], ["ly", ""], ["li", ""], ["s", ""]]); /* he’s (= he is / he has) @@ -64,33 +27,14 @@ export const stemmer = new Map([ won’t (= will not) */ -// const explode = new Map([ -// ["^i'm$", "i am"], -// ["^can't$", "can not"], -// ["^cannot$", "can not"], -// ["^won't$", "will not"], -// ["'s$", " is has"], -// ["n't$", " not"], -// ["'ll$", " will"], -// ["'re$", " are"], -// ["'ve$", " have"], -// ["'d$", " would had"], -// ]); - /** * @type EncoderOptions */ const options = { - prepare: function (str) { - return str - // normalize symbols - .replace(/´`’ʼ/g, "'") - //.replace(/[_\-]+/g, " ") - .replace(/&/g, " and ").replace(/\$/g, " USD ").replace(/£/g, " GBP ") - // explode short forms - .replace(/\bi'm\b/g, "i am").replace(/\b(can't|cannot)\b/g, "can not").replace(/\bwon't\b/g, "will not").replace(/([a-z])'s\b/g, "$1 is has").replace(/([a-z])n't\b/g, "$1 not").replace(/([a-z])'ll\b/g, "$1 will").replace(/([a-z])'re\b/g, "$1 are").replace(/([a-z])'ve\b/g, "$1 have").replace(/([a-z])'d\b/g, "$1 would had"); - }, - filter: filter, - stemmer: stemmer + prepare: function (str) { + return str.replace(/´`’ʼ/g, "'").replace(/&/g, " and ").replace(/\$/g, " USD ").replace(/£/g, " GBP ").replace(/\bi'm\b/g, "i am").replace(/\b(can't|cannot)\b/g, "can not").replace(/\bwon't\b/g, "will not").replace(/([a-z])'s\b/g, "$1 is has").replace(/([a-z])n't\b/g, "$1 not").replace(/([a-z])'ll\b/g, "$1 will").replace(/([a-z])'re\b/g, "$1 are").replace(/([a-z])'ve\b/g, "$1 have").replace(/([a-z])'d\b/g, "$1 would had"); + }, + filter: filter, + stemmer: stemmer }; export default options; \ No newline at end of file diff --git a/dist/module-debug/preset.js b/dist/module-debug/preset.js index 18fd7d2..0ef9da1 100644 --- a/dist/module-debug/preset.js +++ b/dist/module-debug/preset.js @@ -14,8 +14,7 @@ const presets = { performance: { resolution: 3, - fastupdate: /* tag? */ /* stringify */ /* stringify */ /* single param */ /* skip update: */ /* append: */ /* skip update: */ /* skip_update: */ /* skip deletion */ // splice: - !0 /*await rows.hasNext()*/ /*await rows.hasNext()*/ /*await rows.hasNext()*/, + fastupdate: !0, context: { depth: 1, resolution: 1 diff --git a/dist/module-debug/resolve/and.js b/dist/module-debug/resolve/and.js index 1929674..9524427 100644 --- a/dist/module-debug/resolve/and.js +++ b/dist/module-debug/resolve/and.js @@ -84,7 +84,7 @@ function return_result(final, promises, limit, offset, enrich, resolve, suggest) this.result = /** @type {SearchResults|IntermediateSearchResults} */final; } } else { - //final = [this.result].concat(final); + this.result.length && final.unshift(this.result); if (2 > final.length) { diff --git a/dist/module-debug/resolve/default.js b/dist/module-debug/resolve/default.js index c280c35..d635438 100644 --- a/dist/module-debug/resolve/default.js +++ b/dist/module-debug/resolve/default.js @@ -25,7 +25,6 @@ export default function (result, limit, offset, enrich) { return result; } - // fast path: when there is just one slot in the result if (1 === result.length) { let final = result[0]; final = offset || final.length > limit ? limit ? final.slice(offset, offset + limit) : final.slice(offset) : final; @@ -34,19 +33,16 @@ export default function (result, limit, offset, enrich) { let final = []; - // this is an optimized workaround instead of - // just doing result = concat(result) - for (let i = 0, arr, len; i < result.length; i++) { if (!(arr = result[i]) || !(len = arr.length)) continue; if (offset) { - // forward offset pointer + if (offset >= len) { offset -= len; continue; } - // apply offset pointer when length differs + if (offset < len) { arr = limit ? arr.slice(offset, offset + limit) : arr.slice(offset); len = arr.length; @@ -60,7 +56,7 @@ export default function (result, limit, offset, enrich) { } if (!final.length) { - // fast path: when limit was reached in first slot + if (len >= limit) { return enrich ? apply_enrich.call(this, arr) : arr; } @@ -69,7 +65,6 @@ export default function (result, limit, offset, enrich) { final.push(arr); limit -= len; - // break if limit was reached if (!limit) { break; } @@ -78,23 +73,4 @@ export default function (result, limit, offset, enrich) { final = 1 < final.length ? concat(final) : final[0]; return enrich ? apply_enrich.call(this, final) : final; -} - -// /** -// * @param {SearchResults} ids -// * @return {EnrichedSearchResults} -// */ -// -// export function enrich_result(ids){ -// // ids could be the original reference to an index value -// /** @type {EnrichedSearchResults} */ -// const result = new Array(ids.length); -// for(let i = 0, id; i < ids.length; i++){ -// id = ids[i]; -// result[i] = { -// "id": id, -// "doc": this.store.get(id) -// }; -// } -// return result; -// } \ No newline at end of file +} \ No newline at end of file diff --git a/dist/module-debug/resolve/handler.js b/dist/module-debug/resolve/handler.js index 6e3381d..32d7980 100644 --- a/dist/module-debug/resolve/handler.js +++ b/dist/module-debug/resolve/handler.js @@ -13,16 +13,14 @@ Resolver.prototype.handler = function (fn, args) { if (first_argument.then) { const self = this; - // todo: check when this branch was taken - // instead of Promise.all the args[] array could be reduced - // by iterate recursively one by one + return Promise.all(args).then(function (args) { return self[fn].apply(self, args); }); } if (first_argument[0]) { - // detect array parameter style + if (first_argument[0].index) { return this[fn].apply(this, first_argument); } @@ -87,13 +85,10 @@ Resolver.prototype.handler = function (fn, args) { } } - query.resolve = /* suggest */ /* append: */ /* enrich */!1; - //if(DEBUG) - //query.enrich = false; + query.resolve = !1; + result = index.search(query).result; query.resolve = resolve; - //if(DEBUG) - //query.enrich = enrich; if (highlight) { highlight_query = query.query; diff --git a/dist/module-debug/resolve/not.js b/dist/module-debug/resolve/not.js index 9466752..cd9070c 100644 --- a/dist/module-debug/resolve/not.js +++ b/dist/module-debug/resolve/not.js @@ -73,10 +73,6 @@ function return_result(final, promises, limit, offset, enrich, resolve, suggest) function exclusion(result, limit, offset, resolve) { - // if(!result.length){ - // return this.result; - // } - /** @type {SearchResults|IntermediateSearchResults} */ const final = [], exclude = new Set(result.flat().flat()); diff --git a/dist/module-debug/resolve/or.js b/dist/module-debug/resolve/or.js index 13fa4e3..7114d27 100644 --- a/dist/module-debug/resolve/or.js +++ b/dist/module-debug/resolve/or.js @@ -53,18 +53,15 @@ function return_result(final, promises, limit, offset, enrich, resolve) { } if (final.length) { - //this.result.length && (final = final.concat([this.result])); + this.result.length && final.push(this.result); if (2 > final.length) { this.result = final[0]; } else { - // the suggest-union (reversed processing, resolve needs to be disabled) - this.result = union(final /*.reverse()*/ - , limit, offset, /* suggest */ /* append: */ /* enrich */ - /* resolve: */!1, this.boostval); - // offset was already applied + this.result = union(final, limit, offset, !1, this.boostval); + offset = 0; } } diff --git a/dist/module-debug/resolve/xor.js b/dist/module-debug/resolve/xor.js index 844bb7f..5fdbb40 100644 --- a/dist/module-debug/resolve/xor.js +++ b/dist/module-debug/resolve/xor.js @@ -58,7 +58,7 @@ function return_result(final, promises, limit, offset, enrich, resolve, suggest) if (!final.length) { if (!suggest) this.result = /** @type {SearchResults|IntermediateSearchResults} */final; } else { - //this.result.length && (final = [this.result].concat(final)); + this.result.length && final.unshift(this.result); if (2 > final.length) { @@ -86,10 +86,6 @@ function return_result(final, promises, limit, offset, enrich, resolve, suggest) function exclusive(result, limit, offset, resolve, boost) { - // if(!result.length){ - // return result; - // } - /** @type {SearchResults|IntermediateSearchResults} */ const final = [], check = create_object(); @@ -135,7 +131,7 @@ function exclusive(result, limit, offset, resolve, boost) { return final; } } else { - // shift resolution by boost (inverse) + const index = j + (i ? boost : 0); final[index] || (final[index] = []); final[index].push(id); diff --git a/dist/module-debug/resolver.js b/dist/module-debug/resolver.js index 4fed2ac..1bad4c0 100644 --- a/dist/module-debug/resolver.js +++ b/dist/module-debug/resolver.js @@ -21,14 +21,10 @@ export default function Resolver(result, index) { if (!this || this.constructor !== Resolver) { return new Resolver(result, index); } - // if(result && result.constructor === Resolver){ - // // todo test this branch - // //console.log("Resolver Loopback") - // return /** @type {Resolver} */ (result); - // } + if (result && result.index) { - // result = /** @type {ResolverOptions} */ (result); - result.resolve = /* suggest */ /* append: */ /* enrich */ /* resolve: */!1; + + result.resolve = !1; this.index = /** @type {Index|Document} */result.index; this.boostval = result.boost || 0; this.result = this.index.search(result).result; @@ -116,19 +112,8 @@ Resolver.prototype.resolve = function (limit, offset, enrich) { limit.highlight; limit = limit.limit; } - // const document = this.index; - // if(document.index){ - // result = default_resolver(result, limit || 100, offset, false); - // return enrich - // ? apply_enrich.call(document, result) - // : result; - // } - // else{ + result = default_resolver.call(index, result, limit || 100, offset, enrich); - // if(highlight){ - // result = highlight_fields(result); - // } - // } } return result; diff --git a/dist/module-debug/serialize.js b/dist/module-debug/serialize.js index e92750c..69acdcc 100644 --- a/dist/module-debug/serialize.js +++ b/dist/module-debug/serialize.js @@ -174,7 +174,6 @@ export function exportIndex(callback, _field, _index_doc = 0, _index_obj = 0) { case 1: - // todo key = "cfg"; chunk = null; break; @@ -226,13 +225,12 @@ export function importIndex(key, data) { switch (key) { case "cfg": - // todo + break; case "reg": - // fast update isn't supported by export/import - this.fastupdate = /* suggest */ /* append: */ /* enrich */ /* resolve: */!1; + this.fastupdate = !1; this.reg = json_to_reg( /** @type {Array} */data, this.reg); break; @@ -262,7 +260,7 @@ export function exportDocument(callback, _field, _index_doc = 0, _index_obj = 0) const field = this.field[_index_doc], idx = this.index.get(field), res = idx.export(callback, field, _index_doc, _index_obj = 1); - // start from index 1, because document indexes does not additionally store register + if (res && res.then) { const self = this; @@ -299,13 +297,6 @@ export function exportDocument(callback, _field, _index_doc = 0, _index_obj = 0) _field = null; break; - // case 3: - // - // key = "cfg"; - // chunk = null; - // _field = null; - // break; - default: return; @@ -331,7 +322,6 @@ export function importDocument(key, data) { ref = 2 < split.length ? split[2] : split[1]; - // trigger the import for worker field indexes if (this.worker && field) { return this.index.get(field).import(key); } @@ -349,7 +339,6 @@ export function importDocument(key, data) { case "reg": - // fast update isn't supported by export/import this.fastupdate = !1; this.reg = json_to_reg( /** @type {Array} */data, this.reg); @@ -359,17 +348,14 @@ export function importDocument(key, data) { idx.reg = this.reg; } - // trigger the import for worker field indexes if (this.worker) { const promises = [], self = this; for (const index of this.index.values()) { - // const ref = item[0]; - // const index = item[1]; + promises.push(index.import(key)); - //this.index.get(field).import(key); } return Promise.all(promises); @@ -410,8 +396,7 @@ ctx: "gulliver+travel:1,2,3|4,5,6|7,8,9;" * @return {string} */ -export function serialize(withFunctionWrapper = /* tag? */ /* stringify */ /* stringify */ /* single param */ /* skip update: */ /* append: */ /* skip update: */ /* skip_update: */ /* skip deletion */ // splice: -!0 /*await rows.hasNext()*/ /*await rows.hasNext()*/ /*await rows.hasNext()*/) { +export function serialize(withFunctionWrapper = !0) { let reg = '', map = '', ctx = ''; diff --git a/dist/module-debug/type.js b/dist/module-debug/type.js index 51a8f87..368e9fb 100644 --- a/dist/module-debug/type.js +++ b/dist/module-debug/type.js @@ -1,5 +1,4 @@ -// When you are looking for type definitions which fully describes the usage take a look into the index.d.ts file. -// Some of the types here aren't supposed to be used as public, they might be defined just for internal state. + import Index from "./index.js"; import Encoder from "./encoder.js"; @@ -193,9 +192,10 @@ export let EnrichedDocumentSearchResults = []; /** * @typedef {{ * id: (number|string), - * doc: (Object|null), + * doc: (Object|null|undefined), * field: (Array|undefined), - * tag: (Array|undefined) + * tag: (Array|undefined), + * highlight: (Object|undefined) * }} */ export let MergedDocumentSearchEntry = {}; diff --git a/dist/module-debug/worker.js b/dist/module-debug/worker.js index 69aef56..967d758 100644 --- a/dist/module-debug/worker.js +++ b/dist/module-debug/worker.js @@ -19,14 +19,12 @@ export default function WorkerIndex(options = /** @type IndexOptions */{}, encod return new WorkerIndex(options); } - // the factory is the outer wrapper from the build - // it uses "self" as a trap for node.js let factory = "undefined" != typeof self ? self._factory : "undefined" != typeof window ? window._factory : null; if (factory) { factory = factory.toString(); } - const is_node_js = "undefined" == typeof window /*&& self["exports"]*/, + const is_node_js = "undefined" == typeof window, _self = this; /** @@ -56,8 +54,6 @@ export default function WorkerIndex(options = /** @type IndexOptions */{}, encod if (options.config) { - // when extern configuration needs to be loaded - // it needs to return a promise to await for return new Promise(function (resolve) { _self.resolver[++pid] = function () { @@ -74,19 +70,17 @@ export default function WorkerIndex(options = /** @type IndexOptions */{}, encod }); } + this.priority = options.priority || 4; + + + this.encoder = encoder || null; + this.worker.postMessage({ task: "init", factory: factory, options: options }); - this.priority = options.priority || 4; - - // assign encoder for result highlighting - if (encoder) { - this.encoder = encoder; - } - return this; } @@ -99,6 +93,7 @@ export default function WorkerIndex(options = /** @type IndexOptions */{}, encod register("add"); register("append"); register("search"); +register("searchCache"); register("update"); register("remove"); register("clear"); @@ -124,7 +119,7 @@ function register(key) { const promise = new Promise(function (resolve) { if ("export" === key && "function" == typeof args[0]) { - // remove function handler + args[0] = null; } self.resolver[++pid] = resolve; @@ -146,21 +141,7 @@ function register(key) { function create(factory, is_node_js, worker_path) { - let worker = is_node_js ? - // if anyone would ask me what JS has delivered the past 10 years, - // those are the lines I definitively show up first ^^ - "undefined" != typeof module - // This eval will be removed when compiling - // The issue is that this will not build by Closure Compiler - ? (0,eval)('new(require("worker_threads")["Worker"])(__dirname+"/worker/node.js")') - // this will need to remove in CommonJS builds, - // otherwise the module is treated as ESM by Node.js automatic detection - // the path src/worker/node.mjs is located at dist/node/node.mjs - // The issue is that this will not build by Babel Compiler - : import("worker_threads").then(function(worker){return new worker["Worker"](import.meta.dirname+"/../node/node.mjs")}) : factory ? new window.Worker(URL.createObjectURL(new Blob(["onmessage=" + handler.toString()], { type: "text/javascript" }))) : new window.Worker("string" == typeof worker_path ? worker_path - // when loaded from /src/ folder the worker file is located at /worker/worker.js - : (1, eval)("import.meta.url").replace("/worker.js", "/worker/worker.js").replace("flexsearch.bundle.module.min.js", "module/worker/worker.js") /*"worker/worker.js"*/ - , { type: "module" }); + let worker = is_node_js ? "undefined" != typeof module ? (0,eval)('new(require("worker_threads")["Worker"])(__dirname+"/worker/node.js")') : import("worker_threads").then(function(worker){return new worker["Worker"](import.meta.dirname+"/../node/node.mjs")}) : factory ? new window.Worker(URL.createObjectURL(new Blob(["onmessage=" + handler.toString()], { type: "text/javascript" }))) : new window.Worker("string" == typeof worker_path ? worker_path : (1, eval)("import.meta.url").replace("/worker.js", "/worker/worker.js").replace("flexsearch.bundle.module.min.js", "module/worker/worker.js"), { type: "module" }); return worker; } \ No newline at end of file diff --git a/dist/module-debug/worker/handler.js b/dist/module-debug/worker/handler.js index b019b56..9b4b8a2 100644 --- a/dist/module-debug/worker/handler.js +++ b/dist/module-debug/worker/handler.js @@ -22,21 +22,17 @@ export default (async function (data) { options = data.options || {}; let filepath = options.config; if (filepath) { - // compiler fix + options = options; - // will be replaced after build with the line below because - // there is an issue with closure compiler dynamic import - options=(await import(filepath))["default"]; } const factory = data.factory; if (factory) { - // export the FlexSearch global payload to "self" Function("return " + factory)()(self); index = new self.FlexSearch.Index(options); - // destroy the exported payload + delete self.FlexSearch; } else { @@ -54,11 +50,12 @@ export default (async function (data) { if (!options.export || "function" != typeof options.export) { throw new Error("Either no extern configuration provided for the Worker-Index or no method was defined on the config property \"export\"."); } - // skip non-field indexes + + if (!args[1]) args = null;else { args[0] = options.export; args[2] = 0; - args[3] = 1; // skip reg + args[3] = 1; } } if ("import" === task) { diff --git a/dist/module-debug/worker/node.js b/dist/module-debug/worker/node.js index 8b8b3d8..d92e17e 100644 --- a/dist/module-debug/worker/node.js +++ b/dist/module-debug/worker/node.js @@ -4,10 +4,6 @@ */ const { parentPort } = require("worker_threads"), { Index } = require("flexsearch"); -//const { join } = require("path"); -// Test Path -//const { Index } = require("../../dist/flexsearch.bundle.min.js"); - /** @type Index */ let index, options; @@ -24,7 +20,7 @@ parentPort.on("message", async function (data) { case "init": options = data.options || {}; - // load extern field configuration + let filepath = options.config; if (filepath) { options = Object.assign({}, options, require(filepath)); @@ -32,7 +28,6 @@ parentPort.on("message", async function (data) { } index = new Index(options); - //index.db && await index.db; parentPort.postMessage({ id: id }); break; @@ -45,11 +40,11 @@ parentPort.on("message", async function (data) { if (!options.export || "function" != typeof options.export) { throw new Error("Either no extern configuration provided for the Worker-Index or no method was defined on the config property \"export\"."); } - // skip non-field indexes + if (!args[1]) args = null;else { args[0] = options.export; args[2] = 0; - args[3] = 1; // skip reg + args[3] = 1; } } if ("import" === task) { diff --git a/dist/module-min/common.js b/dist/module-min/common.js index de04bf5..7e0ef63 100644 --- a/dist/module-min/common.js +++ b/dist/module-min/common.js @@ -1 +1 @@ -export function merge_option(a,b,c){const d=typeof c,e=typeof a;if("undefined"!=d){if("undefined"!=e){if(c){if("function"==e&&d==e)return function(b){return a(c(b))};const b=a.constructor,f=c.constructor;if(b===f){if(b===Array)return c.concat(a);if(b===Map){const b=new Map(c);for(const c of a){const a=c[0],d=c[1];b.set(a,d)}return b}if(b===Set){const b=new Set(c);for(const c of a.values())b.add(c);return b}}}return a}return c}return"undefined"==e?b:a}export function create_object(){return Object.create(null)}export function concat(a){return[].concat.apply([],a)}export function sort_by_length_down(c,a){return a.length-c.length}export function sort_by_length_up(c,a){return c.length-a.length}export function is_array(a){return a.constructor===Array}export function is_string(a){return"string"==typeof a}export function is_object(a){return"object"==typeof a}export function is_function(a){return"function"==typeof a}export function toArray(a,b){const c=[];for(const d of a.keys())c.push(b?""+d:d);return c}export function parse_simple(a,b){if(is_string(b))a=a[b];else for(let c=0;a&&cc||d)&&(f=f.slice(d,d+c)),e&&(f=apply_enrich.call(this,f))),f}export function apply_enrich(a){if(!this||!this.store)return a;const b=Array(a.length);for(let c,d=0;d= target; } - // cycle all instances from this point if (cycle) { const self = this; - // move the next microtask onto the next macrotask queue + return new Promise(resolve => { setTimeout(function () { resolve(self[key + "Async"].apply(self, args)); diff --git a/dist/module/bundle.js b/dist/module/bundle.js index 1319942..970d520 100644 --- a/dist/module/bundle.js +++ b/dist/module/bundle.js @@ -146,8 +146,8 @@ import { KeystoreMap, KeystoreArray, KeystoreSet } from "./keystore.js"; /** @export */IndexOptions.cache; /** @export */IndexOptions.resolve; /** @export */IndexOptions.db; -/** @export */IndexOptions.worker; // worker url -/** @export */IndexOptions.config; // config url +/** @export */IndexOptions.worker; +/** @export */IndexOptions.config; /** @export */IndexOptions.priority; /** @export */IndexOptions.export; /** @export */IndexOptions.import; @@ -304,32 +304,21 @@ const FlexSearch = { Language: {} }; -// Export as library (Bundle) -// -------------------------------- - { - // Legacy Browser: this refers to window - // ESM Browser: self refers to window - // NodeJS: global refers to the global scope const root = "undefined" != typeof self ? self : "undefined" != typeof global ? global : self; let prop; - // AMD (RequireJS) if ((prop = root.define) && prop.amd) { prop([], function () { return FlexSearch; }); + } else if ("object" == typeof root.exports) { + root.exports = FlexSearch; + } else { + /** @export */ + root.FlexSearch = FlexSearch; } - // CommonJS - else if ("object" == typeof root.exports) { - root.exports = FlexSearch; - } - // Global (window) - else { - /** @export */ - root.FlexSearch = FlexSearch; - } } diff --git a/dist/module/charset.js b/dist/module/charset.js index 659ce73..cecd70c 100644 --- a/dist/module/charset.js +++ b/dist/module/charset.js @@ -6,36 +6,35 @@ import charset_latin_extra from "./charset/latin/extra.js"; import charset_latin_soundex from "./charset/latin/soundex.js"; import charset_cjk from "./charset/cjk.js"; -// universal charset export const Exact = charset_exact; export const Default = charset_normalize; export const Normalize = charset_normalize; -// latin charset + export const LatinBalance = charset_latin_balance; export const LatinAdvanced = charset_latin_advanced; export const LatinExtra = charset_latin_extra; export const LatinSoundex = charset_latin_soundex; -// CJK + export const CJK = charset_cjk; -// deprecated + export const LatinExact = charset_exact; export const LatinDefault = charset_normalize; export const LatinSimple = charset_normalize; export default { - // universal charset - Exact: charset_exact, - Default: charset_normalize, - Normalize: charset_normalize, - // latin charset - LatinBalance: charset_latin_balance, - LatinAdvanced: charset_latin_advanced, - LatinExtra: charset_latin_extra, - LatinSoundex: charset_latin_soundex, - // CJK - CJK: charset_cjk, - // deprecated - LatinExact: charset_exact, - LatinDefault: charset_normalize, - LatinSimple: charset_normalize + + Exact: charset_exact, + Default: charset_normalize, + Normalize: charset_normalize, + + LatinBalance: charset_latin_balance, + LatinAdvanced: charset_latin_advanced, + LatinExtra: charset_latin_extra, + LatinSoundex: charset_latin_soundex, + + CJK: charset_cjk, + + LatinExact: charset_exact, + LatinDefault: charset_normalize, + LatinSimple: charset_normalize }; \ No newline at end of file diff --git a/dist/module/charset/cjk.js b/dist/module/charset/cjk.js index 0767906..f920a29 100644 --- a/dist/module/charset/cjk.js +++ b/dist/module/charset/cjk.js @@ -1,14 +1,8 @@ import { EncoderOptions } from "../type.js"; -// https://en.wikipedia.org/wiki/CJK_characters - /** @type EncoderOptions */ const options = { split: "" - //normalize: true - // normalize: function(str){ - // return str.toLowerCase(); - // }, - //dedupe: false + }; export default options; \ No newline at end of file diff --git a/dist/module/charset/exact.js b/dist/module/charset/exact.js index 29c26bb..9a79b28 100644 --- a/dist/module/charset/exact.js +++ b/dist/module/charset/exact.js @@ -5,8 +5,6 @@ const options = { normalize: !1, numeric: !1, dedupe: !1 - //split: /\s+/ - //normalize: false, - //dedupe: false + }; export default options; \ No newline at end of file diff --git a/dist/module/charset/latin/advanced.js b/dist/module/charset/latin/advanced.js index e20e3d9..3bb213c 100644 --- a/dist/module/charset/latin/advanced.js +++ b/dist/module/charset/latin/advanced.js @@ -1,26 +1,15 @@ import { EncoderOptions } from "../../type.js"; import { soundex } from "./balance.js"; -export const matcher = new Map([ -//["ai", "ei"], // before soundex -["ae", "a"], ["oe", "o"], -//["ue", "u"], // soundex map -["sh", "s"], // replacer "h" -//["ch", "c"], // before soundex -["kh", "k"], // after soundex -["th", "t"], // replacer "h" -["ph", "f"], // replacer "h" -["pf", "f"]]); +export const matcher = new Map([["ae", "a"], ["oe", "o"], ["sh", "s"], ["kh", "k"], ["th", "t"], ["ph", "f"], ["pf", "f"]]); -export const replacer = [/([^aeo])h(.)/g, "$1$2", /([aeo])h([^aeo]|$)/g, "$1$2", /(.)\1+/g, "$1" // /([^0-9])\1+/g, "$1" -]; +export const replacer = [/([^aeo])h(.)/g, "$1$2", /([aeo])h([^aeo]|$)/g, "$1$2", /(.)\1+/g, "$1"]; /** @type EncoderOptions */ const options = { - //normalize: true, - //dedupe: true, - mapper: soundex, - matcher: matcher, - replacer: replacer + + mapper: soundex, + matcher: matcher, + replacer: replacer }; export default options; \ No newline at end of file diff --git a/dist/module/charset/latin/balance.js b/dist/module/charset/latin/balance.js index 6eb1be8..970b584 100644 --- a/dist/module/charset/latin/balance.js +++ b/dist/module/charset/latin/balance.js @@ -1,37 +1,10 @@ import { EncoderOptions } from "../../type.js"; -export const soundex = new Map([["b", "p"], -//["p", "p"], - -//["f", "f"], -["v", "f"], ["w", "f"], - -//["s", "s"], -["z", "s"], ["x", "s"], ["d", "t"], -//["t", "t"], - -//["m", "m"], -["n", "m"], - -//["k", "k"], -["c", "k"], ["g", "k"], ["j", "k"], ["q", "k"], - -//["r", "r"], -//["h", "h"], -//["l", "l"], - -//["a", "a"], - -//["e", "e"], -["i", "e"], ["y", "e"], - -//["o", "o"], -["u", "o"]]); +export const soundex = new Map([["b", "p"], ["v", "f"], ["w", "f"], ["z", "s"], ["x", "s"], ["d", "t"], ["n", "m"], ["c", "k"], ["g", "k"], ["j", "k"], ["q", "k"], ["i", "e"], ["y", "e"], ["u", "o"]]); /** @type EncoderOptions */ const options = { - //normalize: true, - //dedupe: true, - mapper: soundex + + mapper: soundex }; export default options; \ No newline at end of file diff --git a/dist/module/charset/latin/extra.js b/dist/module/charset/latin/extra.js index 4498453..20a2038 100644 --- a/dist/module/charset/latin/extra.js +++ b/dist/module/charset/latin/extra.js @@ -2,13 +2,11 @@ import { EncoderOptions } from "../../type.js"; import { soundex } from "./balance.js"; import { matcher, replacer } from "./advanced.js"; -export const compact = [/(?!^)[aeo]/g, "" // before soundex: aeoy, old: aioy -]; +export const compact = [/(?!^)[aeo]/g, ""]; /** @type EncoderOptions */ const options = { - //normalize: true, - //dedupe: true, + mapper: soundex, replacer: replacer.concat(compact), matcher: matcher diff --git a/dist/module/charset/latin/soundex.js b/dist/module/charset/latin/soundex.js index c15547f..4ec93c9 100644 --- a/dist/module/charset/latin/soundex.js +++ b/dist/module/charset/latin/soundex.js @@ -2,7 +2,7 @@ import { EncoderOptions } from "../../type.js"; /** @type {EncoderOptions} */ const options = { - //normalize: true, + dedupe: !1, include: { letter: !0 @@ -31,13 +31,13 @@ function soundex(stringToEncode) { for (let i = 1, char; i < stringToEncode.length; i++) { char = stringToEncode.charAt(i); - // Remove all occurrences of "h" and "w" + if ("h" !== char && "w" !== char) { - // Replace all consonants with digits + char = codes[char]; - // Remove all occurrences of a,e,i,o,u,y except first letter + if (char) { - // Replace all adjacent same digits with one digit + if (char !== last) { encodedString += char; last = char; @@ -48,8 +48,6 @@ function soundex(stringToEncode) { } } } - // while(encodedString.length < 4){ - // encodedString += "0"; - // } + return encodedString; } \ No newline at end of file diff --git a/dist/module/charset/normalize.js b/dist/module/charset/normalize.js index 1c971e5..372f954 100644 --- a/dist/module/charset/normalize.js +++ b/dist/module/charset/normalize.js @@ -1,11 +1,5 @@ import { EncoderOptions } from "../type.js"; /** @type EncoderOptions */ -const options = { - //normalize: true - // normalize: function(str){ - // return str.toLowerCase(); - // }, - //dedupe: false -}; +const options = {}; export default options; \ No newline at end of file diff --git a/dist/module/charset/polyfill.js b/dist/module/charset/polyfill.js index 749d40b..c32cbde 100644 --- a/dist/module/charset/polyfill.js +++ b/dist/module/charset/polyfill.js @@ -1,29 +1 @@ -export default [ - -// Charset Normalization - -["ª", "a"], ["²", "2"], ["³", "3"], ["¹", "1"], ["º", "o"], ["¼", "1⁄4"], ["½", "1⁄2"], ["¾", "3⁄4"], ["à", "a"], ["á", "a"], ["â", "a"], ["ã", "a"], ["ä", "a"], ["å", "a"], ["ç", "c"], ["è", "e"], ["é", "e"], ["ê", "e"], ["ë", "e"], ["ì", "i"], ["í", "i"], ["î", "i"], ["ï", "i"], ["ñ", "n"], ["ò", "o"], ["ó", "o"], ["ô", "o"], ["õ", "o"], ["ö", "o"], ["ù", "u"], ["ú", "u"], ["û", "u"], ["ü", "u"], ["ý", "y"], ["ÿ", "y"], ["ā", "a"], ["ă", "a"], ["ą", "a"], ["ć", "c"], ["ĉ", "c"], ["ċ", "c"], ["č", "c"], ["ď", "d"], ["ē", "e"], ["ĕ", "e"], ["ė", "e"], ["ę", "e"], ["ě", "e"], ["ĝ", "g"], ["ğ", "g"], ["ġ", "g"], ["ģ", "g"], ["ĥ", "h"], ["ĩ", "i"], ["ī", "i"], ["ĭ", "i"], ["į", "i"], ["ij", "ij"], ["ĵ", "j"], ["ķ", "k"], ["ĺ", "l"], ["ļ", "l"], ["ľ", "l"], ["ŀ", "l"], ["ń", "n"], ["ņ", "n"], ["ň", "n"], ["ʼn", "n"], ["ō", "o"], ["ŏ", "o"], ["ő", "o"], ["ŕ", "r"], ["ŗ", "r"], ["ř", "r"], ["ś", "s"], ["ŝ", "s"], ["ş", "s"], ["š", "s"], ["ţ", "t"], ["ť", "t"], ["ũ", "u"], ["ū", "u"], ["ŭ", "u"], ["ů", "u"], ["ű", "u"], ["ų", "u"], ["ŵ", "w"], ["ŷ", "y"], ["ź", "z"], ["ż", "z"], ["ž", "z"], ["ſ", "s"], ["ơ", "o"], ["ư", "u"], ["dž", "dz"], ["lj", "lj"], ["nj", "nj"], ["ǎ", "a"], ["ǐ", "i"], ["ǒ", "o"], ["ǔ", "u"], ["ǖ", "u"], ["ǘ", "u"], ["ǚ", "u"], ["ǜ", "u"], ["ǟ", "a"], ["ǡ", "a"], ["ǣ", "ae"], ["æ", "ae"], ["ǽ", "ae"], ["ǧ", "g"], ["ǩ", "k"], ["ǫ", "o"], ["ǭ", "o"], ["ǯ", "ʒ"], ["ǰ", "j"], ["dz", "dz"], ["ǵ", "g"], ["ǹ", "n"], ["ǻ", "a"], ["ǿ", "ø"], ["ȁ", "a"], ["ȃ", "a"], ["ȅ", "e"], ["ȇ", "e"], ["ȉ", "i"], ["ȋ", "i"], ["ȍ", "o"], ["ȏ", "o"], ["ȑ", "r"], ["ȓ", "r"], ["ȕ", "u"], ["ȗ", "u"], ["ș", "s"], ["ț", "t"], ["ȟ", "h"], ["ȧ", "a"], ["ȩ", "e"], ["ȫ", "o"], ["ȭ", "o"], ["ȯ", "o"], ["ȱ", "o"], ["ȳ", "y"], ["ʰ", "h"], ["ʱ", "h"], ["ɦ", "h"], ["ʲ", "j"], ["ʳ", "r"], ["ʴ", "ɹ"], ["ʵ", "ɻ"], ["ʶ", "ʁ"], ["ʷ", "w"], ["ʸ", "y"], ["ˠ", "ɣ"], ["ˡ", "l"], ["ˢ", "s"], ["ˣ", "x"], ["ˤ", "ʕ"], ["ΐ", "ι"], ["ά", "α"], ["έ", "ε"], ["ή", "η"], ["ί", "ι"], ["ΰ", "υ"], ["ϊ", "ι"], ["ϋ", "υ"], ["ό", "ο"], ["ύ", "υ"], ["ώ", "ω"], ["ϐ", "β"], ["ϑ", "θ"], ["ϒ", "Υ"], ["ϓ", "Υ"], ["ϔ", "Υ"], ["ϕ", "φ"], ["ϖ", "π"], ["ϰ", "κ"], ["ϱ", "ρ"], ["ϲ", "ς"], ["ϵ", "ε"], ["й", "и"], ["ѐ", "е"], ["ё", "е"], ["ѓ", "г"], ["ї", "і"], ["ќ", "к"], ["ѝ", "и"], ["ў", "у"], ["ѷ", "ѵ"], ["ӂ", "ж"], ["ӑ", "а"], ["ӓ", "а"], ["ӗ", "е"], ["ӛ", "ә"], ["ӝ", "ж"], ["ӟ", "з"], ["ӣ", "и"], ["ӥ", "и"], ["ӧ", "о"], ["ӫ", "ө"], ["ӭ", "э"], ["ӯ", "у"], ["ӱ", "у"], ["ӳ", "у"], ["ӵ", "ч"] - -// Term Separators - -// ["'", ""], // it's -> its -// ["´", ""], -// ["`", ""], -// ["’", ""], -// ["ʼ", ""], - -// Numeric-Separators Chars Removal - -// [",", ""], -// [".", ""] - -// Non-Whitespace Separators - -// already was split by default via p{P} -// ["-", " "], -// [":", " "], -// ["_", " "], -// ["|", " "], -// ["/", " "], -// ["\\", " "] -]; \ No newline at end of file +export default [["ª", "a"], ["²", "2"], ["³", "3"], ["¹", "1"], ["º", "o"], ["¼", "1⁄4"], ["½", "1⁄2"], ["¾", "3⁄4"], ["à", "a"], ["á", "a"], ["â", "a"], ["ã", "a"], ["ä", "a"], ["å", "a"], ["ç", "c"], ["è", "e"], ["é", "e"], ["ê", "e"], ["ë", "e"], ["ì", "i"], ["í", "i"], ["î", "i"], ["ï", "i"], ["ñ", "n"], ["ò", "o"], ["ó", "o"], ["ô", "o"], ["õ", "o"], ["ö", "o"], ["ù", "u"], ["ú", "u"], ["û", "u"], ["ü", "u"], ["ý", "y"], ["ÿ", "y"], ["ā", "a"], ["ă", "a"], ["ą", "a"], ["ć", "c"], ["ĉ", "c"], ["ċ", "c"], ["č", "c"], ["ď", "d"], ["ē", "e"], ["ĕ", "e"], ["ė", "e"], ["ę", "e"], ["ě", "e"], ["ĝ", "g"], ["ğ", "g"], ["ġ", "g"], ["ģ", "g"], ["ĥ", "h"], ["ĩ", "i"], ["ī", "i"], ["ĭ", "i"], ["į", "i"], ["ij", "ij"], ["ĵ", "j"], ["ķ", "k"], ["ĺ", "l"], ["ļ", "l"], ["ľ", "l"], ["ŀ", "l"], ["ń", "n"], ["ņ", "n"], ["ň", "n"], ["ʼn", "n"], ["ō", "o"], ["ŏ", "o"], ["ő", "o"], ["ŕ", "r"], ["ŗ", "r"], ["ř", "r"], ["ś", "s"], ["ŝ", "s"], ["ş", "s"], ["š", "s"], ["ţ", "t"], ["ť", "t"], ["ũ", "u"], ["ū", "u"], ["ŭ", "u"], ["ů", "u"], ["ű", "u"], ["ų", "u"], ["ŵ", "w"], ["ŷ", "y"], ["ź", "z"], ["ż", "z"], ["ž", "z"], ["ſ", "s"], ["ơ", "o"], ["ư", "u"], ["dž", "dz"], ["lj", "lj"], ["nj", "nj"], ["ǎ", "a"], ["ǐ", "i"], ["ǒ", "o"], ["ǔ", "u"], ["ǖ", "u"], ["ǘ", "u"], ["ǚ", "u"], ["ǜ", "u"], ["ǟ", "a"], ["ǡ", "a"], ["ǣ", "ae"], ["æ", "ae"], ["ǽ", "ae"], ["ǧ", "g"], ["ǩ", "k"], ["ǫ", "o"], ["ǭ", "o"], ["ǯ", "ʒ"], ["ǰ", "j"], ["dz", "dz"], ["ǵ", "g"], ["ǹ", "n"], ["ǻ", "a"], ["ǿ", "ø"], ["ȁ", "a"], ["ȃ", "a"], ["ȅ", "e"], ["ȇ", "e"], ["ȉ", "i"], ["ȋ", "i"], ["ȍ", "o"], ["ȏ", "o"], ["ȑ", "r"], ["ȓ", "r"], ["ȕ", "u"], ["ȗ", "u"], ["ș", "s"], ["ț", "t"], ["ȟ", "h"], ["ȧ", "a"], ["ȩ", "e"], ["ȫ", "o"], ["ȭ", "o"], ["ȯ", "o"], ["ȱ", "o"], ["ȳ", "y"], ["ʰ", "h"], ["ʱ", "h"], ["ɦ", "h"], ["ʲ", "j"], ["ʳ", "r"], ["ʴ", "ɹ"], ["ʵ", "ɻ"], ["ʶ", "ʁ"], ["ʷ", "w"], ["ʸ", "y"], ["ˠ", "ɣ"], ["ˡ", "l"], ["ˢ", "s"], ["ˣ", "x"], ["ˤ", "ʕ"], ["ΐ", "ι"], ["ά", "α"], ["έ", "ε"], ["ή", "η"], ["ί", "ι"], ["ΰ", "υ"], ["ϊ", "ι"], ["ϋ", "υ"], ["ό", "ο"], ["ύ", "υ"], ["ώ", "ω"], ["ϐ", "β"], ["ϑ", "θ"], ["ϒ", "Υ"], ["ϓ", "Υ"], ["ϔ", "Υ"], ["ϕ", "φ"], ["ϖ", "π"], ["ϰ", "κ"], ["ϱ", "ρ"], ["ϲ", "ς"], ["ϵ", "ε"], ["й", "и"], ["ѐ", "е"], ["ё", "е"], ["ѓ", "г"], ["ї", "і"], ["ќ", "к"], ["ѝ", "и"], ["ў", "у"], ["ѷ", "ѵ"], ["ӂ", "ж"], ["ӑ", "а"], ["ӓ", "а"], ["ӗ", "е"], ["ӛ", "ә"], ["ӝ", "ж"], ["ӟ", "з"], ["ӣ", "и"], ["ӥ", "и"], ["ӧ", "о"], ["ӫ", "ө"], ["ӭ", "э"], ["ӯ", "у"], ["ӱ", "у"], ["ӳ", "у"], ["ӵ", "ч"]]; \ No newline at end of file diff --git a/dist/module/common.js b/dist/module/common.js index 24f7236..7ccc1da 100644 --- a/dist/module/common.js +++ b/dist/module/common.js @@ -4,7 +4,6 @@ * @param {*=} merge_value * @return {*} */ - export function merge_option(value, default_value, merge_value) { const type_merge = typeof merge_value, type_value = typeof value; @@ -62,6 +61,10 @@ export function merge_option(value, default_value, merge_value) { return "undefined" == type_value ? default_value : value; } +export function inherit(target_value, default_value) { + return "undefined" == typeof target_value ? default_value : target_value; +} + export function create_object() { return Object.create(null); } @@ -108,7 +111,6 @@ export function toArray(val, stringify) { return result; } -// TODO support generic function created from string when tree depth > 1 export function parse_simple(obj, tree) { if (is_string(tree)) { diff --git a/dist/module/compress.js b/dist/module/compress.js index 7da6af0..a47a3bb 100644 --- a/dist/module/compress.js +++ b/dist/module/compress.js @@ -1,4 +1,4 @@ -let table, timer; // = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz+/"; +let table, timer; const cache = new Map(); @@ -6,7 +6,7 @@ function toRadix(number, radix = 255) { if (!table) { table = Array(radix); - // the char code 0 could be a special marker + for (let i = 0; i < radix; i++) table[i] = i + 1; table = String.fromCharCode.apply(null, table); } @@ -35,7 +35,6 @@ export default function (str) { timer = setTimeout(clear, 1); } - /* 2 ** ((level + 1.5) * 1.6 | 0) */ const result = toRadix("number" == typeof str ? str : lcg(str)); @@ -55,7 +54,7 @@ function lcg(str) { for (let i = 0; i < str.length; i++) { crc = (crc * 33 ^ str.charCodeAt(i)) & range; } - // shift up from Int32 to UInt32 range 0xFFFFFFFF + return crc + 2147483648; } diff --git a/dist/module/db/clickhouse/index.js b/dist/module/db/clickhouse/index.js index 5d12d2f..c494dac 100644 --- a/dist/module/db/clickhouse/index.js +++ b/dist/module/db/clickhouse/index.js @@ -65,14 +65,13 @@ export default function ClickhouseDB(name, config = {}) { if (!name) { console.info("Default storage space was used, because a name was not passed."); } - //field = "Test-456"; + this.id = "flexsearch" + (name ? "_" + sanitize(name) : ""); this.field = config.field ? "_" + sanitize(config.field) : ""; - // Clickhouse does not support ALTER TABLE to upgrade - // the type of the ID when it is a part of the merge key + this.type = config.type ? types[config.type.toLowerCase()] : "String"; if (!this.type) throw new Error("Unknown type of ID '" + config.type + "'"); - //this.trx = false; + this.support_tag_search = !0; this.db = Index || (Index = config.db || null); Object.assign(defaults, config); @@ -81,7 +80,7 @@ export default function ClickhouseDB(name, config = {}) { } ClickhouseDB.prototype.mount = function (flexsearch) { - //if(flexsearch.constructor === Document){ + if (flexsearch.index) { return flexsearch.mount(this); } @@ -116,7 +115,7 @@ ClickhouseDB.prototype.open = async function () { id ${this.type} ) ENGINE = MergeTree - /*PRIMARY KEY (key)*/ + ORDER BY (key, id); `, { params: { name: this.id + ".map" + this.field } }).toPromise(); break; @@ -130,7 +129,7 @@ ClickhouseDB.prototype.open = async function () { id ${this.type} ) ENGINE = MergeTree - /*PRIMARY KEY (ctx, key)*/ + ORDER BY (ctx, key, id); `).toPromise(); break; @@ -142,7 +141,7 @@ ClickhouseDB.prototype.open = async function () { id ${this.type} ) ENGINE = MergeTree - /*PRIMARY KEY (ctx, key)*/ + ORDER BY (tag, id); `).toPromise(); break; @@ -173,7 +172,7 @@ ClickhouseDB.prototype.open = async function () { }; ClickhouseDB.prototype.close = function () { - //DB && DB.close(); + this.db = Index = null; return this; }; @@ -309,7 +308,7 @@ ClickhouseDB.prototype.has = async function (id) { const result = await this.db.query(` SELECT 1 FROM ${this.id}.reg - WHERE id = {id:${this.type /*=== "number" ? "Int32" : "String"*/}} + WHERE id = {id:${this.type}} LIMIT 1`, { params: { id } }).toPromise(); return !!(result && result[0] && result[0][1]); }; @@ -347,7 +346,7 @@ ClickhouseDB.prototype.search = function (flexsearch, query, limit = 100, offset ${enrich ? ", doc" : ""} FROM ( SELECT id, count(*) as count, - ${suggest ? "SUM" : "SUM" /*"MIN"*/}(res) as res + ${suggest ? "SUM" : "SUM"}(res) as res FROM ${this.id}.ctx${this.field} WHERE ${where} GROUP BY id @@ -360,32 +359,6 @@ ClickhouseDB.prototype.search = function (flexsearch, query, limit = 100, offset ${limit ? "LIMIT " + limit : ""} ${offset ? "OFFSET " + offset : ""} `, { params }).toPromise(); - - // for(let i = 1; i < query.length; i++){ - // where += (where ? " UNION ALL " : "") + ` - // SELECT id, res - // FROM ${this.id}.ctx${this.field} - // WHERE ctx = {ctx${i}:String} AND key = {key${i}:String} - // `; - // term = query[i]; - // const swap = flexsearch.bidirectional && (term > keyword); - // params["ctx" + i] = swap ? term : keyword; - // params["key" + i] = swap ? keyword : term; - // keyword = term; - // } - // - // rows = await this.db.query(` - // SELECT id, res - // FROM ( - // SELECT id, ${suggest ? "SUM" : "MIN"}(res) as res, count(*) as count - // FROM (${where}) as t - // GROUP BY id - // ORDER BY ${suggest ? "count DESC, res" : "res"} - // LIMIT ${limit} - // OFFSET ${offset} - // ) as r - // ${suggest ? "" : "WHERE count = " + (query.length - 1)} - // `, { params }).toPromise(); } else { let where = "", params = {}; @@ -412,7 +385,7 @@ ClickhouseDB.prototype.search = function (flexsearch, query, limit = 100, offset ${enrich ? ", doc" : ""} FROM ( SELECT id, count(*) as count, - ${suggest ? "SUM" : "SUM" /*"MIN"*/}(res) as res + ${suggest ? "SUM" : "SUM"}(res) as res FROM ${this.id}.map${this.field} WHERE ${where} GROUP BY id @@ -425,56 +398,31 @@ ClickhouseDB.prototype.search = function (flexsearch, query, limit = 100, offset ${limit ? "LIMIT " + limit : ""} ${offset ? "OFFSET " + offset : ""} `, { params }).toPromise(); - - // for(let i = 0; i < query.length; i++){ - // params["key" + i] = query[i]; - // where += (where ? " UNION ALL " : "") + ` - // SELECT id, res - // FROM ${ this.id }.map${ this.field } - // WHERE key = {key${i}:String} - // `; - // } - // rows = await this.db.query(` - // SELECT id, res - // FROM ( - // SELECT id, ${suggest ? "SUM" : "MIN"}(res) as res, count(*) as count - // FROM (${where}) as t - // GROUP BY id - // ORDER BY ${suggest ? "count DESC, res" : "res"} - // LIMIT ${limit} - // OFFSET ${offset} - // ) as r - // ${ suggest ? "" : "WHERE count = " + query.length } - // `, { params }).toPromise(); } return rows.then(function (rows) { return create_result(rows, resolve, enrich); }); }; -ClickhouseDB.prototype.info = function () { - // todo -}; +ClickhouseDB.prototype.info = function () {}; ClickhouseDB.prototype.transaction = function (task) { - // not supported return task.call(this); }; ClickhouseDB.prototype.commit = async function (flexsearch, _replace, _append) { - // process cleanup tasks if (_replace) { await this.clear(); - // there are just removals in the task queue + flexsearch.commit_task = []; } else { let tasks = flexsearch.commit_task; flexsearch.commit_task = []; for (let i = 0, task; i < tasks.length; i++) { task = tasks[i]; - // there are just removals in the task queue + if (task.clear) { await this.clear(); _replace = !0; @@ -504,7 +452,7 @@ ClickhouseDB.prototype.commit = async function (flexsearch, _replace, _append) { for (let i = 0, ids; i < arr.length; i++) { if ((ids = arr[i]) && ids.length) { - //this.type || (this.type = typeof ids[0]); + for (let j = 0; j < ids.length; j++) { data.push({ key: key, @@ -590,25 +538,6 @@ ClickhouseDB.prototype.commit = async function (flexsearch, _replace, _append) { } } - // TODO - // await this.db.insert(`INSERT INTO ${this.id}.cfg${this.field} (cfg)`, [{ - // cfg: JSON.stringify({ - // "encode": typeof flexsearch.encode === "string" ? flexsearch.encode : "", - // "charset": typeof flexsearch.charset === "string" ? flexsearch.charset : "", - // "tokenize": flexsearch.tokenize, - // "resolution": flexsearch.resolution, - // "minlength": flexsearch.minlength, - // "optimize": flexsearch.optimize, - // "fastupdate": flexsearch.fastupdate, - // "encoder": flexsearch.encoder, - // "context": { - // "depth": flexsearch.depth, - // "bidirectional": flexsearch.bidirectional, - // "resolution": flexsearch.resolution_ctx - // } - // }) - // }]).toPromise(); - promises.length && (await Promise.all(promises)); flexsearch.map.clear(); diff --git a/dist/module/db/indexeddb/index.js b/dist/module/db/indexeddb/index.js index 00c56e5..23e2493 100644 --- a/dist/module/db/indexeddb/index.js +++ b/dist/module/db/indexeddb/index.js @@ -48,7 +48,7 @@ export default function IdxDB(name, config = {}) { } IdxDB.prototype.mount = function (flexsearch) { - //if(flexsearch.constructor === Document){ + if (flexsearch.index) { return flexsearch.mount(this); } @@ -63,8 +63,6 @@ IdxDB.prototype.open = function () { navigator.storage && navigator.storage.persist(); - // return this.db = new Promise(function(resolve, reject){ - Index[self.id] || (Index[self.id] = []); Index[self.id].push(self.field); @@ -75,60 +73,22 @@ IdxDB.prototype.open = function () { const db = self.db = this.result; - // Using Indexes + IDBKeyRange on schema map => [key, res, id] performs - // too bad and blows up amazingly in size - // The schema map:key => [res][id] is currently used instead - // In fact that bypass the idea of a storage solution, - // IndexedDB is such a poor contribution :( for (let i = 0, ref; i < fields.length; i++) { ref = fields[i]; for (let j = 0, field; j < Index[self.id].length; j++) { field = Index[self.id][j]; - db.objectStoreNames.contains(ref + ("reg" !== ref ? field ? ":" + field : "" : "")) || db.createObjectStore(ref + ("reg" !== ref ? field ? ":" + field : "" : "")); //{ autoIncrement: true /*keyPath: "id"*/ } - //.createIndex("idx", "ids", { multiEntry: true, unique: false }); + db.objectStoreNames.contains(ref + ("reg" !== ref ? field ? ":" + field : "" : "")) || db.createObjectStore(ref + ("reg" !== ref ? field ? ":" + field : "" : "")); } } - - // switch(event.oldVersion){ // existing db version - // case 0: - // // version 0 means that the client had no database - // // perform initialization - // case 1: - // // client had version 1 - // // update - // } }; return self.db = promisfy(req, function (result) { - self.db = result; //event.target.result; + self.db = result; self.db.onversionchange = function () { - //database is outdated + self.close(); }; }); - - // req.onblocked = function(event) { - // // this event shouldn't trigger if we handle onversionchange correctly - // // it means that there's another open connection to the same database - // // and it wasn't closed after db.onversionchange triggered for it - // console.error("blocked", event); - // reject(); - // }; - // - // req.onerror = function(event){ - // console.error(this.error, event); - // reject(); - // }; - // - // req.onsuccess = function(event){ - // self.db = this.result; //event.target.result; - // self.db.onversionchange = function(){ - // //database is outdated - // self.close(); - // }; - // resolve(self); - // }; - // }); }; IdxDB.prototype.close = function () { @@ -144,20 +104,6 @@ IdxDB.prototype.destroy = function () { return promisfy(req); }; -// IdxDB.prototype.set = function(ref, key, ctx, data){ -// const transaction = this.db.transaction(ref, "readwrite"); -// const map = transaction.objectStore(ref); -// const req = map.put(data, ctx ? ctx + ":" + key : key); -// return transaction;//promisfy(req, callback); -// }; - -// IdxDB.prototype.delete = function(ref, key, ctx){ -// const transaction = this.db.transaction(ref, "readwrite"); -// const map = transaction.objectStore(ref); -// const req = map.delete(ctx ? ctx + ":" + key : key); -// return transaction;//promisfy(req, callback); -// }; - /** * @return {!Promise} */ @@ -190,7 +136,7 @@ IdxDB.prototype.clear = function () { * @param {boolean=} enrich * @return {!Promise} */ -IdxDB.prototype.get = function (key, ctx, limit = 0, offset = 0, resolve = /* tag? */!0, enrich = !1) { +IdxDB.prototype.get = function (key, ctx, limit = 0, offset = 0, resolve = !0, enrich = !1) { const transaction = this.db.transaction((ctx ? "ctx" : "map") + (this.field ? ":" + this.field : ""), "readonly"), map = transaction.objectStore((ctx ? "ctx" : "map") + (this.field ? ":" + this.field : "")), req = map.get(ctx ? ctx + ":" + key : key), @@ -290,16 +236,7 @@ IdxDB.prototype.has = function (id) { IdxDB.prototype.search = null; -// IdxDB.prototype.has = function(ref, key, ctx){ -// const transaction = this.db.transaction(ref, "readonly"); -// const map = transaction.objectStore(ref); -// const req = map.getKey(ctx ? ctx + ":" + key : key); -// return promisfy(req); -// }; - -IdxDB.prototype.info = function () { - // todo -}; +IdxDB.prototype.info = function () {}; /** * @param {!string} ref @@ -327,33 +264,13 @@ IdxDB.prototype.transaction = function (ref, modifier, task) { transaction = store = null; return promise; }); - - // return new Promise((resolve, reject) => { - // transaction.onerror = (err) => { - // transaction.abort(); - // transaction = store = null; - // reject(err); - // //db.close; - // }; - // transaction.oncomplete = (res) => { - // transaction = store = null; - // resolve(res || true); - // //db.close; - // }; - // const promise = task.call(this, store); - // // transactions can just be used within the same event loop - // // the indexeddb is such a stupid tool :( - // this.trx[key + ":" + modifier] = null; - // return promise; - // }); }; IdxDB.prototype.commit = async function (flexsearch, _replace, _append) { - // process cleanup tasks if (_replace) { await this.clear(); - // there are just removals in the task queue + flexsearch.commit_task = []; } else { let tasks = flexsearch.commit_task; @@ -361,7 +278,7 @@ IdxDB.prototype.commit = async function (flexsearch, _replace, _append) { for (let i = 0, task; i < tasks.length; i++) { /** @dict */ task = tasks[i]; - // there are just removals in the task queue + if (task.clear) { await this.clear(); _replace = !0; @@ -410,23 +327,15 @@ IdxDB.prototype.commit = async function (flexsearch, _replace, _append) { res.push(val[j]); } changed = 1; - //result[i] = res.concat(val); - //result[i] = new Set([...result[i], ...value[i]]); - //result[i] = result[i].union(new Set(value[i])); } else { result[i] = val; changed = 1; - //result[i] = new Set(value[i]) } } } } else { result = value; changed = 1; - //result = []; - //for(let i = 0; i < value.length; i++){ - // if(value[i]) result[i] = new Set(value[i]); - //} } changed && store.put(result, key); @@ -466,7 +375,7 @@ IdxDB.prototype.commit = async function (flexsearch, _replace, _append) { for (let j = 0; j < val.length; j++) { res.push(val[j]); } - //result[i] = res.concat(val); + changed = 1; } else { result[i] = val; @@ -519,25 +428,6 @@ IdxDB.prototype.commit = async function (flexsearch, _replace, _append) { }); } - // TODO - // await this.transaction("cfg", "readwrite", function(store){ - // store.put({ - // "charset": flexsearch.charset, - // "tokenize": flexsearch.tokenize, - // "resolution": flexsearch.resolution, - // "fastupdate": flexsearch.fastupdate, - // "compress": flexsearch.compress, - // "encoder": { - // "minlength": flexsearch.encoder.minlength - // }, - // "context": { - // "depth": flexsearch.depth, - // "bidirectional": flexsearch.bidirectional, - // "resolution": flexsearch.resolution_ctx - // } - // }, "current"); - // }); - flexsearch.map.clear(); flexsearch.ctx.clear(); @@ -562,7 +452,7 @@ function handle(cursor, ids, _tag) { for (let x = 0, result; x < arr.length; x++) { - // tags has no resolution layer + if (result = _tag ? arr : arr[x]) { for (let i = 0, pos, id; i < ids.length; i++) { id = ids[i]; @@ -585,11 +475,9 @@ function handle(cursor, ids, _tag) { if (!count) { cursor.delete(); - //store.delete(cursor.key); } else if (changed) { - //await new Promise(resolve => { - cursor.update(arr); //.onsuccess = resolve; - //}); + + cursor.update(arr); } cursor.continue(); @@ -622,31 +510,11 @@ IdxDB.prototype.remove = function (ids) { const cursor = this.result; cursor && handle(cursor, ids, !0); }; - }), - // let filtered = []; - self.transaction("reg", "readwrite", function (store) { + }), self.transaction("reg", "readwrite", function (store) { for (let i = 0; i < ids.length; i++) { store.delete(ids[i]); } - // return new Promise(resolve => { - // store.openCursor().onsuccess = function(){ - // const cursor = this.result; - // if(cursor){ - // const id = cursor.value; - // if(ids.includes(id)){ - // filtered.push(id); - // cursor.delete(); - // } - // cursor.continue(); - // } - // else{ - // resolve(); - // } - // }; - // }); - }) - // ids = filtered; - ]) + })]) ); }; @@ -658,7 +526,7 @@ IdxDB.prototype.remove = function (ids) { function promisfy(req, callback) { return new Promise((resolve, reject) => { - // oncomplete is used for transaction + /** @this {IDBRequest|IDBOpenDBRequest} */ req.onsuccess = req.oncomplete = function () { callback && callback(this.result); diff --git a/dist/module/db/interface.js b/dist/module/db/interface.js index 5c8ef90..cc9b8ae 100644 --- a/dist/module/db/interface.js +++ b/dist/module/db/interface.js @@ -5,22 +5,14 @@ */ export default function StorageInterface() {} -// Mandatory Initializer -// ------------------------------ - -// assign store to an index StorageInterface.prototype.mount = async function () {}; -// open connection + StorageInterface.prototype.open = async function () {}; -// close connection + StorageInterface.prototype.close = function () {}; -// drop the database (drop tables) + StorageInterface.prototype.destroy = async function () {}; -// Mandatory Query Tasks -// ------------------------------ - -// transfer all changes of an index to the database StorageInterface.prototype.commit = async function () {}; /** * get results of a term "key" with optional context "ctx" @@ -39,15 +31,12 @@ StorageInterface.prototype.get = async function () {}; * @return {!Promise} */ StorageInterface.prototype.enrich = async function () {}; -// check if id exists on a specific index -StorageInterface.prototype.has = async function () {}; -// delete one id or multiple ids on a specific index -StorageInterface.prototype.remove = async function () {}; -// clear all data (truncate) -StorageInterface.prototype.clear = async function () {}; -// Optional Methods -// ------------------------------ +StorageInterface.prototype.has = async function () {}; + +StorageInterface.prototype.remove = async function () {}; + +StorageInterface.prototype.clear = async function () {}; /** * Perform the query intersection on database side diff --git a/dist/module/db/mongodb/index.js b/dist/module/db/mongodb/index.js index 59d4259..79b65f9 100644 --- a/dist/module/db/mongodb/index.js +++ b/dist/module/db/mongodb/index.js @@ -40,17 +40,13 @@ export default function MongoDB(name, config = {}) { this.type = config.type || ""; this.db = config.db || Index[this.id] || CLIENT || null; this.trx = !1; - this.support_tag_search = /* tag? */!0 /*await rows.hasNext()*/ /*await rows.hasNext()*/ /*await rows.hasNext()*/; + this.support_tag_search = !0; Object.assign(defaults, config); this.db && delete defaults.db; } -// MongoDB.mount = function(flexsearch){ -// return new this().mount(flexsearch); -// }; - MongoDB.prototype.mount = function (flexsearch) { - //if(flexsearch.constructor === Document){ + if (flexsearch.index) { return flexsearch.mount(this); } @@ -124,7 +120,7 @@ MongoDB.prototype.open = async function () { }; MongoDB.prototype.close = function () { - //CLIENT && CLIENT.close(); + this.db = CLIENT = null; Index[this.id] = null; return this; @@ -291,7 +287,7 @@ MongoDB.prototype.search = async function (flexsearch, query, limit = 100, offse const stmt = [{ $match: { $or: params } }, { $group: { _id: "$id", count: { $sum: 1 }, - res: suggest ? { $sum: "$res" } : { $sum /*$min*/: "$res" } + res: suggest ? { $sum: "$res" } : { $sum: "$res" } } }]; suggest || stmt.push({ $match: { count: query.length - 1 } }); @@ -324,19 +320,11 @@ MongoDB.prototype.search = async function (flexsearch, query, limit = 100, offse count++; } - stmt.push( - //{ $project: project }, - { $match: match }); + stmt.push({ $match: match }); } stmt.push({ $sort: suggest ? { count: -1, res: 1 } : { res: 1 } }, { $skip: offset }, { $limit: limit }); - // if(tags){ - // project = { _id: 1 }; - // if(!resolve) project["res"] = 1; - // if(enrich) project["doc"] = 1; - // } - stmt.push({ $project: project }); rows = await this.db.collection("ctx" + this.field).aggregate(stmt); @@ -351,7 +339,7 @@ MongoDB.prototype.search = async function (flexsearch, query, limit = 100, offse } }, { $group: { _id: "$id", count: { $sum: 1 }, - res: suggest ? { $sum: "$res" } : { $sum /*$min*/: "$res" } + res: suggest ? { $sum: "$res" } : { $sum: "$res" } } }]; suggest || stmt.push({ $match: { count: query.length } }); @@ -384,19 +372,11 @@ MongoDB.prototype.search = async function (flexsearch, query, limit = 100, offse count++; } - stmt.push( - //{ $project: project }, - { $match: match }); + stmt.push({ $match: match }); } stmt.push({ $sort: suggest ? { count: -1, res: 1 } : { res: 1 } }, { $skip: offset }, { $limit: limit }); - // if(tags){ - // project = { _id: 1 }; - // if(!resolve) project["res"] = 1; - // if(enrich) project["doc"] = 1; - // } - stmt.push({ $project: project }); rows = await this.db.collection("map" + this.field).aggregate(stmt); @@ -422,28 +402,25 @@ MongoDB.prototype.search = async function (flexsearch, query, limit = 100, offse } }; -MongoDB.prototype.info = function () { - // todo -}; +MongoDB.prototype.info = function () {}; MongoDB.prototype.transaction = function (task) { - // not supported + return task.call(this); }; MongoDB.prototype.commit = async function (flexsearch, _replace, _append) { - // process cleanup tasks if (_replace) { await this.clear(); - // there are just removals in the task queue + flexsearch.commit_task = []; } else { let tasks = flexsearch.commit_task; flexsearch.commit_task = []; for (let i = 0, task; i < tasks.length; i++) { task = tasks[i]; - // there are just removals in the task queue + if (task.clear) { await this.clear(); _replace = !0; @@ -559,23 +536,6 @@ MongoDB.prototype.commit = async function (flexsearch, _replace, _append) { flexsearch.tag && flexsearch.tag.clear(); flexsearch.store && flexsearch.store.clear(); flexsearch.document || flexsearch.reg.clear(); - - // TODO - // await this.db.collection("cfg" + this.field).insertOne({ - // "encode": typeof flexsearch.encode === "string" ? flexsearch.encode : "", - // "charset": typeof flexsearch.charset === "string" ? flexsearch.charset : "", - // "tokenize": flexsearch.tokenize, - // "resolution": flexsearch.resolution, - // "minlength": flexsearch.minlength, - // "optimize": flexsearch.optimize, - // "fastupdate": flexsearch.fastupdate, - // "encoder": flexsearch.encoder, - // "context": { - // "depth": flexsearch.depth, - // "bidirectional": flexsearch.bidirectional, - // "resolution": flexsearch.resolution_ctx - // } - // }); }; MongoDB.prototype.remove = function (ids) { @@ -585,9 +545,5 @@ MongoDB.prototype.remove = function (ids) { ids = [ids]; } - // if(this.type !== "string" && typeof ids[0] !== "number"){ - // ids = ids.map(item => parseInt(item, 10)); - // } - return Promise.all([this.db.collection("map" + this.field).deleteMany({ id: { $in: ids } }), this.db.collection("ctx" + this.field).deleteMany({ id: { $in: ids } }), this.db.collection("tag" + this.field).deleteMany({ id: { $in: ids } }), this.db.collection("reg").deleteMany({ id: { $in: ids } })]); }; \ No newline at end of file diff --git a/dist/module/db/postgres/index.js b/dist/module/db/postgres/index.js index 5efc5ea..4582514 100644 --- a/dist/module/db/postgres/index.js +++ b/dist/module/db/postgres/index.js @@ -61,7 +61,7 @@ export default function PostgresDB(name, config = {}) { this.id = (config.schema ? sanitize(config.schema) : defaults.schema) + (name ? "_" + sanitize(name) : ""); this.field = config.field ? "_" + sanitize(config.field) : ""; this.type = config.type ? types[config.type.toLowerCase()] : "text"; - this.support_tag_search = /* tag? */!0 /*await rows.hasNext()*/ /*await rows.hasNext()*/ /*await rows.hasNext()*/; + this.support_tag_search = !0; if (!this.type) throw new Error("Unknown type of ID '" + config.type + "'"); this.db = DB || (DB = config.db || null); Object.assign(defaults, config); @@ -69,7 +69,7 @@ export default function PostgresDB(name, config = {}) { } PostgresDB.prototype.mount = function (flexsearch) { - //if(flexsearch.constructor === Document){ + if (flexsearch.index) { return flexsearch.mount(this); } @@ -156,10 +156,7 @@ PostgresDB.prototype.open = async function () { PRIMARY KEY, doc text DEFAULT NULL ); - `).catch(() => { - // document indexes will try to create same registry table - // and the "IF NOT EXISTS" did not apply on parallel - }); + `).catch(() => {}); break; case "cfg": @@ -176,8 +173,8 @@ PostgresDB.prototype.open = async function () { }; PostgresDB.prototype.close = function () { - //DB && DB.close && DB.close(); - this.db = /*DB =*/null; + + this.db = null; return this; }; @@ -332,7 +329,6 @@ PostgresDB.prototype.search = function (flexsearch, query, limit = 100, offset = term, count = 1; - // variant new for (let i = 1; i < query.length; i++) { term = query[i]; @@ -356,7 +352,7 @@ PostgresDB.prototype.search = function (flexsearch, query, limit = 100, offset = ${enrich ? ", doc" : ""} FROM ( SELECT id, count(*) as count, - ${suggest ? "SUM" : "SUM" /*"MIN"*/}(res) as res + ${suggest ? "SUM" : "SUM"}(res) as res FROM ${this.id}.ctx${this.field} WHERE ${where} GROUP BY id @@ -369,36 +365,6 @@ PostgresDB.prototype.search = function (flexsearch, query, limit = 100, offset = ${limit ? "LIMIT " + limit : ""} ${offset ? "OFFSET " + offset : ""} `, params); - - // variant 1 - - // for(let i = 1, count = 1; i < query.length; i++){ - // where += (where ? " UNION " : "") + ` - // SELECT id, res - // FROM ${this.id}.ctx${this.field} - // WHERE ctx = $${count++} AND key = $${count++} - // `; - // term = query[i]; - // const swap = flexsearch.bidirectional && (term > keyword); - // params.push( - // swap ? term : keyword, - // swap ? keyword : term - // ); - // keyword = term; - // } - // - // rows = await db.any(` - // SELECT id, res - // FROM ( - // SELECT id, ${suggest ? "SUM" : "MIN"}(res) as res, count(*) as count - // FROM (${where}) as t - // GROUP BY id - // ORDER BY ${suggest ? "count DESC, res" : "res"} - // LIMIT ${limit} - // OFFSET ${offset} - // ) as r - // ${suggest ? "" : "WHERE count = " + (query.length - 1)} - // `, params); } else { let where = "", count = 1, @@ -423,7 +389,7 @@ PostgresDB.prototype.search = function (flexsearch, query, limit = 100, offset = ${enrich ? ", doc" : ""} FROM ( SELECT id, count(*) as count, - ${suggest ? "SUM" : "SUM" /*"MIN"*/}(res) as res + ${suggest ? "SUM" : "SUM"}(res) as res FROM ${this.id}.map${this.field} WHERE ${where} GROUP BY id @@ -436,67 +402,6 @@ PostgresDB.prototype.search = function (flexsearch, query, limit = 100, offset = ${limit ? "LIMIT " + limit : ""} ${offset ? "OFFSET " + offset : ""} `, query); - - // variant 1 - // for(let i = 1; i <= query.length; i++){ - // where += (where ? " UNION " : "") + ` - // SELECT id, res - // FROM ${ this.id }.map${ this.field } - // WHERE key = $${i} - // `; - // } - // rows = await db.any(` - // SELECT id, res - // FROM ( - // SELECT id, ${suggest ? "SUM" : "MIN"}(res) as res, count(*) as count - // FROM (${where}) as t - // GROUP BY id - // ORDER BY ${suggest ? "count DESC, res" : "res"} - // LIMIT ${limit} - // OFFSET ${offset} - // ) as r - // ${ suggest ? "" : "WHERE count = " + query.length } - // `, query); - - // variant 2 - // for(let i = 1; i <= query.length; i++){ - // where += (where ? " AND EXISTS " : "") + `(SELECT FROM ${this.id}.map${this.field} as d WHERE d.id = t.id AND d.key = $` + i + ")"; - // } - // rows = await db.any(` - // SELECT t.id, min(t.res) - // FROM ${this.id}.map${this.field} AS t - // WHERE EXISTS ${where} - // GROUP BY t.id - // LIMIT ${limit || 100} - // OFFSET ${offset || 0} - // `, query); - - // variant 3 - // for(let i = 1; i <= query.length; i++){ - // where += (where ? " INTERSECT " : "") + `SELECT id FROM ${this.id}.map${this.field} WHERE key = $` + i; - // } - // rows = await db.any(` - // WITH filtering (id) AS(${where}) - // SELECT t.id, min(t.res) - // FROM ${this.id}.map${this.field} AS t - // JOIN filtering USING (id) - // GROUP BY t.id - // LIMIT ${limit || 100} - // OFFSET ${offset || 0} - // `, query); - - // variant 4 - // for(let i = 1; i <= query.length; i++){ - // where += (where ? " INTERSECT " : "") + `SELECT id FROM ${this.id}.map${this.field} WHERE key = $` + i; - // } - // rows = await db.any(` - // SELECT id, min(res) - // FROM ${this.id}.map${this.field} - // WHERE id IN (${where}) - // GROUP BY id - // LIMIT ${limit || 100} - // OFFSET ${offset || 0} - // `, query); } return rows.then(function (rows) { @@ -504,23 +409,7 @@ PostgresDB.prototype.search = function (flexsearch, query, limit = 100, offset = }); }; -PostgresDB.prototype.info = function () { - // todo -}; - -// PostgresDB.prototype.transaction = async function(task){ -// const self = this; -// if(TRX){ -// return TRX.then(function(){ -// return self.transaction(task); -// //task.call(self, TRX); -// }); -// } -// TRX = await this.db.tx(async function(trx){ -// await task.call(self, trx); -// }); -// TRX = null; -// }; +PostgresDB.prototype.info = function () {}; PostgresDB.prototype.transaction = function (task) { const self = this; @@ -529,30 +418,18 @@ PostgresDB.prototype.transaction = function (task) { }); }; -// PostgresDB.prototype.transaction = async function(task){ -// if(TRX){ -// return await task.call(this, TRX); -// } -// const self = this; -// return this.db.tx(async function(trx){ -// await task.call(self, TRX = trx); -// TRX = null; -// }); -// }; - PostgresDB.prototype.commit = async function (flexsearch, _replace, _append) { - // process cleanup tasks if (_replace) { await this.clear(); - // there are just removals in the task queue + flexsearch.commit_task = []; } else { let tasks = flexsearch.commit_task; flexsearch.commit_task = []; for (let i = 0, task; i < tasks.length; i++) { task = tasks[i]; - // there are just removals in the task queue + if (task.clear) { await this.clear(); _replace = !0; @@ -567,8 +444,6 @@ PostgresDB.prototype.commit = async function (flexsearch, _replace, _append) { } tasks.length && (await this.remove(tasks)); } - - //console.log("tasks:", tasks) } if (!flexsearch.reg.size) { @@ -579,8 +454,6 @@ PostgresDB.prototype.commit = async function (flexsearch, _replace, _append) { const batch = []; - // Datastore + Registry - if (flexsearch.store) { let data = [], stmt = new pgp.helpers.ColumnSet(["id", "doc"], { @@ -591,8 +464,7 @@ PostgresDB.prototype.commit = async function (flexsearch, _replace, _append) { const id = item[0], doc = item[1]; - // const migration = checkMigration.call(this, id); - // migration && await migration; + data.push({ id, doc: doc && JSON.stringify(doc) }); if (data.length === MAXIMUM_QUERY_VARS) { let insert = pgp.helpers.insert(data, stmt); @@ -604,44 +476,26 @@ PostgresDB.prototype.commit = async function (flexsearch, _replace, _append) { let insert = pgp.helpers.insert(data, stmt); batch.push(trx.none(insert.replace(/^(insert into )"([^"]+)"/, '$1 $2'))); } - // while(data.length){ - // let next; - // if(data.length > MAXIMUM_QUERY_VARS){ - // next = data.slice(MAXIMUM_QUERY_VARS); - // data = data.slice(0, MAXIMUM_QUERY_VARS); - // } - // let insert = pgp.helpers.insert(data, stmt); - // trx.none(insert.replace(/^(insert into )"([^"]+)"/, '$1 $2')); - // if(next) data = next; - // else break; - // } - } + } else if (!flexsearch.bypass) { + let data = [], + stmt = new pgp.helpers.ColumnSet(["id"], { + table: this.id + ".reg" + }); - // Registry Only + for (const id of flexsearch.reg.keys()) { - else if (!flexsearch.bypass) { - let data = [], - stmt = new pgp.helpers.ColumnSet(["id"], { - table: this.id + ".reg" - }); - - for (const id of flexsearch.reg.keys()) { - // const migration = checkMigration.call(this, id); - // migration && await migration; - data.push({ id }); - if (data.length === MAXIMUM_QUERY_VARS) { - let insert = pgp.helpers.insert(data, stmt); - batch.push(trx.none(insert.replace(/^(insert into )"([^"]+)"/, '$1 $2'))); - data = []; - } - } - if (data.length) { + data.push({ id }); + if (data.length === MAXIMUM_QUERY_VARS) { let insert = pgp.helpers.insert(data, stmt); batch.push(trx.none(insert.replace(/^(insert into )"([^"]+)"/, '$1 $2'))); + data = []; } } - - // Default Index + if (data.length) { + let insert = pgp.helpers.insert(data, stmt); + batch.push(trx.none(insert.replace(/^(insert into )"([^"]+)"/, '$1 $2'))); + } + } if (flexsearch.map.size) { let data = [], @@ -656,13 +510,9 @@ PostgresDB.prototype.commit = async function (flexsearch, _replace, _append) { for (let i = 0, ids; i < arr.length; i++) { if ((ids = arr[i]) && ids.length) { - //this.type || (this.type = typeof ids[0]); - // let stmt = "($1,$2,$3)"; - // let params = [key, i, ids[0]]; + for (let j = 0; j < ids.length; j++) { - // stmt += ",($1,$2,$3)"; - // params.push(key, i, ids[j]); - //trx.none(`INSERT INTO ${config.schema}.map${self.field} (key, res, id) VALUES ($1,$2,$3)`, [key, i, ids[j]]); + data.push({ key: key, res: i, @@ -683,8 +533,6 @@ PostgresDB.prototype.commit = async function (flexsearch, _replace, _append) { } } - // Context Index - if (flexsearch.ctx.size) { let data = [], stmt = new pgp.helpers.ColumnSet(["ctx", "key", "res", "id"], { @@ -703,12 +551,9 @@ PostgresDB.prototype.commit = async function (flexsearch, _replace, _append) { for (let i = 0, ids; i < arr.length; i++) { if ((ids = arr[i]) && ids.length) { - // let stmt = "(?,?,?)"; - // let params = [ctx_key + ":" + key, i, ids[0]]; + for (let j = 0; j < ids.length; j++) { - // stmt += ",(?,?,?)"; - // params.push(ctx_key + ":" + key, i, ids[j]); - //trx.none("INSERT INTO " + config.schema + ".ctx" + self.field + " (ctx, key, res, id) VALUES ($1,$2,$3,$4)", [ctx_key, key, i, ids[j]]); + data.push({ ctx: ctx_key, key: key, @@ -731,8 +576,6 @@ PostgresDB.prototype.commit = async function (flexsearch, _replace, _append) { } } - // Tag Index - if (flexsearch.tag) { let data = [], stmt = new pgp.helpers.ColumnSet(["tag", "id"], { @@ -759,29 +602,6 @@ PostgresDB.prototype.commit = async function (flexsearch, _replace, _append) { } } - // Field Configuration - - // TODO - // trx.none("INSERT INTO " + this.id + ".cfg" + this.field + " (cfg) VALUES ($1)", [ - // JSON.stringify({ - // "encode": typeof flexsearch.encode === "string" ? flexsearch.encode : "", - // "charset": typeof flexsearch.charset === "string" ? flexsearch.charset : "", - // "tokenize": flexsearch.tokenize, - // "resolution": flexsearch.resolution, - // "minlength": flexsearch.minlength, - // "optimize": flexsearch.optimize, - // "fastupdate": flexsearch.fastupdate, - // "encoder": flexsearch.encoder, - // "context": { - // "depth": flexsearch.depth, - // "bidirectional": flexsearch.bidirectional, - // "resolution": flexsearch.resolution_ctx - // } - // }) - // ]); - - //return Promise.all(batch); - if (batch.length) { return trx.batch(batch); } @@ -806,171 +626,9 @@ PostgresDB.prototype.remove = function (ids) { return; } - // ids = [ids]; - // return this.db.none( - // "DELETE FROM " + this.id + ".map" + this.field + " WHERE id = ANY ($1);" + - // "DELETE FROM " + this.id + ".ctx" + this.field + " WHERE id = ANY ($1);" + - // "DELETE FROM " + this.id + ".tag" + this.field + " WHERE id = ANY ($1);" + - // "DELETE FROM " + this.id + ".reg WHERE id = ANY ($1);", [ids] - // ); - - // ids = [ids]; - // return Promise.all([ - // this.db.none({ text: "DELETE FROM " + this.id + ".map" + this.field + " WHERE id = ANY ($1)", rowMode: "array" }, ids), - // this.db.none({ text: "DELETE FROM " + this.id + ".ctx" + this.field + " WHERE id = ANY ($1)", rowMode: "array" }, ids), - // this.db.none({ text: "DELETE FROM " + this.id + ".tag" + this.field + " WHERE id = ANY ($1)", rowMode: "array" }, ids), - // this.db.none({ text: "DELETE FROM " + this.id + ".reg WHERE id = ANY ($1)", rowMode: "array" }, ids) - // ]); - return this.transaction(function (trx) { - //console.log("remove:", ids); - - // ids = [ids]; - // trx.none({ text: "DELETE FROM " + this.id + ".map" + this.field + " WHERE id = ANY ($1)", rowMode: "array" }, ids); - // trx.none({ text: "DELETE FROM " + this.id + ".ctx" + this.field + " WHERE id = ANY ($1)", rowMode: "array" }, ids); - // trx.none({ text: "DELETE FROM " + this.id + ".tag" + this.field + " WHERE id = ANY ($1)", rowMode: "array" }, ids); - // trx.none({ text: "DELETE FROM " + this.id + ".reg WHERE id = ANY ($1)", rowMode: "array" }, ids); - - // ids = [ids]; - // trx.none("DELETE FROM " + this.id + ".map" + this.field + " WHERE id = ANY ($1)", ids); - // trx.none("DELETE FROM " + this.id + ".ctx" + this.field + " WHERE id = ANY ($1)", ids); - // trx.none("DELETE FROM " + this.id + ".tag" + this.field + " WHERE id = ANY ($1)", ids); - // trx.none("DELETE FROM " + this.id + ".reg WHERE id = ANY ($1)", ids); - // return; - - // return trx.none( - // "DELETE FROM " + this.id + ".map" + this.field + " WHERE id = ANY ($1);" + - // "DELETE FROM " + this.id + ".ctx" + this.field + " WHERE id = ANY ($1);" + - // "DELETE FROM " + this.id + ".tag" + this.field + " WHERE id = ANY ($1);" + - // "DELETE FROM " + this.id + ".reg WHERE id = ANY ($1);", [ids] - // ); - - // while(ids.length){ - // let next; - // let stmt = ""; - // let chunk = 0; - // let migration; - // for(let i = 0; i < ids.length; i++){ - // stmt += (stmt ? "," : "") + "$" + (i + 1); // + "::text"; - // // maximum count of variables supported - // if(++chunk === MAXIMUM_QUERY_VARS){ - // next = ids.slice(MAXIMUM_QUERY_VARS); - // ids = ids.slice(0, MAXIMUM_QUERY_VARS); - // break; - // } - // } - // - // trx.batch([ - // trx.none("DELETE FROM " + this.id + ".map" + this.field + " WHERE id IN (" + stmt + ")", ids), - // trx.none("DELETE FROM " + this.id + ".ctx" + this.field + " WHERE id IN (" + stmt + ")", ids), - // trx.none("DELETE FROM " + this.id + ".tag" + this.field + " WHERE id IN (" + stmt + ")", ids), - // trx.none("DELETE FROM " + this.id + ".reg WHERE id IN (" + stmt + ")", ids) - // ]); - // - // // trx.none( - // // "DELETE FROM " + this.id + ".map" + this.field + " WHERE id IN (" + stmt + ");" + - // // "DELETE FROM " + this.id + ".ctx" + this.field + " WHERE id IN (" + stmt + ");" + - // // "DELETE FROM " + this.id + ".tag" + this.field + " WHERE id IN (" + stmt + ");" + - // // "DELETE FROM " + this.id + ".reg WHERE id IN (" + stmt + ");", ids - // // ); - // - // if(next) ids = next; - // else break; - // } - ids = [ids]; return trx.batch([trx.none({ text: "DELETE FROM " + this.id + ".map" + this.field + " WHERE id = ANY ($1)", rowMode: "array" }, ids), trx.none({ text: "DELETE FROM " + this.id + ".ctx" + this.field + " WHERE id = ANY ($1)", rowMode: "array" }, ids), trx.none({ text: "DELETE FROM " + this.id + ".tag" + this.field + " WHERE id = ANY ($1)", rowMode: "array" }, ids), trx.none({ text: "DELETE FROM " + this.id + ".reg WHERE id = ANY ($1)", rowMode: "array" }, ids)]); - - // ids = [ids]; - // return trx.batch([ - // trx.none("DELETE FROM " + this.id + ".map" + this.field + " WHERE id = ANY ($1)", ids), - // trx.none("DELETE FROM " + this.id + ".ctx" + this.field + " WHERE id = ANY ($1)", ids), - // trx.none("DELETE FROM " + this.id + ".tag" + this.field + " WHERE id = ANY ($1)", ids), - // trx.none("DELETE FROM " + this.id + ".reg WHERE id = ANY ($1)", ids) - // ]); - - // return trx.batch([ - // trx.none("DELETE FROM " + this.id + ".map" + this.field + " WHERE id IN ($1:csv)", [ids]), - // trx.none("DELETE FROM " + this.id + ".ctx" + this.field + " WHERE id IN ($1:csv)", [ids]), - // trx.none("DELETE FROM " + this.id + ".tag" + this.field + " WHERE id IN ($1:csv)", [ids]), - // trx.none("DELETE FROM " + this.id + ".reg WHERE id IN ($1:csv)", [ids]) - // ]); - - // const type = self.type === "text" ? "text" : "int"; - // return trx.batch([ - // trx.none("DELETE FROM " + this.id + ".map" + self.field + " WHERE id = ANY($1::" + type + "[])", [ids]), - // trx.none("DELETE FROM " + this.id + ".ctx" + self.field + " WHERE id = ANY($1::" + type + "[])", [ids]), - // trx.none("DELETE FROM " + this.id + ".reg WHERE id = ANY($1::" + type + "[])", [ids]) - // ]); - - // return trx.batch([ - // trx.none("DELETE FROM " + this.id + ".map" + self.field + " WHERE id = ANY($1)", [ids]), - // trx.none("DELETE FROM " + this.id + ".ctx" + self.field + " WHERE id = ANY($1)", [ids]), - // trx.none("DELETE FROM " + this.id + ".reg WHERE id = ANY($1)", [ids]) - // ]); }); -}; - -// if(this.type === "int" && typeof ids[0] === "string"){ -// ids = ids.map(item => parseInt(item, 10)); -// } -// if(this.type === "bigint" && typeof ids[0] === "string"){ -// ids = ids.map(item => BigInt(item)); -// } -// if(this.type === "string" && typeof ids[0] === "number"){ -// ids = ids.map(item => item + ""); -// } -// this.type !== "string" && checkMigration.call(this, ids[0]); - -// function checkMigration(id){ -// if(this.type !== "string"){ -// if(typeof id === "object"){ -// id = id[0]; -// } -// if(typeof id === "string"){ -// this.type = "string"; -// return upgradeTextId.call(this); -// } -// if(this.type !== "bigint"){ -// if(id > 2 ** 31 - 1){ -// this.type = "bigint"; -// return upgradeBigIntId.call(this); -// } -// } -// } -// } -// -// function upgradeTextId(){ -// return this.db.none(` -// ALTER TABLE ${this.id}.map${this.field} -// ALTER COLUMN id type varchar(128) -// USING id::text; -// ALTER TABLE ${this.id}.ctx${this.field} -// ALTER COLUMN id type varchar(128) -// USING id::text; -// ALTER TABLE ${this.id}.tag${this.field} -// ALTER COLUMN id type varchar(128) -// USING id::text; -// ALTER TABLE ${this.id}.reg -// ALTER COLUMN id type varchar(128) -// USING id::text; -// `); -// } -// -// function upgradeBigIntId(){ -// return this.db.none(` -// ALTER TABLE ${this.id}.map${this.field} -// ALTER COLUMN id type bigint -// USING id::bigint; -// ALTER TABLE ${this.id}.ctx${this.field} -// ALTER COLUMN id type bigint -// USING id::bigint; -// ALTER TABLE ${this.id}.tag${this.field} -// ALTER COLUMN id type bigint -// USING id::bigint; -// ALTER TABLE ${this.id}.reg -// ALTER COLUMN id type bigint -// USING id::bigint; -// `); -// } \ No newline at end of file +}; \ No newline at end of file diff --git a/dist/module/db/redis/index.js b/dist/module/db/redis/index.js index 96d59c0..ba09779 100644 --- a/dist/module/db/redis/index.js +++ b/dist/module/db/redis/index.js @@ -36,30 +36,25 @@ export default function RedisDB(name, config = {}) { this.id = (name ? sanitize(name) : "flexsearch") + "|"; this.field = config.field ? "-" + sanitize(config.field) : ""; this.type = config.type || ""; - this.fastupdate = /* tag? */ /* stringify */ /* stringify */!0 /*await rows.hasNext()*/ /*await rows.hasNext()*/ /*await rows.hasNext()*/; + this.fastupdate = !0; this.db = config.db || DB || null; this.support_tag_search = !0; this.resolution = 9; this.resolution_ctx = 9; - //this.trx = false; + Object.assign(defaults, config); this.db && delete defaults.db; } -// RedisDB.mount = function(flexsearch){ -// return new this().mount(flexsearch); -// }; - RedisDB.prototype.mount = function (flexsearch) { - //if(flexsearch.constructor === Document){ + if (flexsearch.index) { return flexsearch.mount(this); } flexsearch.db = this; this.resolution = flexsearch.resolution; this.resolution_ctx = flexsearch.resolution_ctx; - // todo support - //this.fastupdate = flexsearch.fastupdate; + return this.open(); }; @@ -78,7 +73,7 @@ RedisDB.prototype.open = async function () { }; RedisDB.prototype.close = async function () { - DB && (await this.db.disconnect()); // this.db.client.disconnect(); + DB && (await this.db.disconnect()); this.db = DB = null; return this; }; @@ -114,12 +109,11 @@ function create_result(range, type, resolve, enrich, resolution) { } } -RedisDB.prototype.get = function (key, ctx, limit = 0, offset = 0, resolve = !0, enrich = /* suggest */!1, tags) { +RedisDB.prototype.get = function (key, ctx, limit = 0, offset = 0, resolve = !0, enrich = !1, tags) { if (tags) { - // flexsearch dummy const query = ctx ? [ctx, key] : [key]; - // keyword first + return this.search({ depth: !!ctx }, query, limit, offset, !1, resolve, enrich, tags); } @@ -209,28 +203,19 @@ RedisDB.prototype.search = function (flexsearch, query, limit = 100, offset = 0, if (suggest) { const multi = this.db.multi(); - // The zStore implementation lacks of ordering by match count (occurrences). - // Unfortunately, I couldn't find an elegant way to overcome this issue completely. - // For this reason it needs additionally a zInterStore to boost at least matches - // when all terms were found + multi.zInterStore(key, query, { AGGREGATE: "SUM" }); query.push(key); weights.push(query.length); multi.zUnionStore(key, query, { WEIGHTS: weights, AGGREGATE: "SUM" }); - // Strict Tag Intersection: it does not put tags into union, instead it calculates the - // intersection against the term match union. This was the default behavior - // of Tag-Search. But putting everything into union will also provide suggestions derived - // from tags when no term was matched. + if (tags) { - // copy over zInterStore into the same destination surprisingly works fine - // const key2 = key + ":2"; + query = [key]; for (let i = 0; i < tags.length; i += 2) { query.push(this.id + "tag-" + sanitize(tags[i]) + ":" + tags[i + 1]); } multi.zInterStore(key, query, { AGGREGATE: "MAX" }); - // .unlink(key) - // key = key2; } result = multi[resolve ? "zRange" : "zRangeWithScores"](key, "" + offset, "" + (offset + limit - 1), { REV: !0 }).unlink(key).exec(); @@ -243,20 +228,14 @@ RedisDB.prototype.search = function (flexsearch, query, limit = 100, offset = 0, const self = this; return result.then(async function (range) { - range = suggest && tags - // take the 3rd result from batch return - ? range[3] - // take the 2nd result from batch return - : range[suggest ? 2 : 1]; + range = suggest && tags ? range[3] : range[suggest ? 2 : 1]; if (!range.length) return range; if (enrich) range = await self.enrich(range); return create_result(range, type, resolve, enrich, ctx ? self.resolution_ctx : self.resolution); }); }; -RedisDB.prototype.info = function () { - // todo -}; +RedisDB.prototype.info = function () {}; RedisDB.prototype.transaction = function (task, callback) { @@ -265,7 +244,7 @@ RedisDB.prototype.transaction = function (task, callback) { } TRX = this.db.multi(); - let promise1 = /*await*/task.call(this, TRX), + let promise1 = task.call(this, TRX), promise2 = TRX.exec(); TRX = null; @@ -276,17 +255,16 @@ RedisDB.prototype.transaction = function (task, callback) { RedisDB.prototype.commit = async function (flexsearch, _replace, _append) { - // process cleanup tasks if (_replace) { await this.clear(); - // there are just removals in the task queue + flexsearch.commit_task = []; } else { let tasks = flexsearch.commit_task; flexsearch.commit_task = []; for (let i = 0, task; i < tasks.length; i++) { task = tasks[i]; - // there are just removals in the task queue + if (task.clear) { await this.clear(); _replace = !0; @@ -330,15 +308,9 @@ RedisDB.prototype.commit = async function (flexsearch, _replace, _append) { const ref = this.id + "map" + this.field + ":" + key; trx.zAdd(ref, result); - // if(this.fastupdate) for(let j = 0; j < ids.length; j++){ - // trx.sAdd("ref" + this.field + ":" + ids[j], ref); - // } + if (this.fastupdate) for (let j = 0, id; j < ids.length; j++) { - // Map performs bad when pushing numeric-like values as key - // id = ids[j]; - // let tmp = refs.get(id); - // tmp || refs.set(id, tmp = []); - // tmp.push(ref); + id = ids[j]; let tmp = refs.get(id); tmp || refs.set(id, tmp = []); @@ -347,11 +319,7 @@ RedisDB.prototype.commit = async function (flexsearch, _replace, _append) { } } } - // if(this.fastupdate) for(let item of refs){ - // const key = item[0]; - // const value = item[1]; - // trx.sAdd("ref" + this.field + ":" + key, value); - // } + if (this.fastupdate) for (const item of refs) { const key = item[0], value = item[1]; @@ -382,15 +350,9 @@ RedisDB.prototype.commit = async function (flexsearch, _replace, _append) { } const ref = this.id + "ctx" + this.field + ":" + ctx_key + ":" + key; trx.zAdd(ref, result); - // if(this.fastupdate) for(let j = 0; j < ids.length; j++){ - // trx.sAdd("ref" + this.field + ":" + ids[j], ref); - // } + if (this.fastupdate) for (let j = 0, id; j < ids.length; j++) { - // Map performs bad when pushing numeric-like values as key - // id = ids[j]; - // let tmp = refs.get(id); - // tmp || refs.set(id, tmp = []); - // tmp.push(ref); + id = ids[j]; let tmp = refs.get(id); tmp || refs.set(id, tmp = []); @@ -430,12 +392,7 @@ RedisDB.prototype.commit = async function (flexsearch, _replace, _append) { if (!ids.length) continue; let result = []; - // for(let i = 0; i < ids.length; i++){ - // result.push({ - // score: 0, - // value: "" + ids[i] - // }); - // } + if ("number" == typeof ids[0]) { for (let i = 0; i < ids.length; i++) { result[i] = "" + ids[i]; @@ -446,23 +403,6 @@ RedisDB.prototype.commit = async function (flexsearch, _replace, _append) { trx.sAdd(this.id + "tag" + this.field + ":" + tag, result); } } - - // TODO - // trx.set(this.id + "cfg" + this.field, JSON.stringify({ - // "encode": typeof flexsearch.encode === "string" ? flexsearch.encode : "", - // "charset": typeof flexsearch.charset === "string" ? flexsearch.charset : "", - // "tokenize": flexsearch.tokenize, - // "resolution": flexsearch.resolution, - // "minlength": flexsearch.minlength, - // "optimize": flexsearch.optimize, - // "fastupdate": flexsearch.fastupdate, - // "encoder": flexsearch.encoder, - // "context": { - // "depth": flexsearch.depth, - // "bidirectional": flexsearch.bidirectional, - // "resolution": flexsearch.resolution_ctx - // } - // })); }); flexsearch.map.clear(); @@ -506,21 +446,15 @@ RedisDB.prototype.remove = function (ids) { id = "" + ids[i]; if (this.fastupdate) { - // const refs = new Map(); + const ref = await this.db.sMembers(this.id + "ref" + this.field + ":" + id); if (ref) { for (let j = 0; j < ref.length; j++) { - // let tmp = refs.get(ref[j]); - // tmp || refs.set(ref[j], tmp = []); - // tmp.push(id); + trx.zRem(ref[j], id); } trx.unlink(this.id + "ref" + this.field + ":" + id); } - // for(let item of refs){ - // //console.log(item[0], item[1]) - // trx.zRem(item[0], item[1]); - // } } trx.hDel(this.id + "doc", id); diff --git a/dist/module/db/sqlite/index.js b/dist/module/db/sqlite/index.js index d5faa29..702a302 100644 --- a/dist/module/db/sqlite/index.js +++ b/dist/module/db/sqlite/index.js @@ -1,4 +1,4 @@ -//const sqlite3 = require("sqlite3").verbose(); + import sqlite3 from "sqlite3"; import path from "path"; import StorageInterface from "../interface.js"; @@ -34,7 +34,6 @@ function sanitize(str) { return str.toLowerCase().replace(/[^a-z0-9_]/g, ""); } -// global transaction to keep track of database lock const TRX = Object.create(null), Index = Object.create(null); @@ -55,18 +54,17 @@ export default function SqliteDB(name, config = {}) { if (!name) { console.info("Default storage space was used, because a name was not passed."); } - //field = "Test-456"; + this.id = config.path || (":memory:" === name ? name : "flexsearch" + (name ? "-" + sanitize(name) : "") + ".sqlite"); this.field = config.field ? "_" + sanitize(config.field) : ""; - this.support_tag_search = /* tag? */ /* stringify */ /* stringify */ /* single param */!0 /*await rows.hasNext()*/ - /*await rows.hasNext()*/ /*await rows.hasNext()*/; + this.support_tag_search = !0; this.db = config.db || Index[this.id] || null; this.type = config.type ? types[config.type.toLowerCase()] : "string"; if (!this.type) throw new Error("Unknown type of ID '" + config.type + "'"); } SqliteDB.prototype.mount = function (flexsearch) { - //if(flexsearch.constructor === Document){ + if (flexsearch.index) { return flexsearch.mount(this); } @@ -82,9 +80,9 @@ SqliteDB.prototype.open = async function () { let filepath = this.id; if (":memory:" !== filepath) { - // skip absolute path + if ("/" !== filepath[0] && "\\" !== filepath[0]) { - // current working directory + const dir = process.cwd(); filepath = path.join(dir, this.id); } @@ -246,7 +244,7 @@ function create_result(rows, resolve, enrich) { } } -SqliteDB.prototype.get = function (key, ctx, limit = 0, offset = 0, resolve = !0, enrich = /* suggest */!1, tags) { +SqliteDB.prototype.get = function (key, ctx, limit = 0, offset = 0, resolve = !0, enrich = !1, tags) { let result, stmt = '', params = ctx ? [ctx, key] : [key], @@ -352,12 +350,6 @@ SqliteDB.prototype.enrich = function (ids) { const chunk = ids.length - count > MAXIMUM_QUERY_VARS ? ids.slice(count, count + MAXIMUM_QUERY_VARS) : count ? ids.slice(count) : ids; count += chunk.length; - // let stmt = "?"; - // for(let i = 1; i < chunk.length; i++){ - // stmt += ",?"; - // } - - // 10x faster string concatenation let stmt = build_params(chunk.length); promises.push(this.promisfy({ @@ -430,7 +422,7 @@ SqliteDB.prototype.search = function (flexsearch, query, limit = 100, offset = 0 ${enrich ? ", doc" : ""} FROM ( SELECT id, count(*) as count, - ${suggest ? "SUM" : "SUM" /*"MIN"*/}(res) as res + ${suggest ? "SUM" : "SUM"}(res) as res FROM main.ctx${this.field} WHERE ${stmt} GROUP BY id @@ -445,36 +437,6 @@ SqliteDB.prototype.search = function (flexsearch, query, limit = 100, offset = 0 `, params }); - - // variant 1 - // for(let i = 1; i < query.length; i++){ - // stmt += (stmt ? " UNION ALL " : "") + ` - // SELECT id, res - // FROM main.ctx${this.field} - // WHERE ctx = ? AND key = ? - // `; - // term = query[i]; - // const swap = flexsearch.bidirectional && (term > keyword); - // params.push(swap ? term : keyword, swap ? keyword : term); - // keyword = term; - // } - // - // rows = await this.promisfy({ - // method: "all", - // stmt: ` - // SELECT id/*, res */ - // FROM ( - // SELECT id, ${suggest ? "SUM" : "MIN"}(res) as res, count(*) as count - // FROM (${stmt}) as t - // GROUP BY id - // ORDER BY ${suggest ? "count DESC, res" : "res"} - // LIMIT ${limit} - // OFFSET ${offset} - // ) as r - // ${suggest ? "" : "WHERE count = " + (query.length - 1)} - // `, - // params - // }); } else { let stmt = "", query_length = query.length; @@ -499,7 +461,7 @@ SqliteDB.prototype.search = function (flexsearch, query, limit = 100, offset = 0 ${enrich ? ", doc" : ""} FROM ( SELECT id, count(*) as count, - ${suggest ? "SUM" : "SUM" /*"MIN"*/}(res) as res + ${suggest ? "SUM" : "SUM"}(res) as res FROM main.map${this.field} WHERE ${stmt} GROUP BY id @@ -514,32 +476,6 @@ SqliteDB.prototype.search = function (flexsearch, query, limit = 100, offset = 0 `, params: query }); - - // variant 1 - // for(let i = 0; i < query.length; i++){ - // stmt += (stmt ? " UNION ALL " : "") + ` - // SELECT id, res - // FROM main.map${ this.field } - // WHERE key = ? - // `; - // } - // - // rows = await this.promisfy({ - // method: "all", - // stmt: ` - // SELECT id/*, res*/ - // FROM ( - // SELECT id, ${suggest ? "SUM" : "MIN"}(res) as res, count(*) as count - // FROM (${stmt}) as t - // GROUP BY id - // ORDER BY ${suggest ? "count DESC, res" : "res"} - // LIMIT ${limit} - // OFFSET ${offset} - // ) as r - // ${ suggest ? "" : "WHERE count = " + query.length } - // `, - // params: query - // }); } return rows.then(function (rows) { @@ -547,9 +483,7 @@ SqliteDB.prototype.search = function (flexsearch, query, limit = 100, offset = 0 }); }; -SqliteDB.prototype.info = function () { - // todo -}; +SqliteDB.prototype.info = function () {}; SqliteDB.prototype.transaction = async function (task, callback) { @@ -580,17 +514,16 @@ SqliteDB.prototype.transaction = async function (task, callback) { SqliteDB.prototype.commit = async function (flexsearch, _replace, _append) { - // process cleanup tasks if (_replace) { await this.clear(); - // there are just removals in the task queue + flexsearch.commit_task = []; } else { let tasks = flexsearch.commit_task; flexsearch.commit_task = []; for (let i = 0, task; i < tasks.length; i++) { task = tasks[i]; - // there are just removals in the task queue + if (task.clear) { await this.clear(); _replace = !0; @@ -627,21 +560,17 @@ SqliteDB.prototype.commit = async function (flexsearch, _replace, _append) { for (let j = 0; j < ids.length; j++) { stmt += (stmt ? "," : "") + "(?,?,?)"; params.push(key, i, ids[j]); - // maximum count of variables supported + if (j === ids.length - 1 || params.length + 3 > MAXIMUM_QUERY_VARS) { this.db.run("INSERT INTO main.map" + this.field + " (key, res, id) VALUES " + stmt, params); stmt = ""; params = []; } - //this.db.run("INSERT INTO map (key, res, id) VALUES (?, ?, ?) ON CONFLICT DO NOTHING", [key, i, ids[j]]); } } } } - //}); - //await this.transaction(function(){ - for (const ctx of flexsearch.ctx) { const ctx_key = ctx[0], ctx_value = ctx[1]; @@ -661,7 +590,7 @@ SqliteDB.prototype.commit = async function (flexsearch, _replace, _append) { for (let j = 0; j < ids.length; j++) { stmt += (stmt ? "," : "") + "(?,?,?,?)"; params.push(ctx_key, key, i, ids[j]); - // maximum count of variables supported + if (j === ids.length - 1 || params.length + 4 > MAXIMUM_QUERY_VARS) { this.db.run("INSERT INTO main.ctx" + this.field + " (ctx, key, res, id) VALUES " + stmt, params); stmt = ""; @@ -672,8 +601,6 @@ SqliteDB.prototype.commit = async function (flexsearch, _replace, _append) { } } } - //}); - //await this.transaction(function(){ if (flexsearch.store) { let stmt = "", @@ -703,8 +630,6 @@ SqliteDB.prototype.commit = async function (flexsearch, _replace, _append) { this.db.run("INSERT INTO main.reg (id) VALUES " + stmt, chunk); } } - //}); - //await this.transaction(function(){ if (flexsearch.tag) { let stmt = "", @@ -731,25 +656,6 @@ SqliteDB.prototype.commit = async function (flexsearch, _replace, _append) { } }); - // TODO - //await this.transaction(function(){ - // this.db.run("INSERT INTO main.cfg" + this.field + " (cfg) VALUES (?)", [JSON.stringify({ - // "charset": flexsearch.charset, - // "tokenize": flexsearch.tokenize, - // "resolution": flexsearch.resolution, - // "fastupdate": flexsearch.fastupdate, - // "compress": flexsearch.compress, - // "encoder": { - // "minlength": flexsearch.encoder.minlength - // }, - // "context": { - // "depth": flexsearch.depth, - // "bidirectional": flexsearch.bidirectional, - // "resolution": flexsearch.resolution_ctx - // } - // })]); - //}); - flexsearch.map.clear(); flexsearch.ctx.clear(); flexsearch.tag && flexsearch.tag.clear(); @@ -764,7 +670,7 @@ SqliteDB.prototype.remove = function (ids) { } let next; - // maximum count of variables supported + if (ids.length > MAXIMUM_QUERY_VARS) { next = ids.slice(MAXIMUM_QUERY_VARS); ids = ids.slice(0, MAXIMUM_QUERY_VARS); diff --git a/dist/module/document.js b/dist/module/document.js index 9433ebb..0aff73f 100644 --- a/dist/module/document.js +++ b/dist/module/document.js @@ -44,17 +44,15 @@ export default function Document(options) { keystore = options.keystore || 0; keystore && (this.keystore = keystore); this.fastupdate = !!options.fastupdate; - // Shared Registry - this.reg = this.fastupdate && !options.worker && !options.db ? keystore && /* tag? */ /* stringify */ /* stringify */ /* single param */ /* skip update: */ /* append: */ /* skip update: */ /* skip_update: */ /* skip deletion */!0 /*await rows.hasNext()*/ /*await rows.hasNext()*/ /*await rows.hasNext()*/ ? new KeystoreMap(keystore) : new Map() : keystore && !0 ? new KeystoreSet(keystore) : new Set(); - // todo support custom filter function + this.reg = this.fastupdate && !options.worker && !options.db ? keystore && !0 ? new KeystoreMap(keystore) : new Map() : keystore && !0 ? new KeystoreSet(keystore) : new Set(); + this.storetree = (tmp = document.store || null) && tmp && !0 !== tmp && []; this.store = tmp && (keystore && !0 ? new KeystoreMap(keystore) : new Map()); this.cache = (tmp = options.cache || null) && new Cache(tmp); - // do not apply cache again for the indexes since .searchCache() - // is just a wrapper over .search() - options.cache = /* suggest */ /* append: */ /* enrich */!1; + + options.cache = !1; this.worker = options.worker || !1; @@ -66,7 +64,7 @@ export default function Document(options) { this.index = parse_descriptor.call(this, options, document); this.tag = null; - // TODO case-insensitive tags? + if (tmp = document.tag) { if ("string" == typeof tmp) { tmp = [tmp]; @@ -87,20 +85,20 @@ export default function Document(options) { this.tagtree[i] = parse_tree(field, this.marker); if (params.filter) { if ("string" == typeof this.tagtree[i]) { - // it needs an object to put a property to it + this.tagtree[i] = new String(this.tagtree[i]); } this.tagtree[i]._filter = params.filter; } } - // the tag fields need to be hold by indices + this.tagfield[i] = field; this.tag.set(field, new Map()); } } } - // resolve worker promises and swap instances + if (this.worker) { this.fastupdate = !1; const promises = []; @@ -110,38 +108,15 @@ export default function Document(options) { if (promises.length) { const self = this; return Promise.all(promises).then(function (result) { - new Map(); - let count = 0; for (const item of self.index.entries()) { const key = /** @type {string} */item[0]; let index = /** @type {Index|WorkerIndex | Promise} */item[1]; - // let encoder; - // if(SUPPORT_HIGHLIGHTING && SUPPORT_STORE){ - // // make encoder available for result highlighting - // let opt = promises[count].encoder || {}; - // // handle shared encoders - // let encoder = encoder_last.get(opt); - // if(!encoder){ - // encoder = opt.encode - // ? opt - // : SUPPORT_ENCODER - // ? new Encoder( - // SUPPORT_CHARSET && typeof opt === "string" - // ? Charset[opt] - // : opt) - // : { encode: fallback_encoder }; - // encoder_last.set(opt, encoder); - // } - // } if (index.then) { index = result[count]; self.index.set(key, index); count++; } - // if(encoder){ - // index.encoder = encoder; - // } } return self; }); @@ -149,8 +124,7 @@ export default function Document(options) { } else { if (options.db) { this.fastupdate = !1; - // a constructor should not return a promise - // it can be awaited on "await index.db" + this.mount(options.db); } } @@ -165,22 +139,19 @@ Document.prototype.mount = function (db) { let fields = this.field; if (this.tag) { - // tag indexes are referenced by field - // move tags to their field indexes respectively + for (let i = 0, field; i < this.tagfield.length; i++) { field = this.tagfield[i]; - let index; // = this.index.get(field); - //if(!index){ - // create raw index when not exists + let index; + this.index.set(field, index = new Index( /** @type IndexOptions */{}, this.reg)); - // copy and push to the field selection + if (fields === this.field) { fields = fields.slice(0); } - // tag indexes also needs to be upgraded to db instances + fields.push(field); - //} - // assign reference + index.tag = this.tag.get(field); } } @@ -193,22 +164,20 @@ Document.prototype.mount = function (db) { }; - // upgrade all indexes to db instances for (let i = 0, index, field; i < fields.length; i++) { config.field = field = fields[i]; index = this.index.get(field); const dbi = new db.constructor(db.id, config); - // take over the storage id + dbi.id = db.id; promises[i] = dbi.mount(index); - // add an identification property + index.document = !0; if (i) { - // the register has to export just one time - // also it's needed by the index for ID contain check + index.bypass = !0; } else { - // the datastore has to export one time + index.store = this.store; } } @@ -220,18 +189,13 @@ Document.prototype.mount = function (db) { }; Document.prototype.commit = async function (replace, append) { - // parallel: + const promises = []; for (const index of this.index.values()) { promises.push(index.commit(replace, append)); } await Promise.all(promises); this.reg.clear(); - // queued: - // for(const index of this.index.values()){ - // await index.db.commit(index, replace, append); - // } - // this.reg.clear(); }; Document.prototype.destroy = function () { @@ -270,17 +234,15 @@ function parse_descriptor(options, document) { if (this.worker) { let encoder = opt.encoder; - // assign encoder for result highlighting encoder = encoder && encoder.encode ? encoder : new Encoder("string" == typeof encoder ? Charset[encoder] : encoder); const worker = new WorkerIndex(opt, /** @type {Encoder} */encoder); if (worker) { - // worker could be a promise - // it needs to be resolved and swapped later + index.set(key, worker); } else { - // fallback when not supported + this.worker = !1; } } @@ -295,7 +257,7 @@ function parse_descriptor(options, document) { this.tree[i] = parse_tree(key, this.marker); if (opt.filter) { if ("string" == typeof this.tree[i]) { - // it needs an object to put a property to it + this.tree[i] = new String(this.tree[i]); } this.tree[i]._filter = opt.filter; @@ -320,7 +282,7 @@ function parse_descriptor(options, document) { this.storetree[i] = parse_tree(field, this.marker); if (store.filter) { if ("string" == typeof this.storetree[i]) { - // it needs an object to put a property to it + this.storetree[i] = new String(this.storetree[i]); } this.storetree[i]._filter = store.filter; @@ -339,7 +301,7 @@ function parse_tree(key, marker) { for (let i = 0; i < tree.length; i++) { key = tree[i]; - // todo apply some indexes e.g. [0], [-1], [0-2] + if ("]" === key[key.length - 1]) { key = key.substring(0, key.length - 2); if (key) { @@ -393,7 +355,7 @@ Document.prototype.remove = function (id) { if (this.reg.has(id)) { if (this.tag) { - // when fastupdate was enabled all ids are already removed + if (!this.fastupdate) { for (let field of this.tag.values()) { for (let item of field) { @@ -416,7 +378,6 @@ Document.prototype.remove = function (id) { this.reg.delete(id); } - // the cache could be used outside the InMemory store if (this.cache) { this.cache.remove(id); } @@ -429,9 +390,9 @@ Document.prototype.clear = function () { const promises = []; for (const index of this.index.values()) { - // db index will add clear task + const promise = index.clear(); - // worker indexes will return promises + if (promise.then) { promises.push(promise); } @@ -507,7 +468,7 @@ Document.prototype.set = function (id, data) { return this; }; -// todo mo + Document.prototype.searchCache = searchCache; diff --git a/dist/module/document/add.js b/dist/module/document/add.js index fedc026..3314e57 100644 --- a/dist/module/document/add.js +++ b/dist/module/document/add.js @@ -25,7 +25,6 @@ Document.prototype.add = function (id, content, _append) { return this.update(id, content); } - // this.field does not include db tag indexes for (let i = 0, tree; i < this.field.length; i++) { tree = this.tree[i]; @@ -34,7 +33,7 @@ Document.prototype.add = function (id, content, _append) { if ("function" == typeof tree) { const tmp = tree(content); if (tmp) { - index.add(id, tmp, /* suggest */ /* append: */!1, /* tag? */ /* stringify */ /* stringify */ /* single param */ /* skip update: */ /* append: */ /* skip update: */ /* skip_update: */!0 /*await rows.hasNext()*/ /*await rows.hasNext()*/ /*await rows.hasNext()*/); + index.add(id, tmp, !0); } } else { const filter = tree._filter; @@ -52,8 +51,6 @@ Document.prototype.add = function (id, content, _append) { if (this.tag) { - //console.log(this.tag, this.tagtree) - for (let x = 0; x < this.tagtree.length; x++) { let tree = this.tagtree[x], field = this.tagfield[x], @@ -87,7 +84,6 @@ Document.prototype.add = function (id, content, _append) { for (let i = 0, tag, arr; i < tags.length; i++) { tag = tags[i]; - //console.log(this.tag, tag, key, field) if (!dupes[tag]) { dupes[tag] = 1; @@ -97,24 +93,21 @@ Document.prototype.add = function (id, content, _append) { tmp ? arr = tmp : ref.set(tag, arr = []); if (!_append || ! /** @type {!Array|KeystoreArray} */arr.includes(id)) { - - // auto-upgrade to keystore array if max size exceeded - if (2147483647 === arr.length /*|| !(arr instanceof KeystoreArray)*/) { - const keystore = new KeystoreArray(arr); - if (this.fastupdate) { - for (let value of this.reg.values()) { - if (value.includes(arr)) { - value[value.indexOf(arr)] = keystore; - } + if (2147483647 === arr.length) { + const keystore = new KeystoreArray(arr); + if (this.fastupdate) { + for (let value of this.reg.values()) { + if (value.includes(arr)) { + value[value.indexOf(arr)] = keystore; } } - ref.set(tag, arr = keystore); } + ref.set(tag, arr = keystore); + } arr.push(id); - // add a reference to the register for fast updates if (this.fastupdate) { const tmp = this.reg.get(id); tmp ? tmp.push(arr) : this.reg.set(id, [arr]); @@ -165,8 +158,6 @@ Document.prototype.add = function (id, content, _append) { return this; }; -// TODO support generic function created from string when tree depth > 1 - /** * @param obj * @param store @@ -180,10 +171,8 @@ function store_value(obj, store, tree, pos, key, custom) { obj = obj[key]; - // reached target field if (pos === tree.length - 1) { - // store target value store[key] = custom || obj; } else if (obj) { @@ -192,7 +181,7 @@ function store_value(obj, store, tree, pos, key, custom) { store = store[key] = Array(obj.length); for (let i = 0; i < obj.length; i++) { - // do not increase pos (an array is not a field) + store_value(obj, store, tree, pos, i); } } else { @@ -208,21 +197,17 @@ function add_index(obj, tree, marker, pos, index, id, key, _append) { if (obj = obj[key]) { - // reached target field if (pos === tree.length - 1) { - // handle target value if (is_array(obj)) { - // append array contents so each entry gets a new scoring context if (marker[pos]) { for (let i = 0; i < obj.length; i++) { - index.add(id, obj[i], !0, !0); + index.add(id, obj[i], !0); } return; } - // or join array contents and use one scoring context obj = obj.join(" "); } @@ -231,7 +216,7 @@ function add_index(obj, tree, marker, pos, index, id, key, _append) { if (is_array(obj)) { for (let i = 0; i < obj.length; i++) { - // do not increase index, an array is not a field + add_index(obj, tree, marker, pos, index, id, i, _append); } } else { diff --git a/dist/module/document/highlight.js b/dist/module/document/highlight.js index 87d7e97..ada5137 100644 --- a/dist/module/document/highlight.js +++ b/dist/module/document/highlight.js @@ -13,9 +13,6 @@ import { EnrichedDocumentSearchResults, EnrichedSearchResults, HighlightOptions */ export function highlight_fields(query, result, index, pluck, config) { - // The biggest issue is dealing with custom encoders, for this reason - // a combined regular expression can't apply as a template - let template, markup_open, markup_close; if ("string" == typeof config) { @@ -31,7 +28,7 @@ export function highlight_fields(query, result, index, pluck, config) { markup_open = template.substring(0, markup_open); let boundary = config && config.boundary, - clip = !config || /* suggest */ /* append: */!1 !== config.clip, + clip = !config || !1 !== config.clip, merge = config && config.merge && markup_close && markup_open && new RegExp(markup_close + " " + markup_open, "g"), ellipsis = config && config.ellipsis, ellipsis_markup_length = 0, @@ -62,28 +59,23 @@ export function highlight_fields(query, result, index, pluck, config) { boundary = boundary.total || 9e5; } - // cache shared encoders across fields let encoder = new Map(), query_enc; - // todo remove this loop and pass in the field data directly - // todo support field-specific configuration - - // for every field for (let i = 0, enc, idx, path; i < result.length; i++) { /** @type {EnrichedSearchResults} */ let res; if (pluck) { - //res = result[0].result; + res = result; path = pluck; } else { const tmp = result[i]; path = tmp.field; - // skip when not a field entry (e.g. tags) + if (!path) continue; res = tmp.result; } @@ -93,20 +85,18 @@ export function highlight_fields(query, result, index, pluck, config) { idx.tokenize; query_enc = encoder.get(enc); - // re-encode query when encoder has changed or take cache from shared encoders if ("string" != typeof query_enc) { query_enc = enc.encode(query); encoder.set(enc, query_enc); } - // for every doc in results for (let j = 0; j < res.length; j++) { const doc = res[j].doc; if (!doc) continue; const content = parse_simple(doc, path); if (!content) continue; - // just split on whitespace and keep original string (encoder split can't apply) + const doc_org = content.trim().split(/\s+/); if (!doc_org.length) continue; @@ -118,7 +108,6 @@ export function highlight_fields(query, result, index, pluck, config) { length_matches_all = 0; - // loop terms of encoded doc content for (let k = 0; k < doc_org.length; k++) { let doc_org_cur = doc_org[k], doc_enc_cur = enc.encode(doc_org_cur); @@ -134,48 +123,37 @@ export function highlight_fields(query, result, index, pluck, config) { match_length = 0; - // loop terms of encoded query content and determine the longest match for (let l = 0, query_enc_cur; l < query_enc.length; l++) { query_enc_cur = query_enc[l]; if (!query_enc_cur) continue; let query_enc_cur_len = query_enc_cur.length; - // add length from shrinking phonetic transformations (todo: add tests) + query_enc_cur_len += doc_org_diff; - // skip query token when match length can't exceed previously highest found match + if (match_length && query_enc_cur_len <= match_length) { continue; } const position = doc_enc_cur.indexOf(query_enc_cur); if (-1 < position) { - match = - // prefix - (position ? doc_org_cur.substring(0, position) : "") + - // match - markup_open + doc_org_cur.substring(position, position + query_enc_cur_len) + markup_close + ( - // suffix - position + query_enc_cur_len < doc_org_cur_len ? doc_org_cur.substring(position + query_enc_cur_len) : ""); + match = (position ? doc_org_cur.substring(0, position) : "") + markup_open + doc_org_cur.substring(position, position + query_enc_cur_len) + markup_close + (position + query_enc_cur_len < doc_org_cur_len ? doc_org_cur.substring(position + query_enc_cur_len) : ""); match_length = query_enc_cur_len; - found = /* tag? */ /* stringify */ /* stringify */ /* single param */ /* skip update: */ /* append: */ /* skip update: */ /* skip_update: */!0 /*await rows.hasNext()*/ /*await rows.hasNext()*/ /*await rows.hasNext()*/; + found = !0; } - //console.log(doc_org_cur, doc_enc_cur, query_enc_cur, position, match) } - // apply the longest match if (match) { if (boundary) { - // the outer boundary is used to check if all matches are within the total boundary - // if so, it can apply a simpler alignment + if (0 > pos_first_match) { pos_first_match = str.length + (str ? 1 : 0); } pos_last_match = str.length + (str ? 1 : 0) + match.length; - // the overall length of all matches is used to check if matches exceeds the total boundary - // if so, it can early stop further processing + length_matches_all += doc_org_cur_len; - // the match positions are used to pick items for the final result more quickly + pos_matches.push(str_arr.length); - // collect every term as match or text + str_arr.push({ match }); } str += (str ? " " : "") + match; @@ -185,23 +163,19 @@ export function highlight_fields(query, result, index, pluck, config) { if (!found) { const text = doc_org[k]; str += (str ? " " : "") + text; - // collect every term as match or text + boundary && str_arr.push({ text }); } else if (boundary) { if (length_matches_all >= boundary) { - // matches has reached total boundary + break; } } } - // the markup length does not apply to the total boundary let markup_length = pos_matches.length * (template.length - 2); - // apply boundaries and align highlights if (boundary_before || boundary_after || boundary && str.length - markup_length > boundary) { - - // also reduce ellipsis length from boundary let boundary_length = boundary + markup_length - 2 * ellipsis_length, length = pos_last_match - pos_first_match, start, @@ -215,13 +189,11 @@ export function highlight_fields(query, result, index, pluck, config) { length += boundary_after; } - // 1. all matches are withing the overall boundary (apply simple alignment) if (length <= boundary_length) { start = boundary_before ? pos_first_match - (0 < boundary_before ? boundary_before : 0) : pos_first_match - (0 | (boundary_length - length) / 2); end = boundary_after ? pos_last_match + (0 < boundary_after ? boundary_after : 0) : start + boundary_length; - // do not clip terms if (!clip) { if (0 < start) { if (" " === str.charAt(start)) {} else if (" " !== str.charAt(start - 1)) { @@ -238,253 +210,227 @@ export function highlight_fields(query, result, index, pluck, config) { } str = (start ? ellipsis : "") + str.substring(start, end) + (end < str.length ? ellipsis : ""); - } - // 2. matches needs to be split by surrounded terms to fit into the boundary - else { - const final = [], - check = {}, - seamless = {}, - finished = {}, - before = {}, - after = {}; - let final_length = 0, - shift_left = 0, - shift_right = 0, - loop_left = 1, - loop_right = 1; + } else { + const final = [], + check = {}, + seamless = {}, + finished = {}, + before = {}, + after = {}; + let final_length = 0, + shift_left = 0, + shift_right = 0, + loop_left = 1, + loop_right = 1; - while (!0) { + while (!0) { - let loop; + let loop; - for (let k = 0, pos; k < pos_matches.length; k++) { + for (let k = 0, pos; k < pos_matches.length; k++) { - pos = pos_matches[k]; + pos = pos_matches[k]; - // 1. add matches to the result - if (!shift_right) { - str = str_arr[pos].match; + if (!shift_right) { + str = str_arr[pos].match; - // initialize custom boundaries for each slot - if (boundary_before) { - before[k] = boundary_before; - } - if (boundary_after) { - after[k] = boundary_after; - } - - // count whitespaces between each term - if (k) { - final_length++; - } - - let close; - - // close left side when first term was matched - if (!pos) { - // it can be set before content was added, - // because the first term match is always added - seamless[k] = 1; - finished[k] = 1; - } - // initial ellipsis - else if (!k && ellipsis_length) { - final_length += ellipsis_length; - } - - // close right side when last term was matched - if (pos >= doc_org.length - 1) { - close = 1; - } - // close right side when next term was a match - else if (pos < str_arr.length - 1 && str_arr[pos + 1].match) { - close = 1; - } else if (ellipsis_length) { - final_length += ellipsis_length; - } - - // reduce template length on matches - final_length -= template.length - 2; - - // at least add one match - if (!k || final_length + str.length <= boundary) { - final[k] = str; - } else { - seamless[k] = 0; - loop = loop_left = loop_right = 0; - break; - } - - // update state when term was added - if (close) { - seamless[k + 1] = 1; - finished[k + 1] = 1; - } + if (boundary_before) { + before[k] = boundary_before; + } + if (boundary_after) { + after[k] = boundary_after; } - // 2. add surrounded text to the result - else { - // alternate direction term by term - // 2.1. extend to right first (index: k + 1) - if (shift_left != shift_right) { - if (finished[k + 1]) continue; - pos += shift_right; - // overlap with other slot - if (check[pos]) { - final_length -= ellipsis_length; - seamless[k + 1] = 1; - finished[k + 1] = 1; - continue; - } - // end reached - if (pos >= str_arr.length - 1) { - if (pos >= str_arr.length) { - finished[k + 1] = 1; - if (pos >= doc_org.length) { - seamless[k + 1] = 1; - } - continue; - } - final_length -= ellipsis_length; - } + if (k) { + final_length++; + } - str = str_arr[pos].text; + let close; - let current_after = boundary_after && after[k]; - if (current_after) { - if (0 < current_after) { - if (str.length > current_after) { - finished[k + 1] = 1; - if (clip) { - str = str.substring(0, current_after); - } else { - continue; - } - } - current_after -= str.length; - if (!current_after) current_after = -1; - after[k] = current_after; - } else { - finished[k + 1] = 1; - continue; - } - } + if (!pos) { - // count whitespaces between each term - if (final_length + str.length + 1 <= boundary) { - str = " " + str; - final[k] += str; - } else if (clip) { - const diff = boundary - final_length - 1; - if (0 < diff) { - str = " " + str.substring(0, diff); - final[k] += str; - } - finished[k + 1] = 1; - } else { - finished[k + 1] = 1; - continue; - } - } - // 2.2. extend to left (index: k) - else { - if (finished[k]) continue; - pos -= shift_left; + seamless[k] = 1; + finished[k] = 1; + } else if (!k && ellipsis_length) { + final_length += ellipsis_length; + } - // overlap with other slot - if (check[pos]) { - final_length -= ellipsis_length; - finished[k] = 1; - seamless[k] = 1; - continue; - } - // start reached - if (0 >= pos) { - if (0 > pos) { - finished[k] = 1; - seamless[k] = 1; - continue; - } - final_length -= ellipsis_length; - } + if (pos >= doc_org.length - 1) { + close = 1; + } else if (pos < str_arr.length - 1 && str_arr[pos + 1].match) { + close = 1; + } else if (ellipsis_length) { + final_length += ellipsis_length; + } - str = str_arr[pos].text; + final_length -= template.length - 2; - let current_before = boundary_before && before[k]; - if (current_before) { - if (0 < current_before) { - if (str.length > current_before) { - finished[k] = 1; - if (clip) { - str = str.substring(str.length - current_before); - } else { - continue; - } - } - current_before -= str.length; - if (!current_before) current_before = -1; - before[k] = current_before; - } else { - finished[k] = 1; - continue; - } - } - - // count whitespaces between each term - if (final_length + str.length + 1 <= boundary) { - str += " "; - final[k] = str + final[k]; - } else if (clip) { - const diff = str.length + 1 - (boundary - final_length); - if (0 <= diff && diff < str.length) { - str = str.substring(diff) + " "; - final[k] = str + final[k]; - } - finished[k] = 1; - } else { - finished[k] = 1; - continue; - } - } - } - - // update state when term was added - final_length += str.length; - check[pos] = 1; - loop = 1; - } - - if (loop) { - // alternate shift direction - shift_left == shift_right ? shift_right++ : shift_left++; - } else { - // check finish state - shift_left == shift_right ? loop_left = 0 : loop_right = 0; - // break process when both directions are done - if (!loop_left && !loop_right) { + if (!k || final_length + str.length <= boundary) { + final[k] = str; + } else { + seamless[k] = 0; + loop = loop_left = loop_right = 0; break; } - // continue with opposite direction - if (loop_left) { - shift_left++; - shift_right = shift_left; + + if (close) { + seamless[k + 1] = 1; + finished[k + 1] = 1; + } + } else { + + if (shift_left != shift_right) { + if (finished[k + 1]) continue; + pos += shift_right; + + if (check[pos]) { + final_length -= ellipsis_length; + seamless[k + 1] = 1; + finished[k + 1] = 1; + continue; + } + + if (pos >= str_arr.length - 1) { + if (pos >= str_arr.length) { + finished[k + 1] = 1; + if (pos >= doc_org.length) { + seamless[k + 1] = 1; + } + continue; + } + final_length -= ellipsis_length; + } + + str = str_arr[pos].text; + + let current_after = boundary_after && after[k]; + if (current_after) { + if (0 < current_after) { + if (str.length > current_after) { + finished[k + 1] = 1; + if (clip) { + str = str.substring(0, current_after); + } else { + continue; + } + } + current_after -= str.length; + if (!current_after) current_after = -1; + after[k] = current_after; + } else { + finished[k + 1] = 1; + continue; + } + } + + if (final_length + str.length + 1 <= boundary) { + str = " " + str; + final[k] += str; + } else if (clip) { + const diff = boundary - final_length - 1; + if (0 < diff) { + str = " " + str.substring(0, diff); + final[k] += str; + } + finished[k + 1] = 1; + } else { + finished[k + 1] = 1; + continue; + } } else { - shift_right++; + if (finished[k]) continue; + pos -= shift_left; + + if (check[pos]) { + final_length -= ellipsis_length; + finished[k] = 1; + seamless[k] = 1; + continue; + } + + if (0 >= pos) { + if (0 > pos) { + finished[k] = 1; + seamless[k] = 1; + continue; + } + final_length -= ellipsis_length; + } + + str = str_arr[pos].text; + + let current_before = boundary_before && before[k]; + if (current_before) { + if (0 < current_before) { + if (str.length > current_before) { + finished[k] = 1; + if (clip) { + str = str.substring(str.length - current_before); + } else { + continue; + } + } + current_before -= str.length; + if (!current_before) current_before = -1; + before[k] = current_before; + } else { + finished[k] = 1; + continue; + } + } + + if (final_length + str.length + 1 <= boundary) { + str += " "; + final[k] = str + final[k]; + } else if (clip) { + const diff = str.length + 1 - (boundary - final_length); + if (0 <= diff && diff < str.length) { + str = str.substring(diff) + " "; + final[k] = str + final[k]; + } + finished[k] = 1; + } else { + finished[k] = 1; + continue; + } } } + + final_length += str.length; + check[pos] = 1; + loop = 1; } - str = ""; - for (let k = 0, tmp; k < final.length; k++) { - tmp = (k && seamless[k] ? " " : (k && !ellipsis ? " " : "") + ellipsis) + final[k]; - str += tmp; + if (loop) { + + shift_left == shift_right ? shift_right++ : shift_left++; + } else { + + shift_left == shift_right ? loop_left = 0 : loop_right = 0; + + if (!loop_left && !loop_right) { + break; + } + + if (loop_left) { + shift_left++; + shift_right = shift_left; + } else { + shift_right++; + } } - if (ellipsis && !seamless[final.length]) { - str += ellipsis; - } - //console.log(query, seamless, final) } + + str = ""; + for (let k = 0, tmp; k < final.length; k++) { + tmp = (k && seamless[k] ? " " : (k && !ellipsis ? " " : "") + ellipsis) + final[k]; + str += tmp; + } + if (ellipsis && !seamless[final.length]) { + str += ellipsis; + } + } } if (merge) { @@ -500,303 +446,4 @@ export function highlight_fields(query, result, index, pluck, config) { } return result; -} - -// /** -// * @param {string} query -// * @param {EnrichedDocumentSearchResults|EnrichedSearchResults} result -// * @param {Map} index -// * @param {string} pluck -// * @param {HighlightOptions|string} config -// * @return {EnrichedDocumentSearchResults|EnrichedSearchResults} -// */ -// export function highlight_fields(query, result, index, pluck, config){ -// -// // The biggest issue is dealing with custom encoders, for this reason -// // a combined regular expression can't apply as a template -// -// let template, markup_open, markup_close; -// -// if(typeof config === "string"){ -// template = config; -// config = ""; -// } -// else{ -// template = config.template; -// } -// -// if(DEBUG){ -// if(!template){ -// throw new Error('No template pattern was specified by the search option "highlight"'); -// } -// } -// -// markup_open = template.indexOf("$1"); -// -// if(DEBUG){ -// if(markup_open === -1){ -// throw new Error('Invalid highlight template. The replacement pattern "$1" was not found in template: ' + template); -// } -// } -// -// markup_close = template.substring(markup_open + 2); -// markup_open = template.substring(0, markup_open); -// -// let boundary = config && config.boundary; -// let clip = !config || config.clip !== false; -// let merge = config && config.merge && markup_close && markup_open && new RegExp(markup_close + " " + markup_open, "g"); -// let ellipsis = config && config.ellipsis; -// if(typeof ellipsis !== "string"){ -// ellipsis = "..."; -// } -// -// let boundary_before, boundary_after; -// -// if(typeof boundary === "object"){ -// boundary_before = boundary.before; -// if(boundary_before === 0) boundary_before = -1; -// boundary_after = boundary.after; -// if(boundary_after === 0) boundary_after = -1; -// boundary = boundary.total || 9e5; -// } -// -// // cache shared encoders across fields -// let encoder = new Map(); -// let query_enc; -// let tokenize; -// -// // todo remove this loop and pass in the field data directly -// // todo support field-specific configuration -// -// // for every field -// for(let i = 0, enc, idx, path; i < result.length; i++){ -// -// /** @type {EnrichedSearchResults} */ -// let res; -// -// if(pluck){ -// res = result; -// path = pluck; -// } -// else{ -// const tmp = result[i]; -// path = tmp.field; -// // skip when not a field entry (e.g. tags) -// if(!path) continue; -// res = tmp.result; -// } -// -// idx = index.get(path); -// enc = idx.encoder; -// tokenize = idx.tokenize; -// query_enc = encoder.get(enc); -// -// // re-encode query when encoder has changed or take cache from shared encoders -// if(typeof query_enc !== "string"){ -// query_enc = enc.encode(query); -// encoder.set(enc, query_enc); -// } -// -// // for every doc in results -// for(let j = 0; j < res.length; j++){ -// -// const doc = res[j]["doc"]; -// if(!doc) continue; -// const content = parse_simple(doc, path); -// if(!content) continue; -// const doc_org = content.trim().split(/\s+/); -// if(!doc_org.length) continue; -// -// let str = ""; -// let pos_matches = []; -// let length_matches_all = 0; -// -// // loop terms of encoded doc content -// for(let k = 0; k < doc_org.length; k++){ -// let doc_org_cur = doc_org[k]; -// let doc_org_cur_len = doc_org_cur.length; -// let doc_enc_cur = enc.encode(doc_org_cur); -// doc_enc_cur = doc_enc_cur.length > 1 -// ? doc_enc_cur.join(" ") -// : doc_enc_cur[0]; -// -// let found; -// -// if(doc_enc_cur && doc_org_cur){ -// -// let match = ""; -// let match_length = 0; -// -// // loop terms of encoded query content and determine the longest match -// for(let l = 0; l < query_enc.length; l++){ -// let query_enc_cur = query_enc[l]; -// if(!query_enc_cur) continue; -// let query_enc_cur_len = query_enc_cur.length; -// // add length from shrinking phonetic transformations (todo: add tests) -// query_enc_cur_len += doc_org_cur.length - doc_enc_cur.length; -// // skip query token when match length can't exceed previously highest found match -// if(match_length && query_enc_cur_len <= match_length){ -// continue; -// } -// const position = doc_enc_cur.indexOf(query_enc_cur); -// //console.log(doc_org_cur, doc_enc_cur, query_enc_cur, position) -// if(position > -1){ -// match = -// // prefix -// (position ? doc_org_cur.substring(0, position) : "") + -// // match -// markup_open + doc_org_cur.substring(position, position + query_enc_cur_len) + markup_close + -// // suffix -// (position + query_enc_cur_len < doc_org_cur_len ? doc_org_cur.substring(position + query_enc_cur_len) : ""); -// match_length = query_enc_cur_len; -// found = true; -// } -// } -// -// // apply the longest match -// if(match){ -// if(boundary){ -// if(!pos_matches.length && k) length_matches_all += ellipsis.length; -// // the overall length of all matches is used to check if matches exceeds the total boundary -// // if so, it can early stop further processing -// length_matches_all += match.length;//doc_org_cur_len + (str ? 1 : 0) + (k < doc_org.length - 1 ? ellipsis.length : 0); -// // the match positions are used to pick items for the final result more quickly -// pos_matches.push([ -// str.length + (str ? 1 : 0), -// str.length + (str ? 1 : 0) + match.length, -// k -// ]); -// } -// str += (str ? " " : "") + match; -// } -// } -// -// if(!found){ -// const text = doc_org[k]; -// str += (str ? " " : "") + text; -// } -// else if(boundary){ -// if(length_matches_all >= boundary){ -// // matches has reached total boundary -// break; -// } -// } -// } -// -// // the markup length does not apply to the total boundary -// let markup_length = pos_matches.length * (template.length - 2); -// -// // apply boundaries and align highlights -// if(boundary_before || boundary_after || (boundary && (str.length - markup_length) > boundary)){ -// -// let final = ""; -// let surrounded_length = (((((boundary + markup_length) - length_matches_all) / pos_matches.length) - ellipsis.length) / 2); -// //if(surrounded_length < 0) surrounded_length = 0; -// -// let before = boundary_before || ( -// surrounded_length > 0 -// ? Math.floor(surrounded_length + -// (boundary_after -// ? surrounded_length - boundary_after -// : 0)) -// : 0 -// ); -// let after = boundary_after || ( -// surrounded_length > 0 -// ? Math.ceil(surrounded_length + -// (boundary_before -// ? surrounded_length - boundary_before -// : 0)) -// : 0 -// ); -// -// //console.log(surrounded_length, before, after) -// -// for(let k = 0, cur, prev, next; k < pos_matches.length; k++){ -// -// prev = cur; -// cur = next || pos_matches[k]; -// next = pos_matches[k + 1]; -// -// let start = cur[0] - before; -// let end = cur[1] + after; -// let closed_left; -// let closed_right; -// -// // if(k){ -// // closed_left = 1; -// // } -// -// // apply right limit -// if(next && (end >= next[0] - before)){ -// end = cur[1] + (next[0] - cur[1]) / 2 | 0; -// start -= ellipsis.length + 1; -// closed_right = 1; -// } -// // apply left limit -// if(prev && (start <= prev[1] + after)){ -// start = cur[0] - (cur[0] - prev[1]) / 2 | 0; -// end += ellipsis.length + 1; -// closed_left = 1; -// -// // repeat right limit -// if(next && (end >= next[0] - before)){ -// end = cur[1] + (next[0] - cur[1]) / 2 | 0; -// closed_right = 1; -// } -// } -// -// //console.log(start, end, prev, cur, next); -// -// // do not clip terms -// if(!clip){ -// if(start){ -// if(str.charAt(start) === " "){ -// //start++; -// } -// else if(str.charAt(start - 1) !== " "){ -// start = str.indexOf(" ", start); -// start < 0 -// ? start = cur[0] -// : start;//++; -// } -// } -// if(end < str.length){ -// if(str.charAt(end - 1) === " "){ -// //end--; -// } -// else if(str.charAt(end) !== " "){ -// end = str.lastIndexOf(" ", end); -// end < cur[1] -// ? end = cur[1] -// : end++; -// } -// } -// } -// -// final += -// /*(final ? " " : "") +*/ -// (!closed_left && start > 0 ? ellipsis : "") + -// str.substring(start, end) + -// (!closed_right && cur[2] < doc_org.length - 1 ? ellipsis : ""); -// -// //console.log(final) -// } -// -// str = final; -// } -// -// if(merge){ -// str = str.replace(merge, " "); -// } -// -// res[j]["highlight"] = str; -// } -// -// if(pluck){ -// break; -// } -// } -// -// return result; -// } \ No newline at end of file +} \ No newline at end of file diff --git a/dist/module/document/search.js b/dist/module/document/search.js index 9417aea..b66ca6f 100644 --- a/dist/module/document/search.js +++ b/dist/module/document/search.js @@ -1,6 +1,6 @@ import { DocumentSearchOptions, DocumentSearchResults, EnrichedDocumentSearchResults, MergedDocumentSearchResults, MergedDocumentSearchEntry, EnrichedSearchResults, SearchResults, IntermediateSearchResults } from "../type.js"; -import { create_object, is_array, is_object, is_string } from "../common.js"; +import { create_object, is_array, is_object, is_string, inherit } from "../common.js"; import { intersect, intersect_union } from "../intersect.js"; import Document from "../document.js"; import Index from "../index.js"; @@ -46,10 +46,9 @@ Document.prototype.search = function (query, limit, options, _promises) { } if (options && options.cache) { - options.cache = /* suggest */ /* append: */ /* enrich */!1; + options.cache = !1; const res = this.searchCache(query, limit, options); - options.cache = /* tag? */ /* stringify */ /* stringify */ /* single param */ /* skip update: */ /* append: */ /* skip update: */ /* skip_update: */!0 /*await rows.hasNext()*/ /*await rows.hasNext()*/ - /*await rows.hasNext()*/; + options.cache = !0; return res; } @@ -105,16 +104,12 @@ Document.prototype.search = function (query, limit, options, _promises) { tag = [tag]; } - // ----------------------------- - // Tag-Search - // ----------------------------- - let pairs = []; for (let i = 0, field; i < tag.length; i++) { field = tag[i]; - // default array notation + if (field.field && field.tag) { const value = field.tag; if (value.constructor === Array) { @@ -124,29 +119,24 @@ Document.prototype.search = function (query, limit, options, _promises) { } else { pairs.push(field.field, value); } - } - // shorter object notation - else { - const keys = Object.keys(field); - for (let j = 0, key, value; j < keys.length; j++) { - key = keys[j]; - value = field[key]; - if (value.constructor === Array) { - for (let k = 0; k < value.length; k++) { - pairs.push(key, value[k]); - } - } else { - pairs.push(key, value); + } else { + const keys = Object.keys(field); + for (let j = 0, key, value; j < keys.length; j++) { + key = keys[j]; + value = field[key]; + if (value.constructor === Array) { + for (let k = 0; k < value.length; k++) { + pairs.push(key, value[k]); } + } else { + pairs.push(key, value); } } + } } - // tag used as pairs from this point tag = pairs; - // when tags is used and no query was set, - // then just return the tag indexes if (!query) { let promises = []; @@ -179,15 +169,14 @@ Document.prototype.search = function (query, limit, options, _promises) { result[j] = promises[j]; } } - return resolve || !!0 ? result : new Resolver(1 < result.length ? intersect(result, 1, 0, 0, suggest, boost) : result[0], self); + return resolve ? result : new Resolver(1 < result.length ? intersect( /** @type {!Array} */result, 1, 0, 0, suggest, boost) : result[0], self); }); } - return resolve || !!0 ? result : new Resolver(1 < result.length ? intersect(result, 1, 0, 0, suggest, boost) : result[0], this); + return resolve ? result : new Resolver(1 < result.length ? intersect( /** @type {!Array} */result, 1, 0, 0, suggest, boost) : result[0], this); } } - // upgrade pluck when missing if (!resolve && !pluck) { field = field || this.field; if (field) { @@ -202,7 +191,6 @@ Document.prototype.search = function (query, limit, options, _promises) { } } - // extend to multi field search by default if (field && field.constructor !== Array) { field = [field]; } @@ -216,15 +204,12 @@ Document.prototype.search = function (query, limit, options, _promises) { ) && !_promises && []; - // multi field search - // field could be a custom set of selected fields by this query - // db tag indexes are also included in this field list for (let i = 0, res, key, len; i < field.length; i++) { key = field[i]; if (this.db && this.tag) { - // tree is missing when it is a tag-only index (db) + if (!this.tree[i]) { continue; } @@ -261,32 +246,28 @@ Document.prototype.search = function (query, limit, options, _promises) { } } if (promises) { - promises[i] = index.search /*Async*/(query, limit, opt); - // restore enrich state + promises[i] = index.search(query, limit, opt); + opt && enrich && (opt.enrich = enrich); - // just collect and continue + continue; } else { res = index.search(query, limit, opt); - // restore enrich state + opt && enrich && (opt.enrich = enrich); } } len = res && (resolve ? res.length : res.result.length); - // todo when no term was matched but tag was retrieved extend suggestion to tags - // every field has to intersect against all selected tag fields if (tag && len) { const arr = []; let count = 0; - // tags are only applied in resolve phase when it's a db if (this.db && _promises) { if (!db_tag_search) { - // retrieve tag results assigned to it's field for (let y = field.length; y < _promises.length; y++) { let ids = _promises[y], len = ids && ids.length; @@ -296,14 +277,13 @@ Document.prototype.search = function (query, limit, options, _promises) { count++; arr.push(ids); } else if (!suggest) { - // no tags found - return resolve || !!0 ? result : new Resolver(result, this); + + return resolve ? result : new Resolver(result, this); } } } } else { - // tag[] are pairs at this line for (let y = 0, ids, len; y < tag.length; y += 2) { ids = this.tag.get(tag[y]); @@ -311,7 +291,7 @@ Document.prototype.search = function (query, limit, options, _promises) { if (suggest) { continue; } else { - return resolve || !!0 ? result : new Resolver(result, this); + return resolve ? result : new Resolver(result, this); } } @@ -322,20 +302,20 @@ Document.prototype.search = function (query, limit, options, _promises) { count++; arr.push(ids); } else if (!suggest) { - // no tags found - return resolve || !!0 ? result : new Resolver(result, this); + + return resolve ? result : new Resolver(result, this); } } } if (count) { - res = intersect_union(res, arr, resolve); // intersect(arr, limit, offset) + res = intersect_union(res, arr, resolve); len = res.length; if (!len && !suggest) { - // nothing matched - return resolve || !!0 ? res : new Resolver( /** @type {IntermediateSearchResults} */res, this); + + return resolve ? res : new Resolver( /** @type {IntermediateSearchResults} */res, this); } - // move counter back by 1 + count--; } } @@ -345,24 +325,23 @@ Document.prototype.search = function (query, limit, options, _promises) { result.push(res); count++; } else if (1 === field.length) { - // fast path: nothing matched - return resolve || !!0 ? result : new Resolver(result, this); + + return resolve ? result : new Resolver(result, this); } } if (promises) { if (this.db) { - // todo when a tag index is never a search index this could be extracted - // push tag promises to the end + if (tag && tag.length && !db_tag_search) { for (let y = 0; y < tag.length; y += 2) { - // it needs to retrieve data from tag pairs + const index = this.index.get(tag[y]); if (!index) { if (suggest) { continue; } else { - return resolve || !!0 ? result : new Resolver(result, this); + return resolve ? result : new Resolver(result, this); } } @@ -373,14 +352,13 @@ Document.prototype.search = function (query, limit, options, _promises) { const self = this; - // TODO unroll this recursion return Promise.all(promises).then(function (result) { - return result.length ? self.search(query, limit, options, /* promises: */result) : result; + return result.length ? self.search(query, limit, options, result) : result; }); } if (!count) { - return resolve || !!0 ? result : new Resolver(result, this); + return resolve ? result : new Resolver(result, this); } if (pluck && (!enrich || !this.store)) { result = result[0]; @@ -399,18 +377,16 @@ Document.prototype.search = function (query, limit, options, _promises) { if (enrich && res.length && "undefined" == typeof res[0].doc) { if (!this.db) { - // if(res.length){ + res = apply_enrich.call(this, res); - // } } else { - // todo - // the documents are stored on the first field + promises.push(res = this.index.get(this.field[0]).db.enrich(res)); } } if (pluck) { - return resolve || !!0 ? highlight ? highlight_fields( /** @type {string} */query, res, this.index, pluck, highlight) : /** @type {SearchResults|EnrichedSearchResults} */res : new Resolver( /** @type {IntermediateSearchResults} */res, this); + return resolve ? highlight ? highlight_fields( /** @type {string} */query, res, this.index, pluck, highlight) : /** @type {SearchResults|EnrichedSearchResults} */res : new Resolver( /** @type {IntermediateSearchResults} */res, this); } result[i] = { @@ -425,22 +401,19 @@ Document.prototype.search = function (query, limit, options, _promises) { for (let j = 0; j < promises.length; j++) { result[j].result = promises[j]; } - return merge ? merge_fields(result) : highlight ? highlight_fields( /** @type {string} */query, result, self.index, pluck, highlight) : /** @type {DocumentSearchResults} */result; + if (highlight) { + result = highlight_fields( /** @type {string} */query, result, self.index, pluck, highlight); + } + return merge ? merge_fields(result) : /** @type {DocumentSearchResults} */result; }); } - return merge ? merge_fields(result) : highlight ? highlight_fields( /** @type {string} */query, result, this.index, pluck, highlight) : /** @type {DocumentSearchResults} */result; + if (highlight) { + result = highlight_fields( /** @type {string} */query, result, this.index, pluck, highlight); + } + return merge ? merge_fields(result) : /** @type {DocumentSearchResults} */result; }; -function inherit(target_value, default_value) { - return "undefined" == typeof target_value ? default_value : target_value; -} - -// todo support Resolver -// todo when searching through multiple fields each term should -// be found at least by one field to get a valid match without -// using suggestion explicitly - /** * @param {DocumentSearchResults} fields * @return {MergedDocumentSearchResults} @@ -448,24 +421,31 @@ function inherit(target_value, default_value) { function merge_fields(fields) { /** @type {MergedDocumentSearchResults} */ const final = [], - set = create_object(); + group_field = create_object(), + group_highlight = create_object(); - for (let i = 0, field, res; i < fields.length; i++) { + for (let i = 0, field, key, res, id, entry, tmp, highlight; i < fields.length; i++) { field = fields[i]; + key = field.field; res = field.result; - for (let j = 0, id, entry, tmp; j < res.length; j++) { + for (let j = 0; j < res.length; j++) { entry = res[j]; - // upgrade flat results - if ("object" != typeof entry) { - entry = { id: entry }; - } - id = entry.id; - tmp = set[id]; + + "object" != typeof entry ? entry = { id: id = entry } : id = entry.id; + tmp = group_field[id]; if (!tmp) { - entry.field = set[id] = [field.field]; + entry.field = group_field[id] = [key]; final.push( /** @type {MergedDocumentSearchEntry} */entry); } else { - tmp.push(field.field); + tmp.push(key); + } + if (highlight = entry.highlight) { + tmp = group_highlight[id]; + if (!tmp) { + group_highlight[id] = tmp = {}; + entry.highlight = tmp; + } + tmp[key] = highlight; } } } @@ -476,13 +456,24 @@ function merge_fields(fields) { * @this {Document} */ -function get_tag(tag, key, limit, offset) { +function get_tag(tag, key, limit, offset, enrich) { + let res = this.tag.get(tag); - if (!res) { - return []; + if (!res) return []; + res = res.get(key); + if (!res) return []; + let len = res.length - offset; + + if (0 < len) { + if (limit && len > limit || offset) { + res = res.slice(offset, offset + limit); + } + if (enrich) { + res = apply_enrich.call(this, res); + } } - res = res && res.get(key); - res && res.length - offset; + + return res; } /** diff --git a/dist/module/encoder.js b/dist/module/encoder.js index da772a0..72329f3 100644 --- a/dist/module/encoder.js +++ b/dist/module/encoder.js @@ -3,74 +3,62 @@ import { create_object, merge_option } from "./common.js"; import normalize_polyfill from "./charset/polyfill.js"; import { EncoderOptions } from "./type.js"; -/* - -Custom Encoder ----------------- - -// Split a passed string into an Array of words: -function englishEncoder(string){ - return string.toLowerCase().split(/[^a-z]+/) -} - -// For CJK split a passed string into an Array of chars: -function chineseEncoder(string){ - return string.replace(/\s+/, "").split("") -} - -// Alternatively do not split the input: -function fixedEncoder(string){ - return [string] -} - -Built-in Encoder ----------------------------- -The main workflow follows an increasing strategy, -starting from a simple .toLowerCase() to full RegExp -Pipeline: - 1. apply this.normalize (charset normalization) - applied on the whole input string e.g. lowercase, - everything you put later into (filter, matcher, stemmer, mapper, etc.) - has to be normalized by definition, because it won't apply to them automatically - 2. apply this.prepare (custom function, string in - string out) - 3 split numerics into triplets - 4. split input into terms (by one of them: split/include/exclude) - 5. pre-encoded term deduplication - 6. apply this.filter (stop-words) - 7. apply this.stemmer (replace term endings) - 8. apply this.mapper (replace chars) - 9. apply this.dedupe (letter deduplication) - 10. apply this.matcher (replace terms) - 11. apply this.replacer (custom regex) - 12. post-encoded term deduplication - 13. apply this.finalize (custom function, array in - array out) +/* + +Custom Encoder +---------------- + +function englishEncoder(string){ + return string.toLowerCase().split(/[^a-z]+/) +} + +function chineseEncoder(string){ + return string.replace(/\s+/, "").split("") +} + +function fixedEncoder(string){ + return [string] +} + +Built-in Encoder +---------------------------- +The main workflow follows an increasing strategy, +starting from a simple .toLowerCase() to full RegExp +Pipeline: + 1. apply this.normalize (charset normalization) + applied on the whole input string e.g. lowercase, + everything you put later into (filter, matcher, stemmer, mapper, etc.) + has to be normalized by definition, because it won't apply to them automatically + 2. apply this.prepare (custom function, string in - string out) + 3 split numerics into triplets + 4. split input into terms (by one of them: split/include/exclude) + 5. pre-encoded term deduplication + 6. apply this.filter (stop-words) + 7. apply this.stemmer (replace term endings) + 8. apply this.mapper (replace chars) + 9. apply this.dedupe (letter deduplication) + 10. apply this.matcher (replace terms) + 11. apply this.replacer (custom regex) + 12. post-encoded term deduplication + 13. apply this.finalize (custom function, array in - array out) */ const whitespace = /[^\p{L}\p{N}]+/u, numeric_split_length = /(\d{3})/g, numeric_split_prev_char = /(\D)(\d{3})/g, numeric_split_next_char = /(\d{3})(\D)/g, - normalize = /*"".normalize &&*//[\u0300-\u036f]/g; // /[\p{Z}\p{S}\p{P}\p{C}]+/u; -//const numeric_split = /(\d{3})/g; + normalize = /[\u0300-\u036f]/g; -//.replace(/(\d{3})/g, "$1 ") -//.replace(/([^\d])([\d])/g, "$1 $2") -//.replace(/([\d])([^\d])/g, "$1 $2") -// '´`’ʼ., -//const normalize_mapper = SUPPORT_CHARSET && !normalize && normalize_polyfill; - -/** - * @param {EncoderOptions=} options - * @constructor +/** + * @param {EncoderOptions=} options + * @constructor */ export default function Encoder(options = {}) { if (!this || this.constructor !== Encoder) { - // let args = Array.prototype.slice.call(arguments); - // args.unshift(Encoder); - // return new (Encoder.bind.apply(Encoder, args)); + return new Encoder(...arguments); } @@ -83,27 +71,16 @@ export default function Encoder(options = {}) { } } -/** - * @param {!EncoderOptions} options +/** + * @param {!EncoderOptions} options */ Encoder.prototype.assign = function (options) { - /** - * pre-processing string input - * @type {Function|boolean} + /** + * pre-processing string input + * @type {Function|boolean} */ - this.normalize = /** @type {Function|boolean} */merge_option(options.normalize, /* tag? */ /* stringify */ /* stringify */ /* single param */ /* skip update: */ /* append: */ /* skip update: */ /* skip_update: */ /* skip deletion */!0 /*await rows.hasNext()*/ - /*await rows.hasNext()*/ /*await rows.hasNext()*/, this.normalize); - - // { - // letter: true, - // number: true, - // whitespace: true, - // symbol: true, - // punctuation: true, - // control: true, - // char: "" - // } + this.normalize = /** @type {Function|boolean} */merge_option(options.normalize, !0, this.normalize); let include = options.include, tmp = include || options.exclude || options.split, @@ -114,7 +91,7 @@ Encoder.prototype.assign = function (options) { if ("object" == typeof tmp && tmp.constructor !== RegExp) { let regex = ""; numeric = !include; - // split on whitespace by default + include || (regex += "\\p{Z}"); if (tmp.letter) { regex += "\\p{L}"; @@ -137,55 +114,46 @@ Encoder.prototype.assign = function (options) { } try { - // https://github.com/nextapps-de/flexsearch/issues/410 - /** - * split string input into terms - * @type {string|RegExp|boolean|null} + + /** + * split string input into terms + * @type {string|RegExp|boolean|null} */ this.split = new RegExp("[" + (include ? "^" : "") + regex + "]+", "u"); } catch (e) { - // fallback to a simple whitespace splitter + this.split = /\s+/; } } else { this.split = /** @type {string|RegExp|boolean} */tmp; - // determine numeric encoding - numeric = /* suggest */ /* append: */ /* enrich */!1 === tmp || 2 > "a1a".split(tmp).length; + + numeric = !1 === tmp || 2 > "a1a".split(tmp).length; } this.numeric = merge_option(options.numeric, numeric); } else { try { - // https://github.com/nextapps-de/flexsearch/issues/410 + this.split = /** @type {string|RegExp|boolean} */merge_option(this.split, whitespace); } catch (e) { - // fallback to a simple whitespace splitter + this.split = /\s+/; } this.numeric = merge_option(options.numeric, merge_option(this.numeric, !0)); } - /** - * post-processing terms - * @type {Function|null} + /** + * post-processing terms + * @type {Function|null} */ this.prepare = /** @type {Function|null} */merge_option(options.prepare, null, this.prepare); - /** - * final processing - * @type {Function|null} + /** + * final processing + * @type {Function|null} */ this.finalize = /** @type {Function|null} */merge_option(options.finalize, null, this.finalize); - // assign the normalization fallback to the mapper - // if(SUPPORT_CHARSET && !normalize){ - // this.mapper = new Map( - // /** @type {Array>} */ ( - // normalize_polyfill - // ) - // ); - // } - tmp = options.filter; this.filter = "function" == typeof tmp ? tmp : merge_option(tmp && new Set(tmp), null, this.filter); this.dedupe = merge_option(options.dedupe, !0, this.dedupe); @@ -197,32 +165,21 @@ Encoder.prototype.assign = function (options) { this.maxlength = merge_option(options.maxlength, 1024, this.maxlength); this.rtl = merge_option(options.rtl, !1, this.rtl); - // auto-balanced cache this.cache = tmp = merge_option(options.cache, !0, this.cache); if (tmp) { - this.timer = null;this.cache_size = "number" == typeof tmp ? tmp : 2e5; + this.timer = null; + this.cache_size = "number" == typeof tmp ? tmp : 2e5; this.cache_enc = new Map(); this.cache_term = new Map(); this.cache_enc_length = 128; this.cache_term_length = 128; } - // regex temporary state this.matcher_str = ""; this.matcher_test = null; this.stemmer_str = ""; this.stemmer_test = null; - // prebuilt - // if(this.filter && this.split){ - // for(const key of this.filter){ - // const tmp = key.replace(this.split, ""); - // if(key !== tmp){ - // this.filter.delete(key); - // this.filter.add(tmp); - // } - // } - // } if (this.matcher) { for (const key of this.matcher.keys()) { this.matcher_str += (this.matcher_str ? "|" : "") + key; @@ -234,15 +191,6 @@ Encoder.prototype.assign = function (options) { } } - // if(SUPPORT_COMPRESSION){ - // this.compression = merge_option(options.compress || options.compression, 0, this.compression); - // if(this.compression && !table){ - // table = new Array(radix); - // for(let i = 0; i < radix; i++) table[i] = i + 33; - // table = String.fromCharCode.apply(null, table); - // } - // } - return this; }; @@ -257,8 +205,8 @@ Encoder.prototype.addStemmer = function (match, replace) { Encoder.prototype.addFilter = function (term) { if ("function" == typeof term) { - // does not support merge yet - this.filter = term; //merge_option(term, term, this.filter); + + this.filter = term; } else { this.filter || (this.filter = new Set()); this.filter.add(term); @@ -267,19 +215,19 @@ Encoder.prototype.addFilter = function (term) { return this; }; -/** - * Replace a single char - * @param {string} char_match - * @param {string} char_replace - * @return {Encoder} - * @suppress {invalidCasts} +/** + * Replace a single char + * @param {string} char_match + * @param {string} char_replace + * @return {Encoder} + * @suppress {invalidCasts} */ Encoder.prototype.addMapper = function (char_match, char_replace) { - // regex: + if ("object" == typeof char_match) { return this.addReplacer( /** @type {RegExp} */char_match, char_replace); } - // not a char: + if (1 < char_match.length) { return this.addMatcher(char_match, char_replace); } @@ -289,20 +237,19 @@ Encoder.prototype.addMapper = function (char_match, char_replace) { return this; }; -/** - * Replace a string - * @param {string} match - * @param {string} replace - * @return {Encoder} - * @suppress {invalidCasts} +/** + * Replace a string + * @param {string} match + * @param {string} replace + * @return {Encoder} + * @suppress {invalidCasts} */ Encoder.prototype.addMatcher = function (match, replace) { - // regex: + if ("object" == typeof match) { return this.addReplacer( /** @type {RegExp} */match, replace); } - // a single char: - // only downgrade when dedupe is on or mapper already was filled + if (2 > match.length && (this.dedupe || this.mapper)) { return this.addMapper(match, replace); } @@ -314,11 +261,11 @@ Encoder.prototype.addMatcher = function (match, replace) { return this; }; -/** - * @param {RegExp} regex - * @param {string} replace - * @return {Encoder} - * @suppress {invalidCasts} +/** + * @param {RegExp} regex + * @param {string} replace + * @return {Encoder} + * @suppress {invalidCasts} */ Encoder.prototype.addReplacer = function (regex, replace) { if ("string" == typeof regex) { @@ -330,10 +277,10 @@ Encoder.prototype.addReplacer = function (regex, replace) { return this; }; -/** - * @param {!string} str - * @param {boolean=} dedupe_terms Note: term deduplication will break the context chain - * @return {!Array} +/** + * @param {!string} str + * @param {boolean=} dedupe_terms Note: term deduplication will break the context chain + * @return {!Array} */ Encoder.prototype.encode = function (str, dedupe_terms) { @@ -347,7 +294,6 @@ Encoder.prototype.encode = function (str, dedupe_terms) { } } - // apply charset normalization if (this.normalize) { if ("function" == typeof this.normalize) { str = this.normalize(str); @@ -358,37 +304,21 @@ Encoder.prototype.encode = function (str, dedupe_terms) { } } - // apply custom encoder (can replace split) if (this.prepare) { str = this.prepare(str); } - // split numbers into triplets if (this.numeric && 3 < str.length) { str = str.replace(numeric_split_prev_char, "$1 $2").replace(numeric_split_next_char, "$1 $2").replace(numeric_split_length, "$1 "); } - // if(this.matcher && (str.length > 1)){ - // this.matcher_test || ( - // this.matcher_test = new RegExp("(" + this.matcher_str + ")", "g") - // ); - // str = str.replace(this.matcher_test, match => this.matcher.get(match)); - // } - - // if(this.stemmer){ - // this.stemmer_test || ( - // this.stemmer_test = new RegExp("(?!\\b)(" + this.stemmer_str + ")(\\b|_)", "g") - // ); - // str = str.replace(this.stemmer_test, match => this.stemmer.get(match)); - // } - const skip = !(this.dedupe || this.mapper || this.filter || this.matcher || this.stemmer || this.replacer); let final = [], dupes = create_object(), last_term, last_term_enc, words = this.split || "" === this.split ? str.split( /** @type {string|RegExp} */this.split) : [str]; - // str; + for (let i = 0, word, base; i < words.length; i++) { @@ -433,41 +363,18 @@ Encoder.prototype.encode = function (str, dedupe_terms) { } } - // from here minlength should not apply again - // when the input string is further shrinking - - // it needs to apply stemmer before bigger transformations - // it needs to apply stemmer after filter (user -> us -> filter out) if (this.stemmer) { - // for(const item of this.stemmer){ - // const key = item[0]; - // const value = item[1]; - // if(word.length > key.length && word.endsWith(key)){ - // word = word.substring(0, word.length - key.length) + value; - // break; - // } - // // const position = word.length - key.length; - // // if(position > 0 && word.substring(position) === key){ - // // word = word.substring(0, position) + value; - // // break; - // // } - // } - // todo compare advantages when filter/stemmer are also encoded this.stemmer_test || (this.stemmer_test = new RegExp("(?!^)(" + this.stemmer_str + ")$")); let old; - // loop stemmer as long as anything has matched - // just terms with length > 2 should need a stemmer (its -> it) - // the minlength also prevents stemmer looping to cut off everything while (old !== word && 2 < word.length) { old = word; word = word.replace(this.stemmer_test, match => this.stemmer.get(match)); } } - // apply mapper and collapsing if (word && (this.mapper || this.dedupe && 1 < word.length)) { let final = ""; for (let i = 0, prev = "", char, tmp; i < word.length; i++) { @@ -480,24 +387,17 @@ Encoder.prototype.encode = function (str, dedupe_terms) { word = final; } - // apply matcher if (this.matcher && 1 < word.length) { this.matcher_test || (this.matcher_test = new RegExp("(" + this.matcher_str + ")", "g")); word = word.replace(this.matcher_test, match => this.matcher.get(match)); } - // apply custom regex if (word && this.replacer) { for (let i = 0; word && i < this.replacer.length; i += 2) { word = word.replace(this.replacer[i], this.replacer[i + 1]); } } - // slower variants for removing same chars in a row: - //word = word.replace(/([^0-9])\1+/g, "$1"); - //word = word.replace(/(.)\1+/g, "$1"); - //word = word.replace(/(?<=(.))\1+/g, ""); - if (this.cache && base.length <= this.cache_term_length) { this.cache_term.set(base, word); if (this.cache_term.size > this.cache_size) { @@ -543,41 +443,8 @@ export function fallback_encoder(str) { return str.normalize("NFKD").replace(normalize, "").toLowerCase().trim().split(/\s+/); } -// Encoder.prototype.compress = function(str) { -// -// //return str; -// //if(!str) return str; -// -// if(SUPPORT_CACHE && this.cache && str.length <= this.cache_term_length){ -// if(this.timer){ -// if(this.cache_cmp.has(str)){ -// return this.cache_cmp.get(str); -// } -// } -// else{ -// this.timer = setTimeout(clear, 0, this); -// } -// } -// -// const result = typeof this.compression === "function" -// ? this.compression(str) -// : hash(str); //window.hash(str); -// -// if(SUPPORT_CACHE && this.cache && str.length <= this.cache_term_length){ -// this.cache_cmp.set(str, result); -// this.cache_cmp.size > this.cache_size && -// this.cache_cmp.clear(); -// } -// -// return result; -// }; - -// function hash(str){ -// return str; -// } - -/** - * @param {Encoder} self +/** + * @param {Encoder} self */ function clear(self) { self.timer = null; diff --git a/dist/module/index.js b/dist/module/index.js index 24ca24f..07160af 100644 --- a/dist/module/index.js +++ b/dist/module/index.js @@ -14,7 +14,7 @@ import { KeystoreMap, KeystoreSet } from "./keystore.js"; import { is_array, is_string } from "./common.js"; import { exportIndex, importIndex, serialize } from "./serialize.js"; import { remove_index } from "./index/remove.js"; -//import default_encoder from "./charset/latin/default.js"; + import apply_preset from "./preset.js"; import apply_async from "./async.js"; import tick from "./profiler.js"; @@ -39,13 +39,13 @@ export default function Index(options, _register) { /** @type {*} */ let tmp = options.context; /** @type ContextOptions */ - const context = /** @type ContextOptions */ /* tag? */ /* stringify */ /* stringify */ /* single param */ /* skip update: */ /* append: */ /* skip update: */ /* skip_update: */ /* skip deletion */!0 /*await rows.hasNext()*/ /*await rows.hasNext()*/ /*await rows.hasNext()*/ === tmp ? { depth: 1 } : tmp || {}, - encoder = is_string(options.encoder) ? Charset[options.encoder] : options.encode || options.encoder || {} /*default_encoder*/; + const context = /** @type ContextOptions */!0 === tmp ? { depth: 1 } : tmp || {}, + encoder = is_string(options.encoder) ? Charset[options.encoder] : options.encode || options.encoder || {}; /** @type Encoder */ this.encoder = encoder.encode ? encoder : "object" == typeof encoder ? new Encoder( /** @type {EncoderOptions} */encoder) : { encode: encoder }; - this.compress = options.compress || options.compression || /* suggest */ /* append: */ /* enrich */!1; + this.compress = options.compress || options.compression || !1; this.resolution = options.resolution || 9; @@ -156,32 +156,6 @@ Index.prototype.update = function (id, content) { return res && res.then ? res.then(() => self.add(id, content)) : this.add(id, content); }; -// /** -// * @param map -// * @return {number} -// */ -// -// function cleanup_index(map){ -// -// let count = 0; -// -// if(is_array(map)){ -// for(let i = 0, arr; i < map.length; i++){ -// (arr = map[i]) && -// (count += arr.length); -// } -// } -// else for(const item of map.entries()){ -// const key = item[0]; -// const value = item[1]; -// const tmp = cleanup_index(value); -// tmp ? count += tmp -// : map.delete(key); -// } -// -// return count; -// } - Index.prototype.cleanup = function () { if (!this.fastupdate) { @@ -189,10 +163,8 @@ Index.prototype.cleanup = function () { } remove_index(this.map); - //cleanup_index(this.map); - this.depth && - //cleanup_index(this.ctx); - remove_index(this.ctx); + + this.depth && remove_index(this.ctx); return this; }; diff --git a/dist/module/index/add.js b/dist/module/index/add.js index 03a7634..cc6cdc6 100644 --- a/dist/module/index/add.js +++ b/dist/module/index/add.js @@ -4,11 +4,6 @@ import Index, { autoCommit } from "../index.js"; import default_compress from "../compress.js"; import { KeystoreArray } from "../keystore.js"; -// TODO: -// string + number as text -// boolean, null, undefined as ? - - /** * @param {!number|string} id * @param {!string} content @@ -20,9 +15,6 @@ Index.prototype.add = function (id, content, _append, _skip_update) { if (content && (id || 0 === id)) { - // todo check skip_update - //_skip_update = false; - if (!_skip_update && !_append) { if (this.reg.has(id)) { return this.update(id, content); @@ -30,15 +22,11 @@ Index.prototype.add = function (id, content, _append, _skip_update) { } const depth = this.depth; - // do not force a string as input - // https://github.com/nextapps-de/flexsearch/issues/432 + content = this.encoder.encode(content, !depth); const word_length = content.length; if (word_length) { - - // check context dupes to skip all contextual redundancy along a document - const dupes_ctx = create_object(), dupes = create_object(), resolution = this.resolution; @@ -49,9 +37,6 @@ Index.prototype.add = function (id, content, _append, _skip_update) { term_length = term.length; - // todo check context search - // this check also wasn't applied on search, so it's useless here - // skip dupes will break the context chain if (term_length && (depth || !dupes[term])) { let score = this.score ? this.score(content, term, i, null, 0) : get_score(resolution, word_length, i), token = ""; @@ -71,10 +56,10 @@ Index.prototype.add = function (id, content, _append, _skip_update) { } break; } - // fallthrough to next case when term length < 3 + case "bidirectional": case "reverse": - // skip last round (this token exist already in "forward") + if (1 < term_length) { for (let x = term_length - 1; 0 < x; x--) { token = term[this.rtl ? term_length - 1 - x : x] + token; @@ -84,7 +69,6 @@ Index.prototype.add = function (id, content, _append, _skip_update) { token = ""; } - // fallthrough to next case to apply forward also case "forward": if (1 < term_length) { for (let x = 0; x < term_length; x++) { @@ -94,16 +78,12 @@ Index.prototype.add = function (id, content, _append, _skip_update) { break; } - // fallthrough to next case when token has a length of 1 default: - // "strict": this.push_index(dupes, term, score, id, _append); - // context is just supported by tokenizer "strict" + if (depth) { if (1 < word_length && i < word_length - 1) { - - // check inner dupes to skip repeating words in the current context const dupes_inner = create_object(), resolution = this.resolution_ctx, keyword = term, @@ -138,8 +118,7 @@ Index.prototype.add = function (id, content, _append, _skip_update) { } if (this.db) { - // when the term has no valid content (e.g. empty), - // then it was not added to the ID registry for removal + content || this.commit_task.push({ del: id }); this.commit_auto && autoCommit(this); } @@ -186,28 +165,25 @@ Index.prototype.push_index = function (dupes, term, score, id, append, keyword) tmp = arr.get(term); tmp ? arr = tmp : arr.set(term, arr = tmp = []); - // the ID array will be upgraded dynamically + arr = arr[score] || (arr[score] = []); if (!append || !arr.includes(id)) { - - // auto-upgrade to keystore array if max size exceeded - if (2147483647 === arr.length /*|| !(arr instanceof KeystoreArray)*/) { - const keystore = new KeystoreArray(arr); - if (this.fastupdate) { - for (let value of this.reg.values()) { - if (value.includes(arr)) { - value[value.indexOf(arr)] = keystore; - } + if (2147483647 === arr.length) { + const keystore = new KeystoreArray(arr); + if (this.fastupdate) { + for (let value of this.reg.values()) { + if (value.includes(arr)) { + value[value.indexOf(arr)] = keystore; } } - tmp[score] = arr = keystore; } + tmp[score] = arr = keystore; + } arr.push(id); - // add a reference to the register for fast updates if (this.fastupdate) { const tmp = this.reg.get(id); tmp ? tmp.push(arr) : this.reg.set(id, [arr]); @@ -227,23 +203,5 @@ Index.prototype.push_index = function (dupes, term, score, id, append, keyword) function get_score(resolution, length, i, term_length, x) { - // console.log("resolution", resolution); - // console.log("length", length); - // console.log("term_length", term_length); - // console.log("i", i); - // console.log("x", x); - // console.log((resolution - 1) / (length + (term_length || 0)) * (i + (x || 0)) + 1); - - // the first resolution slot is reserved for the best match, - // when a query matches the first word(s). - - // also to stretch score to the whole range of resolution, the - // calculation is shift by one and cut the floating point. - // this needs the resolution "1" to be handled additionally. - - // do not stretch the resolution more than the term length will - // improve performance and memory, also it improves scoring in - // most cases between a short document and a long document - return i && 1 < resolution ? length + (term_length || 0) <= resolution ? i + (x || 0) : 0 | (resolution - 1) / (length + (term_length || 0)) * (i + (x || 0)) + 1 : 0; } \ No newline at end of file diff --git a/dist/module/index/remove.js b/dist/module/index/remove.js index 2675be2..63cf421 100644 --- a/dist/module/index/remove.js +++ b/dist/module/index/remove.js @@ -14,13 +14,9 @@ Index.prototype.remove = function (id, _skip_deletion) { if (this.fastupdate) { - // fast updates did not fully clean up the key entries - for (let i = 0, tmp; i < refs.length; i++) { if (tmp = refs[i]) { - // todo check - //if(tmp.length < 1) throw new Error("invalid length"); - //if(tmp.indexOf(id) < 0) throw new Error("invalid id"); + if (2 > tmp.length) { tmp.pop(); } else { @@ -29,51 +25,10 @@ Index.prototype.remove = function (id, _skip_deletion) { } } } - - // todo variation which cleans up, requires to push [ctx, key] instead of arr to the index.reg - // for(let i = 0, arr, term, keyword; i < refs.length; i++){ - // arr = refs[i]; - // if(typeof arr === "string"){ - // arr = this.map.get(term = arr); - // } - // else{ - // arr = this.ctx.get(keyword = arr[0]); - // arr && (arr = arr.get(arr[1])); - // } - // let counter = 0, found; - // if(arr && arr.length){ - // for(let j = 0, tmp; j < arr.length; j++){ - // if((tmp = arr[j])){ - // if(!found && tmp.length){ - // const index = tmp.indexOf(id); - // if(index >= 0){ - // tmp.splice(index, 1); - // // the index [ctx, key]:[res, id] is unique - // found = 1; - // } - // } - // if(tmp.length){ - // counter++; - // if(found){ - // break; - // } - // } - // else{ - // delete arr[j]; - // } - // } - // } - // } - // if(!counter){ - // keyword - // ? this.ctx.delete(keyword) - // : this.map.delete(term); - // } - // } } else { - remove_index(this.map, id /*, this.resolution*/); - this.depth && remove_index(this.ctx, id /*, this.resolution_ctx*/); + remove_index(this.map, id); + this.depth && remove_index(this.ctx, id); } _skip_deletion || this.reg.delete(id); @@ -82,10 +37,8 @@ Index.prototype.remove = function (id, _skip_deletion) { if (this.db) { this.commit_task.push({ del: id }); this.commit_auto && autoCommit(this); - //return this.db.remove(id); } - // the cache could be used outside the InMemory store if (this.cache) { this.cache.remove(id); } @@ -101,9 +54,6 @@ Index.prototype.remove = function (id, _skip_deletion) { */ export function remove_index(map, id) { - - // a check counter of filled resolution slots - // to prevent removing the field let count = 0; @@ -111,7 +61,7 @@ export function remove_index(map, id) { for (let x = 0, arr, index; x < map.length; x++) { if ((arr = map[x]) && arr.length) { if ("undefined" == typeof id) { - //count += arr.length; + count++; } else { index = arr.indexOf(id); @@ -120,10 +70,10 @@ export function remove_index(map, id) { arr.splice(index, 1); count++; } else { - // remove resolution slot + delete map[x]; } - // the index key:[res, id] is unique + break; } else { count++; diff --git a/dist/module/index/search.js b/dist/module/index/search.js index d9c8921..5fb6c4e 100644 --- a/dist/module/index/search.js +++ b/dist/module/index/search.js @@ -30,9 +30,9 @@ Index.prototype.search = function (query, limit, options) { } if (options && options.cache) { - options.cache = /* suggest */ /* append: */ /* enrich */!1; + options.cache = !1; const res = this.searchCache(query, limit, options); - options.cache = /* tag? */ /* stringify */ /* stringify */ /* single param */ /* skip update: */ /* append: */ /* skip update: */ /* skip_update: */ /* skip deletion */!0 /*await rows.hasNext()*/ /*await rows.hasNext()*/ /*await rows.hasNext()*/; + options.cache = !0; return res; } @@ -46,10 +46,7 @@ Index.prototype.search = function (query, limit, options) { tag, boost, resolution, - - // enrich is internally used just - // for the persistent indexes - enrich; + enrich; if (options) { @@ -70,146 +67,39 @@ Index.prototype.search = function (query, limit, options) { } context = this.depth && !1 !== context; - // do not force a string as input - // https://github.com/nextapps-de/flexsearch/issues/432 + /** @type {Array} */ let query_terms = this.encoder.encode(query, !context); length = query_terms.length; limit = /** @type {!number} */limit || (resolve ? 100 : 0); - // fast path single term if (1 === length) { - return single_term_query.call(this, query_terms[0], // term - "", // ctx - limit, offset, resolve, enrich, tag); + return single_term_query.call(this, query_terms[0], "", limit, offset, resolve, enrich, tag); } - // fast path single context if (2 === length && context && !suggest) { - return single_term_query.call(this, query_terms[1], // term - query_terms[0], // ctx - limit, offset, resolve, enrich, tag); + return single_term_query.call(this, query_terms[1], query_terms[0], limit, offset, resolve, enrich, tag); } - // let maxlength = 0; - // let minlength = 0; - // - // if(length > 1){ - // - // // term deduplication will break the context chain - // // todo add context to dupe check - // const dupes = create_object(); - // const query_new = []; - // - // // if(context){ - // // keyword = query_terms[0]; - // // dupes[keyword] = 1; - // // query_new.push(keyword); - // // maxlength = minlength = keyword.length; - // // i = 1; - // // } - // - // for(let i = 0, term; i < length; i++){ - // - // term = query_terms[i]; - // - // if(term && !dupes[term]){ - // - // // todo add keyword check - // // this fast path can't apply to persistent indexes - // if(!suggest && !(SUPPORT_PERSISTENT && this.db) && !this.get_array(term/*, keyword*/)){ - // - // // fast path "not found" - // return !SUPPORT_RESOLVER || resolve - // ? result - // : new Resolver(result); - // } - // else{ - // - // query_new.push(term); - // dupes[term] = 1; - // } - // - // const term_length = term.length; - // maxlength = Math.max(maxlength, term_length); - // minlength = minlength ? Math.min(minlength, term_length) : term_length; - // } - // // else if(term && (!this.depth || context === false)){ - // // query_new.push(term); - // // } - // } - // - // query_terms = query_new; - // length = query_terms.length; - // } - // - // // the term length could be changed after deduplication - // - // if(!length){ - // return !SUPPORT_RESOLVER || resolve - // ? result - // : new Resolver(result); - // } - // - // // fast path single term - // if(length === 1){ - // return single_term_query.call( - // this, - // query_terms[0], // term - // "", // ctx - // limit, - // offset, - // resolve, - // enrich, - // tag - // ); - // } - // - // // fast path single context - // if(length === 2 && context && !suggest){ - // return single_term_query.call( - // this, - // query_terms[0], // term - // query_terms[1], // ctx - // limit, - // offset, - // resolve, - // enrich, - // tag - // ); - // } - let dupes = create_object(), index = 0, keyword; - //if(length > 1){ if (context) { - // start with context right away + keyword = query_terms[0]; index = 1; } - // todo - // else if(maxlength > 9 && (maxlength / minlength) > 3){ - // // sorting terms will break the context chain - // // bigger terms has less occurrence - // // this might also reduce the intersection task - // // todo check intersection order - // query_terms.sort(sort_by_length_down); - // } - //} if (!resolution && 0 !== resolution) { resolution = keyword ? this.resolution_ctx : this.resolution; } - // from this point there are just multi-term queries - if (this.db) { if (this.db.search) { - // when the configuration is not supported it returns false + const result = this.db.search(this, query_terms, limit, offset, suggest, resolve, enrich, tag); if (!1 !== result) return result; } @@ -234,16 +124,12 @@ Index.prototype.search = function (query, limit, options) { if (keyword) { - // the context is a moving window where the keyword is going forward like a cursor - // 1. when suggestion enabled just forward keyword if term was found - // 2. as long as the result is empty forward the pointer also if (!suggest || !arr || !result.length) { keyword = term; } } } - // fallback to non-contextual search when no result was found if (suggest && keyword && index == length - 1) { if (!result.length) { resolution = self.resolution; @@ -263,7 +149,6 @@ Index.prototype.search = function (query, limit, options) { term = query_terms[index]; - // todo should the dupe check applied on [keyword:term]? if (term && !dupes[term]) { dupes[term] = 1; @@ -276,16 +161,13 @@ Index.prototype.search = function (query, limit, options) { } if (keyword) { - // the context is a moving window where the keyword is going forward like a cursor - // 1. when suggestion enabled just forward keyword if term was found - // 2. as long as the result is empty forward the pointer also + if (!suggest || !arr || !result.length) { keyword = term; } } } - // fallback to non-contextual search when no result was found if (suggest && keyword && index == length - 1) { if (!result.length) { resolution = this.resolution; @@ -375,14 +257,12 @@ function add_result(arr, result, suggest, resolution) { if (arr && arr.length) { - // short when resolution does not exceed: if (arr.length <= resolution) { result.push(arr); - // return nothing will continue the query + return; } - // apply reduced resolution for queries for (let x = 0, tmp; x < resolution; x++) { if (tmp = arr[x]) { word_arr[x] = tmp; @@ -391,13 +271,11 @@ function add_result(arr, result, suggest, resolution) { if (word_arr.length) { result.push(word_arr); - // return nothing will continue the query + return; } } - // 1. return an empty array will stop the loop - // 2. return a false value to prevent stop when using suggestions if (!suggest) return word_arr; } @@ -437,9 +315,7 @@ Index.prototype.get_array = function (term, keyword, limit, offset, resolve, enr } if (keyword) { - // the frequency of the starting letter is slightly less - // on the last half of the alphabet (m-z) in almost every latin language, - // so we sort downwards (https://en.wikipedia.org/wiki/Letter_frequency) + arr = this.ctx.get(keyword); arr = arr && arr.get(term); } else { diff --git a/dist/module/intersect.js b/dist/module/intersect.js index c77a41e..0b74fb3 100644 --- a/dist/module/intersect.js +++ b/dist/module/intersect.js @@ -34,9 +34,6 @@ export function intersect(arrays, resolution, limit, offset, suggest, boost, res count; - // alternatively the results could be sorted by length up - //arrays.sort(sort_by_length_up); - check = create_object(); for (let y = 0, ids, id, res_arr, tmp; y < resolution; y++) { @@ -51,35 +48,23 @@ export function intersect(arrays, resolution, limit, offset, suggest, boost, res id = ids[z]; - // todo the persistent implementation will count term matches - // and also aggregate the score (group by id) - // min(score): suggestions off (already covered) - // sum(score): suggestions on (actually not covered) - if (count = check[id]) { check[id]++; - // tmp.count++; - // tmp.sum += y; } else { count = 0; check[id] = 1; - // check[id] = { - // count: 1, - // sum: y - // }; } tmp = result[count] || (result[count] = []); if (!resolve) { - // boost everything after first result + let score = y + (x || !suggest ? 0 : boost || 0); tmp = tmp[score] || (tmp[score] = []); } tmp.push(id); - // fast path early result when limit was set if (resolve) { if (limit && count === length - 1) { if (tmp.length - offset === limit) { @@ -87,16 +72,11 @@ export function intersect(arrays, resolution, limit, offset, suggest, boost, res } } } - // todo break early on suggest: true } } } } - // result.sort(function(a, b){ - // return check[a] - check[b]; - // }); - const result_len = result.length; if (result_len) { @@ -115,8 +95,7 @@ export function intersect(arrays, resolution, limit, offset, suggest, boost, res result = result.slice(offset, limit + offset); } } else { - // todo this is doing the same as Resolver.resolve({limit}) ? - // todo check limit + offset when resolve = false + const final = []; for (let i = 0, arr; i < result.length; i++) { arr = result[i]; @@ -136,14 +115,7 @@ export function intersect(arrays, resolution, limit, offset, suggest, boost, res } } result = final; - // result = final.length > 1 - // ? concat(final) - // : final[0]; } - - // return /** @type {SearchResults|IntermediateSearchResults} */ ( - // result - // ); } } else { @@ -174,8 +146,6 @@ export function union(arrays, limit, offset, resolve, boost) { arr_len = arrays.length, ids_len; - //let maxres = get_max_len(arrays); - if (!resolve) { for (let i = arr_len - 1, res, count = 0; 0 <= i; i--) { @@ -196,11 +166,6 @@ export function union(arrays, limit, offset, resolve, boost) { if (offset) { offset--; } else { - // adjust score to reduce resolution of suggestions - // todo: instead of applying the resolve task directly it could - // be added to the chain and resolved later, that will keep - // the original score but also can't resolve early when - // nothing was found let score = 0 | (k + (i < arr_len - 1 ? boost || 0 : 0)) / (i + 1), arr = result[score] || (result[score] = []); @@ -282,222 +247,6 @@ export function intersect_union(arrays, mandatory, resolve) { return result; } -// export function intersect_union(mandatory, arrays, resolution) { -// -// const check = create_object(); -// const union = create_object(); -// const result = []; -// -// for(let x = 0; x < mandatory.length; x++){ -// check[mandatory[x]] = 1; -// } -// -// -// for(let y = 0, ids, id; y < resolution; y++){ -// for(let x = 0; x < arrays.length; x++){ -// -// ids = arrays[x]; -// -// if(y < ids.length){ -// -// id = ids[y]; -// -// if(check[id]){ -// -// if(!union[id]){ -// -// union[id] = 1; -// result.push(id); -// } -// } -// } -// } -// } -// -// return result; -// } - -// -// /** -// * Implementation based on Object[key] provides better suggestions -// * capabilities and has less performance scaling issues on large indexes. -// * -// * @param arrays -// * @param limit -// * @param offset -// * @param {boolean|Array=} suggest -// * @param {boolean=} resolve -// * @returns {Array} -// */ -// -// export function intersect(arrays, limit, offset, suggest, resolve) { -// -// const length = arrays.length; -// -// // todo remove -// // if(length < 2){ -// // throw new Error("Not optimized intersect"); -// // } -// -// let result = []; -// let size = 0; -// let check; -// let check_suggest; -// let check_new; -// let res_arr; -// -// if(suggest){ -// suggest = []; -// } -// -// // 1. a reversed order prioritize the order of words from a query -// // because it ends with the first term. -// // 2. process terms in reversed order often has advantage for -// // the fast path "end reached". -// -// // alternatively the results could be sorted by length up -// //arrays.sort(sort_by_length_up); -// -// // todo the outer loop should be the res array instead of term array, -// // this isn't just simple because the intersection calculation needs to reflect this -// //const maxlen = get_max_len(arrays); -// -// for(let x = length - 1, found; x >= 0; x--){ -// //for(let x = 0, found; x < length; x++){ -// -// res_arr = arrays[x]; -// check_new = create_object(); -// found = !check; -// -// // process relevance in forward order (direction is -// // important for adding IDs during the last round) -// -// for(let y = 0, ids; y < res_arr.length; y++){ -// -// ids = res_arr[y]; -// if(!ids || !ids.length) continue; -// -// for(let z = 0, id; z < ids.length; z++){ -// -// id = ids[z]; -// -// // check exists starting from the 2nd slot -// if(check){ -// if(check[id]){ -// -// // check if in last round -// if(!x){ -// //if(x === length - 1){ -// -// if(offset){ -// offset--; -// } -// else{ -// -// result[size++] = id; -// -// if(size === limit){ -// // fast path "end reached" -// return result /*resolve === false -// ? { result, suggest } -// :*/ -// } -// } -// } -// -// if(x || suggest){ -// //if((x < length - 1) || suggest){ -// check_new[id] = 1; -// } -// -// found = true; -// } -// -// if(suggest){ -// -// if(!check_suggest[id]){ -// check_suggest[id] = 1; -// const arr = suggest[y] || (suggest[y] = []); -// arr.push(id); -// } -// -// // OLD: -// // -// // check_idx = (check_suggest[id] || 0) + 1; -// // check_suggest[id] = check_idx; -// // -// // // do not adding IDs which are already included in the result (saves one loop) -// // // the first intersection match has the check index 2, so shift by -2 -// // -// // if(check_idx < length){ -// // -// // const tmp = suggest[check_idx - 2] || (suggest[check_idx - 2] = []); -// // tmp[tmp.length] = id; -// // } -// } -// } -// else{ -// -// // pre-fill in first round -// check_new[id] = 1; -// } -// } -// } -// -// if(suggest){ -// -// // re-use the first pre-filled check for suggestions -// check || (check_suggest = check_new); -// } -// else if(!found){ -// -// return []; -// } -// -// check = check_new; -// } -// -// // return intermediate result -// // if(resolve === false){ -// // return { result, suggest }; -// // } -// -// if(suggest){ -// -// // needs to iterate in reverse direction -// for(let x = suggest.length - 1, ids, len; x >= 0; x--){ -// -// ids = suggest[x]; -// len = ids.length; -// -// for(let y = 0, id; y < len; y++){ -// -// id = ids[y]; -// -// if(!check[id]){ -// -// if(offset){ -// offset--; -// } -// else{ -// -// result[size++] = id; -// -// if(size === limit){ -// // fast path "end reached" -// return result; -// } -// } -// -// check[id] = 1; -// } -// } -// } -// } -// -// return result; -// } - /** * Implementation based on Array.includes() provides better performance, * but it needs at least one word in the query which is less frequent. @@ -509,185 +258,4 @@ export function intersect_union(arrays, mandatory, resolve) { * @param offset * @param {boolean|Array=} suggest * @returns {Array} - */ - -// export function intersect(arrays, limit, offset, suggest) { -// -// const length = arrays.length; -// let result = []; -// let check; -// -// // determine shortest array and collect results -// // from the sparse relevance arrays -// -// let smallest_size; -// let smallest_arr; -// let smallest_index; -// -// for(let x = 0; x < length; x++){ -// -// const arr = arrays[x]; -// const len = arr.length; -// -// let size = 0; -// -// for(let y = 0, tmp; y < len; y++){ -// -// tmp = arr[y]; -// -// if(tmp){ -// -// size += tmp.length; -// } -// } -// -// if(!smallest_size || (size < smallest_size)){ -// -// smallest_size = size; -// smallest_arr = arr; -// smallest_index = x; -// } -// } -// -// smallest_arr = smallest_arr.length === 1 ? -// -// smallest_arr[0] -// : -// concat(smallest_arr); -// -// if(suggest){ -// -// suggest = [smallest_arr]; -// check = create_object(); -// } -// -// let size = 0; -// let steps = 0; -// -// // process terms in reversed order often results in better performance. -// // the outer loop must be the words array, using the -// // smallest array here disables the "fast fail" optimization. -// -// for(let x = length - 1; x >= 0; x--){ -// -// if(x !== smallest_index){ -// -// steps++; -// -// const word_arr = arrays[x]; -// const word_arr_len = word_arr.length; -// const new_arr = []; -// -// let count = 0; -// -// for(let z = 0, id; z < smallest_arr.length; z++){ -// -// id = smallest_arr[z]; -// -// let found; -// -// // process relevance in forward order (direction is -// // important for adding IDs during the last round) -// -// for(let y = 0; y < word_arr_len; y++){ -// -// const arr = word_arr[y]; -// -// if(arr.length){ -// -// found = arr.includes(id); -// -// if(found){ -// -// // check if in last round -// -// if(steps === length - 1){ -// -// if(offset){ -// -// offset--; -// } -// else{ -// -// result[size++] = id; -// -// if(size === limit){ -// -// // fast path "end reached" -// -// return result; -// } -// } -// -// if(suggest){ -// -// check[id] = 1; -// } -// } -// -// break; -// } -// } -// } -// -// if(found){ -// -// new_arr[count++] = id; -// } -// } -// -// if(suggest){ -// -// suggest[steps] = new_arr; -// } -// else if(!count){ -// -// return []; -// } -// -// smallest_arr = new_arr; -// } -// } -// -// if(suggest){ -// -// // needs to iterate in reverse direction -// -// for(let x = suggest.length - 1, arr, len; x >= 0; x--){ -// -// arr = suggest[x]; -// len = arr && arr.length; -// -// if(len){ -// -// for(let y = 0, id; y < len; y++){ -// -// id = arr[y]; -// -// if(!check[id]){ -// -// check[id] = 1; -// -// if(offset){ -// -// offset--; -// } -// else{ -// -// result[size++] = id; -// -// if(size === limit){ -// -// // fast path "end reached" -// -// return result; -// } -// } -// } -// } -// } -// } -// } -// -// return result; -// } \ No newline at end of file + */ \ No newline at end of file diff --git a/dist/module/keystore.js b/dist/module/keystore.js index 40cbd39..cfd76db 100644 --- a/dist/module/keystore.js +++ b/dist/module/keystore.js @@ -1,64 +1,5 @@ import { create_object } from "./common.js"; -// /** -// * @param bitlength -// * @constructor -// */ -// -// export function KeystoreObj(bitlength = 8){ -// -// if(!this || this.constructor !== KeystoreObj){ -// return new KeystoreObj(bitlength); -// } -// -// this.index = create_object(); -// this.keys = []; -// -// if(bitlength > 32){ -// this.crc = lcg64; -// this.bit = BigInt(bitlength); -// } -// else { -// this.crc = lcg; -// this.bit = bitlength; -// } -// -// return /*this.proxy =*/ new Proxy(this, { -// get(target, key) { -// const address = target.crc(key); -// const obj = target.index[address]; -// return obj && obj[key]; -// }, -// set(target, key, value){ -// const address = target.crc(key); -// let obj = target.index[address]; -// if(!obj){ -// target.index[address] = obj = create_object(); -// target.keys.push(address); -// } -// obj[key] = value; -// return true; -// }, -// delete(target, key){ -// const address = target.crc(key); -// const obj = target.index[address]; -// obj && delete obj[key]; -// return true; -// } -// }); -// } -// -// KeystoreObj.prototype.clear = function(){ -// this.index = create_object(); -// this.keys = []; -// }; - -// KeystoreObj.prototype.destroy = function(){ -// this.index = null; -// this.keys = null; -// this.proxy = null; -// }; - function _slice(self, start, end, splice) { let arr = []; for (let i = 0, index; i < self.index.length; i++) { @@ -96,83 +37,78 @@ export function KeystoreArray(arr) { this.length = arr ? arr.length : 0; const self = this; - return (/*this.proxy =*/new Proxy([], { - get(target, key) { - if ("length" === key) { - return self.length; - } - if ("push" === key) { - return function (value) { - self.index[self.index.length - 1].push(value); - self.length++; - }; - } - if ("pop" === key) { - return function () { - if (self.length) { - self.length--; - return self.index[self.index.length - 1].pop(); - } - }; - } - if ("indexOf" === key) { - return function (key) { - let index = 0; - for (let i = 0, arr, tmp; i < self.index.length; i++) { - arr = self.index[i]; - //if(!arr.includes(key)) continue; - tmp = arr.indexOf(key); - if (0 <= tmp) return index + tmp; - index += arr.length; - } - return -1; - }; - } - if ("includes" === key) { - return function (key) { - for (let i = 0; i < self.index.length; i++) { - if (self.index[i].includes(key)) { - return (/* tag? */ /* stringify */ /* stringify */ /* single param */ /* skip update: */ /* append: */ /* skip update: */ /* skip_update: */ /* skip deletion */ - // splice: - !0 /*await rows.hasNext()*/ /*await rows.hasNext()*/ /*await rows.hasNext()*/ - ); - } - } - return (/* suggest */ /* append: */ /* enrich */!1 - ); - }; - } - if ("slice" === key) { - return function (start, end) { - return _slice(self, start || 0, end || self.length, !1); - }; - } - if ("splice" === key) { - return function (start, end) { - return _slice(self, start || 0, end || self.length, !0); - }; - } - if ("constructor" === key) { - return Array; - } - if ("symbol" == typeof key /*|| isNaN(key)*/) { - // not supported - return; - } - const arr = self.index[0 | key / 2147483648]; - - return arr && arr[key]; - }, - set(target, key, value) { - const index = 0 | key / 2147483648, - arr = self.index[index] || (self.index[index] = []); - - arr[key] = value; - self.length++; - return !0; + return new Proxy([], { + get(target, key) { + if ("length" === key) { + return self.length; } - }) - ); + if ("push" === key) { + return function (value) { + self.index[self.index.length - 1].push(value); + self.length++; + }; + } + if ("pop" === key) { + return function () { + if (self.length) { + self.length--; + return self.index[self.index.length - 1].pop(); + } + }; + } + if ("indexOf" === key) { + return function (key) { + let index = 0; + for (let i = 0, arr, tmp; i < self.index.length; i++) { + arr = self.index[i]; + + tmp = arr.indexOf(key); + if (0 <= tmp) return index + tmp; + index += arr.length; + } + return -1; + }; + } + if ("includes" === key) { + return function (key) { + for (let i = 0; i < self.index.length; i++) { + if (self.index[i].includes(key)) { + return !0; + } + } + return !1; + }; + } + if ("slice" === key) { + return function (start, end) { + return _slice(self, start || 0, end || self.length, !1); + }; + } + if ("splice" === key) { + return function (start, end) { + return _slice(self, start || 0, end || self.length, !0); + }; + } + if ("constructor" === key) { + return Array; + } + if ("symbol" == typeof key) { + + return; + } + const arr = self.index[0 | key / 2147483648]; + + return arr && arr[key]; + }, + set(target, key, value) { + const index = 0 | key / 2147483648, + arr = self.index[index] || (self.index[index] = []); + + arr[key] = value; + self.length++; + return !0; + } + }); } KeystoreArray.prototype.clear = function () { @@ -328,9 +264,7 @@ KeystoreSet.prototype.delete = function (key) { const address = this.crc(key), map_or_set = this.index[address]; - // set && (set.size === 1 - // ? this.index.delete(address) - // : set.delete(key)); + map_or_set && map_or_set.delete(key) && this.size--; }; @@ -340,19 +274,11 @@ KeystoreMap.prototype.clear = KeystoreSet.prototype.clear = function () { this.size = 0; }; -// KeystoreMap.prototype.destroy = -// KeystoreSet.prototype.destroy = function(){ -// this.index = null; -// this.refs = null; -// this.proxy = null; -// }; - /** * @return Iterable */ KeystoreMap.prototype.values = KeystoreSet.prototype.values = function* () { - // alternatively iterate through this.keys[] - //const refs = Object.values(this.index); + for (let i = 0; i < this.refs.length; i++) { for (let value of this.refs[i].values()) { yield value; @@ -364,7 +290,7 @@ KeystoreMap.prototype.values = KeystoreSet.prototype.values = function* () { * @return Iterable */ KeystoreMap.prototype.keys = KeystoreSet.prototype.keys = function* () { - //const values = Object.values(this.index); + for (let i = 0; i < this.refs.length; i++) { for (let key of this.refs[i].keys()) { yield key; @@ -376,7 +302,7 @@ KeystoreMap.prototype.keys = KeystoreSet.prototype.keys = function* () { * @return Iterable */ KeystoreMap.prototype.entries = KeystoreSet.prototype.entries = function* () { - //const values = Object.values(this.index); + for (let i = 0; i < this.refs.length; i++) { for (let entry of this.refs[i].entries()) { yield entry; @@ -400,9 +326,8 @@ function lcg(str) { for (let i = 0; i < str.length; i++) { crc = (crc * bit ^ str.charCodeAt(i)) & range; } - // shift Int32 to UInt32 because negative numbers - // extremely slows down key lookup - return 32 === this.bit ? crc + 2147483648 : crc; // & 0xFFFF; + + return 32 === this.bit ? crc + 2147483648 : crc; } /** @@ -426,5 +351,5 @@ function lcg64(str) { for (let i = 0; i < str.length; i++) { crc = (crc * bit ^ BigInt(str.charCodeAt(i))) & range; } - return crc; // & 0xFFFFFFFFFFFFFFFF; + return crc; } \ No newline at end of file diff --git a/dist/module/lang/de.js b/dist/module/lang/de.js index 6559526..2f74ae0 100644 --- a/dist/module/lang/de.js +++ b/dist/module/lang/de.js @@ -26,14 +26,14 @@ export const stemmer = new Map([["niss", ""], ["isch", ""], ["lich", ""], ["heit */ const map = new Map([["_", " "], ["ä", "ae"], ["ö", "oe"], ["ü", "ue"], ["ß", "ss"], ["&", " und "], ["€", " EUR "]]), options = { - prepare: function (str) { - // normalization - if (/[_äöüß&€]/.test(str)) str = str.replace(/[_äöüß&€]/g, match => map.get(match)); - // street names - return str.replace(/str\b/g, "strasse").replace(/(?!\b)strasse\b/g, " strasse"); - }, - filter: filter, - stemmer: stemmer + prepare: function (str) { + + if (/[_äöüß&€]/.test(str)) str = str.replace(/[_äöüß&€]/g, match => map.get(match)); + + return str.replace(/str\b/g, "strasse").replace(/(?!\b)strasse\b/g, " strasse"); + }, + filter: filter, + stemmer: stemmer }; /** diff --git a/dist/module/lang/en.js b/dist/module/lang/en.js index 17afe21..959e0ec 100644 --- a/dist/module/lang/en.js +++ b/dist/module/lang/en.js @@ -1,53 +1,16 @@ import { EncoderOptions } from "../type.js"; -// todo filter out minlength - /** * http://www.ranks.nl/stopwords * @type {Set} */ -export const filter = new Set(["a", "about", "above", "after", "again", "against", "all", "also", "am", "an", "and", "any", "are", "arent", "as", "at", "back", "be", "because", "been", "before", "being", "below", "between", "both", "but", "by", "can", "cannot", "cant", "come", "could", "couldnt", -//"day", -"did", "didnt", "do", "does", "doesnt", "doing", "dont", "down", "during", "each", "even", "few", -//"first", -"for", "from", "further", "get", -//"give", -"go", "good", "had", "hadnt", "has", "hasnt", "have", "havent", "having", "he", "hed", -//"hell", -"her", "here", "heres", "hers", "herself", "hes", "him", "himself", "his", "how", "hows", "i", "id", "if", "ill", "im", "in", "into", "is", "isnt", "it", "its", "itself", "ive", "just", "know", "lets", "like", -//"look", -"lot", "make", "made", "me", "more", "most", "mustnt", "my", "myself", "new", "no", "nor", "not", "now", "of", "off", "on", "once", "one", "only", "or", "other", "ought", "our", "ours", "ourselves", "out", "over", "own", -//"people", -"same", "say", "see", "shant", "she", "shed", "shell", "shes", "should", "shouldnt", "so", "some", "such", "take", "than", "that", "thats", "the", "their", "theirs", "them", "themselves", "then", "there", "theres", "these", "they", "theyd", "theyll", "theyre", "theyve", "think", "this", "those", "through", "time", "times", "to", "too", -//"two", -"under", "until", "up", "us", "use", "very", "want", "was", "wasnt", "way", "we", "wed", "well", "were", "werent", "weve", "what", "whats", "when", "whens", "where", "wheres", "which", "while", "who", "whom", "whos", "why", "whys", "will", "with", "wont", "work", "would", "wouldnt", -//"year", -"ya", "you", "youd", "youll", "your", "youre", "yours", "yourself", "yourselves", "youve"]); +export const filter = new Set(["a", "about", "above", "after", "again", "against", "all", "also", "am", "an", "and", "any", "are", "arent", "as", "at", "back", "be", "because", "been", "before", "being", "below", "between", "both", "but", "by", "can", "cannot", "cant", "come", "could", "couldnt", "did", "didnt", "do", "does", "doesnt", "doing", "dont", "down", "during", "each", "even", "few", "for", "from", "further", "get", "go", "good", "had", "hadnt", "has", "hasnt", "have", "havent", "having", "he", "hed", "her", "here", "heres", "hers", "herself", "hes", "him", "himself", "his", "how", "hows", "i", "id", "if", "ill", "im", "in", "into", "is", "isnt", "it", "its", "itself", "ive", "just", "know", "lets", "like", "lot", "make", "made", "me", "more", "most", "mustnt", "my", "myself", "new", "no", "nor", "not", "now", "of", "off", "on", "once", "one", "only", "or", "other", "ought", "our", "ours", "ourselves", "out", "over", "own", "same", "say", "see", "shant", "she", "shed", "shell", "shes", "should", "shouldnt", "so", "some", "such", "take", "than", "that", "thats", "the", "their", "theirs", "them", "themselves", "then", "there", "theres", "these", "they", "theyd", "theyll", "theyre", "theyve", "think", "this", "those", "through", "time", "times", "to", "too", "under", "until", "up", "us", "use", "very", "want", "was", "wasnt", "way", "we", "wed", "well", "were", "werent", "weve", "what", "whats", "when", "whens", "where", "wheres", "which", "while", "who", "whom", "whos", "why", "whys", "will", "with", "wont", "work", "would", "wouldnt", "ya", "you", "youd", "youll", "your", "youre", "yours", "yourself", "yourselves", "youve"]); /** * @type {Map} */ -export const stemmer = new Map([ -//["ational", "ate"], -//["iveness", ""], -//["fulness", ""], -//["ousness", ""], -["ization", ""], -//["tional", "tion"], -["biliti", ""], ["icate", ""], ["ative", ""], -//["alize", ""], -//["iciti", ""], -//["entli", ""], -//["ousli", ""], -//["alism", ""], -["ation", ""], -//["aliti", ""], -["iviti", ""], ["ement", ""], ["izer", ""], ["able", ""], ["ible", ""], ["alli", ""], ["ator", ""], ["less", ""], ["logi", ""], ["ical", ""], ["ance", ""], ["ence", ""], ["ness", ""], ["ble", ""], ["ment", ""], -//["nal", "n"], -["eli", ""], ["bli", ""], ["ful", ""], ["ant", ""], ["ent", ""], ["ism", ""], ["ate", ""], ["iti", ""], ["ous", ""], ["ive", ""], ["ize", ""], ["ing", ""], ["ion", ""], ["ies", "y"], ["al", ""], ["ou", ""], ["er", ""], ["ed", ""], -//["es", "e"], -["ic", ""], ["ly", ""], ["li", ""], ["s", ""]]); +export const stemmer = new Map([["ization", ""], ["biliti", ""], ["icate", ""], ["ative", ""], ["ation", ""], ["iviti", ""], ["ement", ""], ["izer", ""], ["able", ""], ["ible", ""], ["alli", ""], ["ator", ""], ["less", ""], ["logi", ""], ["ical", ""], ["ance", ""], ["ence", ""], ["ness", ""], ["ble", ""], ["ment", ""], ["eli", ""], ["bli", ""], ["ful", ""], ["ant", ""], ["ent", ""], ["ism", ""], ["ate", ""], ["iti", ""], ["ous", ""], ["ive", ""], ["ize", ""], ["ing", ""], ["ion", ""], ["ies", "y"], ["al", ""], ["ou", ""], ["er", ""], ["ed", ""], ["ic", ""], ["ly", ""], ["li", ""], ["s", ""]]); /* he’s (= he is / he has) @@ -64,33 +27,14 @@ export const stemmer = new Map([ won’t (= will not) */ -// const explode = new Map([ -// ["^i'm$", "i am"], -// ["^can't$", "can not"], -// ["^cannot$", "can not"], -// ["^won't$", "will not"], -// ["'s$", " is has"], -// ["n't$", " not"], -// ["'ll$", " will"], -// ["'re$", " are"], -// ["'ve$", " have"], -// ["'d$", " would had"], -// ]); - /** * @type EncoderOptions */ const options = { - prepare: function (str) { - return str - // normalize symbols - .replace(/´`’ʼ/g, "'") - //.replace(/[_\-]+/g, " ") - .replace(/&/g, " and ").replace(/\$/g, " USD ").replace(/£/g, " GBP ") - // explode short forms - .replace(/\bi'm\b/g, "i am").replace(/\b(can't|cannot)\b/g, "can not").replace(/\bwon't\b/g, "will not").replace(/([a-z])'s\b/g, "$1 is has").replace(/([a-z])n't\b/g, "$1 not").replace(/([a-z])'ll\b/g, "$1 will").replace(/([a-z])'re\b/g, "$1 are").replace(/([a-z])'ve\b/g, "$1 have").replace(/([a-z])'d\b/g, "$1 would had"); - }, - filter: filter, - stemmer: stemmer + prepare: function (str) { + return str.replace(/´`’ʼ/g, "'").replace(/&/g, " and ").replace(/\$/g, " USD ").replace(/£/g, " GBP ").replace(/\bi'm\b/g, "i am").replace(/\b(can't|cannot)\b/g, "can not").replace(/\bwon't\b/g, "will not").replace(/([a-z])'s\b/g, "$1 is has").replace(/([a-z])n't\b/g, "$1 not").replace(/([a-z])'ll\b/g, "$1 will").replace(/([a-z])'re\b/g, "$1 are").replace(/([a-z])'ve\b/g, "$1 have").replace(/([a-z])'d\b/g, "$1 would had"); + }, + filter: filter, + stemmer: stemmer }; export default options; \ No newline at end of file diff --git a/dist/module/preset.js b/dist/module/preset.js index 4fbf451..f133fc8 100644 --- a/dist/module/preset.js +++ b/dist/module/preset.js @@ -14,8 +14,7 @@ const presets = { performance: { resolution: 3, - fastupdate: /* tag? */ /* stringify */ /* stringify */ /* single param */ /* skip update: */ /* append: */ /* skip update: */ /* skip_update: */ /* skip deletion */ // splice: - !0 /*await rows.hasNext()*/ /*await rows.hasNext()*/ /*await rows.hasNext()*/, + fastupdate: !0, context: { depth: 1, resolution: 1 diff --git a/dist/module/resolve/and.js b/dist/module/resolve/and.js index 1929674..9524427 100644 --- a/dist/module/resolve/and.js +++ b/dist/module/resolve/and.js @@ -84,7 +84,7 @@ function return_result(final, promises, limit, offset, enrich, resolve, suggest) this.result = /** @type {SearchResults|IntermediateSearchResults} */final; } } else { - //final = [this.result].concat(final); + this.result.length && final.unshift(this.result); if (2 > final.length) { diff --git a/dist/module/resolve/default.js b/dist/module/resolve/default.js index c280c35..d635438 100644 --- a/dist/module/resolve/default.js +++ b/dist/module/resolve/default.js @@ -25,7 +25,6 @@ export default function (result, limit, offset, enrich) { return result; } - // fast path: when there is just one slot in the result if (1 === result.length) { let final = result[0]; final = offset || final.length > limit ? limit ? final.slice(offset, offset + limit) : final.slice(offset) : final; @@ -34,19 +33,16 @@ export default function (result, limit, offset, enrich) { let final = []; - // this is an optimized workaround instead of - // just doing result = concat(result) - for (let i = 0, arr, len; i < result.length; i++) { if (!(arr = result[i]) || !(len = arr.length)) continue; if (offset) { - // forward offset pointer + if (offset >= len) { offset -= len; continue; } - // apply offset pointer when length differs + if (offset < len) { arr = limit ? arr.slice(offset, offset + limit) : arr.slice(offset); len = arr.length; @@ -60,7 +56,7 @@ export default function (result, limit, offset, enrich) { } if (!final.length) { - // fast path: when limit was reached in first slot + if (len >= limit) { return enrich ? apply_enrich.call(this, arr) : arr; } @@ -69,7 +65,6 @@ export default function (result, limit, offset, enrich) { final.push(arr); limit -= len; - // break if limit was reached if (!limit) { break; } @@ -78,23 +73,4 @@ export default function (result, limit, offset, enrich) { final = 1 < final.length ? concat(final) : final[0]; return enrich ? apply_enrich.call(this, final) : final; -} - -// /** -// * @param {SearchResults} ids -// * @return {EnrichedSearchResults} -// */ -// -// export function enrich_result(ids){ -// // ids could be the original reference to an index value -// /** @type {EnrichedSearchResults} */ -// const result = new Array(ids.length); -// for(let i = 0, id; i < ids.length; i++){ -// id = ids[i]; -// result[i] = { -// "id": id, -// "doc": this.store.get(id) -// }; -// } -// return result; -// } \ No newline at end of file +} \ No newline at end of file diff --git a/dist/module/resolve/handler.js b/dist/module/resolve/handler.js index 8c32bd1..add2d9b 100644 --- a/dist/module/resolve/handler.js +++ b/dist/module/resolve/handler.js @@ -13,16 +13,14 @@ Resolver.prototype.handler = function (fn, args) { if (first_argument.then) { const self = this; - // todo: check when this branch was taken - // instead of Promise.all the args[] array could be reduced - // by iterate recursively one by one + return Promise.all(args).then(function (args) { return self[fn].apply(self, args); }); } if (first_argument[0]) { - // detect array parameter style + if (first_argument[0].index) { return this[fn].apply(this, first_argument); } @@ -76,13 +74,10 @@ Resolver.prototype.handler = function (fn, args) { } } - query.resolve = /* suggest */ /* append: */ /* enrich */!1; - //if(DEBUG) - //query.enrich = false; + query.resolve = !1; + result = index.search(query).result; query.resolve = resolve; - //if(DEBUG) - //query.enrich = enrich; if (highlight) { highlight_query = query.query; diff --git a/dist/module/resolve/not.js b/dist/module/resolve/not.js index 9466752..cd9070c 100644 --- a/dist/module/resolve/not.js +++ b/dist/module/resolve/not.js @@ -73,10 +73,6 @@ function return_result(final, promises, limit, offset, enrich, resolve, suggest) function exclusion(result, limit, offset, resolve) { - // if(!result.length){ - // return this.result; - // } - /** @type {SearchResults|IntermediateSearchResults} */ const final = [], exclude = new Set(result.flat().flat()); diff --git a/dist/module/resolve/or.js b/dist/module/resolve/or.js index 13fa4e3..7114d27 100644 --- a/dist/module/resolve/or.js +++ b/dist/module/resolve/or.js @@ -53,18 +53,15 @@ function return_result(final, promises, limit, offset, enrich, resolve) { } if (final.length) { - //this.result.length && (final = final.concat([this.result])); + this.result.length && final.push(this.result); if (2 > final.length) { this.result = final[0]; } else { - // the suggest-union (reversed processing, resolve needs to be disabled) - this.result = union(final /*.reverse()*/ - , limit, offset, /* suggest */ /* append: */ /* enrich */ - /* resolve: */!1, this.boostval); - // offset was already applied + this.result = union(final, limit, offset, !1, this.boostval); + offset = 0; } } diff --git a/dist/module/resolve/xor.js b/dist/module/resolve/xor.js index 844bb7f..5fdbb40 100644 --- a/dist/module/resolve/xor.js +++ b/dist/module/resolve/xor.js @@ -58,7 +58,7 @@ function return_result(final, promises, limit, offset, enrich, resolve, suggest) if (!final.length) { if (!suggest) this.result = /** @type {SearchResults|IntermediateSearchResults} */final; } else { - //this.result.length && (final = [this.result].concat(final)); + this.result.length && final.unshift(this.result); if (2 > final.length) { @@ -86,10 +86,6 @@ function return_result(final, promises, limit, offset, enrich, resolve, suggest) function exclusive(result, limit, offset, resolve, boost) { - // if(!result.length){ - // return result; - // } - /** @type {SearchResults|IntermediateSearchResults} */ const final = [], check = create_object(); @@ -135,7 +131,7 @@ function exclusive(result, limit, offset, resolve, boost) { return final; } } else { - // shift resolution by boost (inverse) + const index = j + (i ? boost : 0); final[index] || (final[index] = []); final[index].push(id); diff --git a/dist/module/resolver.js b/dist/module/resolver.js index 4fed2ac..1bad4c0 100644 --- a/dist/module/resolver.js +++ b/dist/module/resolver.js @@ -21,14 +21,10 @@ export default function Resolver(result, index) { if (!this || this.constructor !== Resolver) { return new Resolver(result, index); } - // if(result && result.constructor === Resolver){ - // // todo test this branch - // //console.log("Resolver Loopback") - // return /** @type {Resolver} */ (result); - // } + if (result && result.index) { - // result = /** @type {ResolverOptions} */ (result); - result.resolve = /* suggest */ /* append: */ /* enrich */ /* resolve: */!1; + + result.resolve = !1; this.index = /** @type {Index|Document} */result.index; this.boostval = result.boost || 0; this.result = this.index.search(result).result; @@ -116,19 +112,8 @@ Resolver.prototype.resolve = function (limit, offset, enrich) { limit.highlight; limit = limit.limit; } - // const document = this.index; - // if(document.index){ - // result = default_resolver(result, limit || 100, offset, false); - // return enrich - // ? apply_enrich.call(document, result) - // : result; - // } - // else{ + result = default_resolver.call(index, result, limit || 100, offset, enrich); - // if(highlight){ - // result = highlight_fields(result); - // } - // } } return result; diff --git a/dist/module/serialize.js b/dist/module/serialize.js index e92750c..69acdcc 100644 --- a/dist/module/serialize.js +++ b/dist/module/serialize.js @@ -174,7 +174,6 @@ export function exportIndex(callback, _field, _index_doc = 0, _index_obj = 0) { case 1: - // todo key = "cfg"; chunk = null; break; @@ -226,13 +225,12 @@ export function importIndex(key, data) { switch (key) { case "cfg": - // todo + break; case "reg": - // fast update isn't supported by export/import - this.fastupdate = /* suggest */ /* append: */ /* enrich */ /* resolve: */!1; + this.fastupdate = !1; this.reg = json_to_reg( /** @type {Array} */data, this.reg); break; @@ -262,7 +260,7 @@ export function exportDocument(callback, _field, _index_doc = 0, _index_obj = 0) const field = this.field[_index_doc], idx = this.index.get(field), res = idx.export(callback, field, _index_doc, _index_obj = 1); - // start from index 1, because document indexes does not additionally store register + if (res && res.then) { const self = this; @@ -299,13 +297,6 @@ export function exportDocument(callback, _field, _index_doc = 0, _index_obj = 0) _field = null; break; - // case 3: - // - // key = "cfg"; - // chunk = null; - // _field = null; - // break; - default: return; @@ -331,7 +322,6 @@ export function importDocument(key, data) { ref = 2 < split.length ? split[2] : split[1]; - // trigger the import for worker field indexes if (this.worker && field) { return this.index.get(field).import(key); } @@ -349,7 +339,6 @@ export function importDocument(key, data) { case "reg": - // fast update isn't supported by export/import this.fastupdate = !1; this.reg = json_to_reg( /** @type {Array} */data, this.reg); @@ -359,17 +348,14 @@ export function importDocument(key, data) { idx.reg = this.reg; } - // trigger the import for worker field indexes if (this.worker) { const promises = [], self = this; for (const index of this.index.values()) { - // const ref = item[0]; - // const index = item[1]; + promises.push(index.import(key)); - //this.index.get(field).import(key); } return Promise.all(promises); @@ -410,8 +396,7 @@ ctx: "gulliver+travel:1,2,3|4,5,6|7,8,9;" * @return {string} */ -export function serialize(withFunctionWrapper = /* tag? */ /* stringify */ /* stringify */ /* single param */ /* skip update: */ /* append: */ /* skip update: */ /* skip_update: */ /* skip deletion */ // splice: -!0 /*await rows.hasNext()*/ /*await rows.hasNext()*/ /*await rows.hasNext()*/) { +export function serialize(withFunctionWrapper = !0) { let reg = '', map = '', ctx = ''; diff --git a/dist/module/type.js b/dist/module/type.js index 51a8f87..368e9fb 100644 --- a/dist/module/type.js +++ b/dist/module/type.js @@ -1,5 +1,4 @@ -// When you are looking for type definitions which fully describes the usage take a look into the index.d.ts file. -// Some of the types here aren't supposed to be used as public, they might be defined just for internal state. + import Index from "./index.js"; import Encoder from "./encoder.js"; @@ -193,9 +192,10 @@ export let EnrichedDocumentSearchResults = []; /** * @typedef {{ * id: (number|string), - * doc: (Object|null), + * doc: (Object|null|undefined), * field: (Array|undefined), - * tag: (Array|undefined) + * tag: (Array|undefined), + * highlight: (Object|undefined) * }} */ export let MergedDocumentSearchEntry = {}; diff --git a/dist/module/worker.js b/dist/module/worker.js index 69aef56..967d758 100644 --- a/dist/module/worker.js +++ b/dist/module/worker.js @@ -19,14 +19,12 @@ export default function WorkerIndex(options = /** @type IndexOptions */{}, encod return new WorkerIndex(options); } - // the factory is the outer wrapper from the build - // it uses "self" as a trap for node.js let factory = "undefined" != typeof self ? self._factory : "undefined" != typeof window ? window._factory : null; if (factory) { factory = factory.toString(); } - const is_node_js = "undefined" == typeof window /*&& self["exports"]*/, + const is_node_js = "undefined" == typeof window, _self = this; /** @@ -56,8 +54,6 @@ export default function WorkerIndex(options = /** @type IndexOptions */{}, encod if (options.config) { - // when extern configuration needs to be loaded - // it needs to return a promise to await for return new Promise(function (resolve) { _self.resolver[++pid] = function () { @@ -74,19 +70,17 @@ export default function WorkerIndex(options = /** @type IndexOptions */{}, encod }); } + this.priority = options.priority || 4; + + + this.encoder = encoder || null; + this.worker.postMessage({ task: "init", factory: factory, options: options }); - this.priority = options.priority || 4; - - // assign encoder for result highlighting - if (encoder) { - this.encoder = encoder; - } - return this; } @@ -99,6 +93,7 @@ export default function WorkerIndex(options = /** @type IndexOptions */{}, encod register("add"); register("append"); register("search"); +register("searchCache"); register("update"); register("remove"); register("clear"); @@ -124,7 +119,7 @@ function register(key) { const promise = new Promise(function (resolve) { if ("export" === key && "function" == typeof args[0]) { - // remove function handler + args[0] = null; } self.resolver[++pid] = resolve; @@ -146,21 +141,7 @@ function register(key) { function create(factory, is_node_js, worker_path) { - let worker = is_node_js ? - // if anyone would ask me what JS has delivered the past 10 years, - // those are the lines I definitively show up first ^^ - "undefined" != typeof module - // This eval will be removed when compiling - // The issue is that this will not build by Closure Compiler - ? (0,eval)('new(require("worker_threads")["Worker"])(__dirname+"/worker/node.js")') - // this will need to remove in CommonJS builds, - // otherwise the module is treated as ESM by Node.js automatic detection - // the path src/worker/node.mjs is located at dist/node/node.mjs - // The issue is that this will not build by Babel Compiler - : import("worker_threads").then(function(worker){return new worker["Worker"](import.meta.dirname+"/../node/node.mjs")}) : factory ? new window.Worker(URL.createObjectURL(new Blob(["onmessage=" + handler.toString()], { type: "text/javascript" }))) : new window.Worker("string" == typeof worker_path ? worker_path - // when loaded from /src/ folder the worker file is located at /worker/worker.js - : (1, eval)("import.meta.url").replace("/worker.js", "/worker/worker.js").replace("flexsearch.bundle.module.min.js", "module/worker/worker.js") /*"worker/worker.js"*/ - , { type: "module" }); + let worker = is_node_js ? "undefined" != typeof module ? (0,eval)('new(require("worker_threads")["Worker"])(__dirname+"/worker/node.js")') : import("worker_threads").then(function(worker){return new worker["Worker"](import.meta.dirname+"/../node/node.mjs")}) : factory ? new window.Worker(URL.createObjectURL(new Blob(["onmessage=" + handler.toString()], { type: "text/javascript" }))) : new window.Worker("string" == typeof worker_path ? worker_path : (1, eval)("import.meta.url").replace("/worker.js", "/worker/worker.js").replace("flexsearch.bundle.module.min.js", "module/worker/worker.js"), { type: "module" }); return worker; } \ No newline at end of file diff --git a/dist/module/worker/handler.js b/dist/module/worker/handler.js index a911533..2deff6f 100644 --- a/dist/module/worker/handler.js +++ b/dist/module/worker/handler.js @@ -22,21 +22,17 @@ export default (async function (data) { options = data.options || {}; let filepath = options.config; if (filepath) { - // compiler fix + options = options; - // will be replaced after build with the line below because - // there is an issue with closure compiler dynamic import - options=(await import(filepath))["default"]; } const factory = data.factory; if (factory) { - // export the FlexSearch global payload to "self" Function("return " + factory)()(self); index = new self.FlexSearch.Index(options); - // destroy the exported payload + delete self.FlexSearch; } else { @@ -51,11 +47,11 @@ export default (async function (data) { let message; if ("export" === task) { - // skip non-field indexes + if (!args[1]) args = null;else { args[0] = options.export; args[2] = 0; - args[3] = 1; // skip reg + args[3] = 1; } } if ("import" === task) { diff --git a/dist/module/worker/node.js b/dist/module/worker/node.js index 8b8b3d8..d92e17e 100644 --- a/dist/module/worker/node.js +++ b/dist/module/worker/node.js @@ -4,10 +4,6 @@ */ const { parentPort } = require("worker_threads"), { Index } = require("flexsearch"); -//const { join } = require("path"); -// Test Path -//const { Index } = require("../../dist/flexsearch.bundle.min.js"); - /** @type Index */ let index, options; @@ -24,7 +20,7 @@ parentPort.on("message", async function (data) { case "init": options = data.options || {}; - // load extern field configuration + let filepath = options.config; if (filepath) { options = Object.assign({}, options, require(filepath)); @@ -32,7 +28,6 @@ parentPort.on("message", async function (data) { } index = new Index(options); - //index.db && await index.db; parentPort.postMessage({ id: id }); break; @@ -45,11 +40,11 @@ parentPort.on("message", async function (data) { if (!options.export || "function" != typeof options.export) { throw new Error("Either no extern configuration provided for the Worker-Index or no method was defined on the config property \"export\"."); } - // skip non-field indexes + if (!args[1]) args = null;else { args[0] = options.export; args[2] = 0; - args[3] = 1; // skip reg + args[3] = 1; } } if ("import" === task) { diff --git a/doc/document-search.md b/doc/document-search.md index 4d201a5..c9814e6 100644 --- a/doc/document-search.md +++ b/doc/document-search.md @@ -890,7 +890,7 @@ Your results look now like: ### Configure Document Store (Recommended) -You can configure independently what should being indexed and what should being stored. This can reduce required index space significantly. Indexed fields do not require to be included in the stored data (also the ID isn't necessary to keep in store). +When storing documents, you can configure independently what should be indexed and what should be stored. This can reduce required index space significantly. Indexed fields do not require to be included in the stored data (also the ID isn't necessary to keep in store). It is recommended to just add fields to the store you'll need in the final result to process further on. A short example of configuring a document store: @@ -1057,6 +1057,33 @@ const result = index.search({ tag: { "city": "Berlin" } }); ``` +### Best Practices: TypeScript + +When using TypeScript, you can type your document data when creating a `Document`-Index. This will provide enhanced type checks of your syntax. + +Create a schema accordingly to your document data, e.g.: +```ts +type doctype = { + id: number, + title: string, + description: string, + tags: string[] +}; +``` + +Create the document index by assigning the type `doctype`: +```ts +const document = new Document({ + id: "id", + store: true, + index: [{ + field: "title" + },{ + field: "description" + }], + tag: "tags" +}); +``` ### Best Practices: Merge Documents diff --git a/package-lock.json b/package-lock.json index 7c74128..dca5241 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "flexsearch", - "version": "0.8.164", + "version": "0.8.165", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "flexsearch", - "version": "0.8.164", + "version": "0.8.165", "funding": [ { "type": "github", diff --git a/package.json b/package.json index 0bbff5b..4f8219b 100644 --- a/package.json +++ b/package.json @@ -2,7 +2,7 @@ "public": true, "preferGlobal": false, "name": "flexsearch", - "version": "0.8.164", + "version": "0.8.165", "description": "Next-Generation full-text search library for Browser and Node.js", "homepage": "https://github.com/nextapps-de/flexsearch/", "author": "Thomas Wilkerling", diff --git a/src/common.js b/src/common.js index bad0c3f..f45ef28 100644 --- a/src/common.js +++ b/src/common.js @@ -4,7 +4,6 @@ * @param {*=} merge_value * @return {*} */ - export function merge_option(value, default_value, merge_value){ const type_merge = typeof merge_value; @@ -64,6 +63,13 @@ export function merge_option(value, default_value, merge_value){ : value; } + +export function inherit(target_value, default_value){ + return typeof target_value === "undefined" + ? default_value + : target_value; +} + export function create_object(){ return Object.create(null); } diff --git a/src/document.js b/src/document.js index c9aa76f..cb5ae00 100644 --- a/src/document.js +++ b/src/document.js @@ -153,37 +153,15 @@ export default function Document(options){ if(promises.length){ const self = this; return Promise.all(promises).then(function(result){ - const encoder_last = new Map(); let count = 0; for(const item of self.index.entries()){ const key = /** @type {string} */ (item[0]); let index = /** @type {Index|WorkerIndex | Promise} */ (item[1]); - // let encoder; - // if(SUPPORT_HIGHLIGHTING && SUPPORT_STORE){ - // // make encoder available for result highlighting - // let opt = promises[count].encoder || {}; - // // handle shared encoders - // let encoder = encoder_last.get(opt); - // if(!encoder){ - // encoder = opt.encode - // ? opt - // : SUPPORT_ENCODER - // ? new Encoder( - // SUPPORT_CHARSET && typeof opt === "string" - // ? Charset[opt] - // : opt) - // : { encode: fallback_encoder }; - // encoder_last.set(opt, encoder); - // } - // } if(index.then){ index = result[count]; self.index.set(key, index); count++; } - // if(encoder){ - // index.encoder = encoder; - // } } return self; }); diff --git a/src/document/search.js b/src/document/search.js index 44a3944..59c2c30 100644 --- a/src/document/search.js +++ b/src/document/search.js @@ -1,7 +1,8 @@ // COMPILER BLOCK --> import { DEBUG, - PROFILER, SUPPORT_ASYNC, SUPPORT_CACHE, + PROFILER, + SUPPORT_CACHE, SUPPORT_HIGHLIGHTING, SUPPORT_PERSISTENT, SUPPORT_RESOLVER, @@ -21,7 +22,7 @@ import { SearchResults, IntermediateSearchResults } from "../type.js"; -import { create_object, is_array, is_object, is_string } from "../common.js"; +import { create_object, is_array, is_object, is_string, inherit } from "../common.js"; import { intersect, intersect_union } from "../intersect.js"; import Document from "../document.js"; import Index from "../index.js"; @@ -199,7 +200,7 @@ Document.prototype.search = function(query, limit, options, _promises){ PROFILER && tick("Document.search:tag:get:" + pairs[j + 1]); ids = get_tag.call(this, pairs[j], pairs[j + 1], limit, offset, enrich); } - result.push(resolve ? { + result.push(!SUPPORT_RESOLVER || resolve ? { "field": pairs[j], "tag": pairs[j + 1], "result": ids @@ -210,30 +211,30 @@ Document.prototype.search = function(query, limit, options, _promises){ const self = this; return Promise.all(promises).then(function(promises){ for(let j = 0; j < promises.length; j++){ - if(resolve){ + if(!SUPPORT_RESOLVER || resolve){ result[j]["result"] = promises[j]; } else{ result[j] = promises[j]; } } - return resolve || !SUPPORT_RESOLVER + return !SUPPORT_RESOLVER || resolve ? result : new Resolver(result.length > 1 - ? intersect(result, 1, 0, 0, suggest, boost) + ? intersect(/** @type {!Array} */ (result), 1, 0, 0, suggest, boost) : result[0], self) }); } - return resolve || !SUPPORT_RESOLVER + return !SUPPORT_RESOLVER || resolve ? result : new Resolver(result.length > 1 - ? intersect(result, 1, 0, 0, suggest, boost) + ? intersect(/** @type {!Array} */ (result), 1, 0, 0, suggest, boost) : result[0], this) } } - // upgrade pluck when missing + // upgrade pluck for resolver when missing if(SUPPORT_RESOLVER && !resolve && !pluck){ field = field || this.field; if(field){ @@ -351,7 +352,7 @@ Document.prototype.search = function(query, limit, options, _promises){ } else if(!suggest){ // no tags found - return resolve || !SUPPORT_RESOLVER + return !SUPPORT_RESOLVER || resolve ? result : new Resolver(result, this) } @@ -374,7 +375,7 @@ Document.prototype.search = function(query, limit, options, _promises){ continue; } else{ - return resolve || !SUPPORT_RESOLVER + return !SUPPORT_RESOLVER || resolve ? result : new Resolver(result, this) } @@ -389,7 +390,7 @@ Document.prototype.search = function(query, limit, options, _promises){ } else if(!suggest){ // no tags found - return resolve || !SUPPORT_RESOLVER + return !SUPPORT_RESOLVER || resolve ? result : new Resolver(result, this) } @@ -402,7 +403,7 @@ Document.prototype.search = function(query, limit, options, _promises){ len = res.length; if(!len && !suggest){ // nothing matched - return resolve || !SUPPORT_RESOLVER + return !SUPPORT_RESOLVER || resolve ? res : new Resolver(/** @type {IntermediateSearchResults} */ (res), this); } @@ -418,7 +419,7 @@ Document.prototype.search = function(query, limit, options, _promises){ } else if(field.length === 1){ // fast path: nothing matched - return resolve || !SUPPORT_RESOLVER + return !SUPPORT_RESOLVER || resolve ? result : new Resolver(result, this); } @@ -440,7 +441,7 @@ Document.prototype.search = function(query, limit, options, _promises){ continue; } else{ - return resolve || !SUPPORT_RESOLVER + return !SUPPORT_RESOLVER || resolve ? result : new Resolver(result, this); } @@ -462,13 +463,13 @@ Document.prototype.search = function(query, limit, options, _promises){ } if(!count){ - return resolve || !SUPPORT_RESOLVER + return !SUPPORT_RESOLVER || resolve ? result : new Resolver(result, this); } if(pluck && (!enrich || !this.store)){ result = result[0]; - if(!resolve) result.index = this; + if(SUPPORT_RESOLVER && !resolve) result.index = this; return /** @type {SearchResults|Resolver} */ (result); } @@ -494,7 +495,7 @@ Document.prototype.search = function(query, limit, options, _promises){ } if(pluck){ - return resolve || !SUPPORT_RESOLVER + return !SUPPORT_RESOLVER || resolve ? (highlight ? highlight_fields(/** @type {string} */ (query), res, this.index, pluck, highlight) : /** @type {SearchResults|EnrichedSearchResults} */ (res)) @@ -513,29 +514,21 @@ Document.prototype.search = function(query, limit, options, _promises){ for(let j = 0; j < promises.length; j++){ result[j]["result"] = promises[j]; } + if(highlight){ + result = highlight_fields(/** @type {string} */ (query), result, self.index, pluck, highlight); + } return merge ? merge_fields(result) - : highlight - ? highlight_fields(/** @type {string} */ (query), result, self.index, pluck, highlight) - : /** @type {DocumentSearchResults} */ ( - result - ); + : /** @type {DocumentSearchResults} */ (result); }); } + if(highlight){ + result = highlight_fields(/** @type {string} */ (query), result, this.index, pluck, highlight); + } return merge ? merge_fields(result) - : highlight - ? highlight_fields(/** @type {string} */ (query), result, this.index, pluck, highlight) - : /** @type {DocumentSearchResults} */ ( - result - ); -} - -function inherit(target_value, default_value){ - return typeof target_value === "undefined" - ? default_value - : target_value; + : /** @type {DocumentSearchResults} */ (result); } // todo support Resolver @@ -550,24 +543,33 @@ function inherit(target_value, default_value){ function merge_fields(fields){ /** @type {MergedDocumentSearchResults} */ const final = []; - const set = create_object(); - for(let i = 0, field, res; i < fields.length; i++){ + const group_field = create_object(); + const group_highlight = create_object(); + for(let i = 0, field, key, res, id, entry, tmp, highlight; i < fields.length; i++){ field = fields[i]; + key = field.field; res = field.result; - for(let j = 0, id, entry, tmp; j < res.length; j++){ + for(let j = 0; j < res.length; j++){ entry = res[j]; // upgrade flat results - if(typeof entry !== "object"){ - entry = { "id": entry }; - } - id = entry["id"]; - tmp = set[id]; + typeof entry !== "object" + ? entry = { "id": id = entry } + : id = entry["id"]; + tmp = group_field[id]; if(!tmp){ - entry.field = set[id] = [field.field]; + entry["field"] = group_field[id] = [key]; final.push(/** @type {MergedDocumentSearchEntry} */ (entry)); } else{ - tmp.push(field.field); + tmp.push(key); + } + if(SUPPORT_HIGHLIGHTING && SUPPORT_STORE && (highlight = entry["highlight"])){ + tmp = group_highlight[id]; + if(!tmp){ + group_highlight[id] = tmp = {}; + entry["highlight"] = tmp; + } + tmp[key] = highlight; } } } @@ -581,23 +583,23 @@ function merge_fields(fields){ function get_tag(tag, key, limit, offset, enrich){ PROFILER && tick("Document.search:tag:get:" + key); - let res = this.tag.get(tag); - if(!res){ - DEBUG && console.warn("Tag-Field '" + tag + "' was not found"); - return []; - } - res = res && res.get(key); - let len = res && (res.length - offset); - if(len && (len > 0)){ + let res = this.tag.get(tag); + if(!res) return []; + res = res.get(key); + if(!res) return []; + let len = res.length - offset; + + if(len > 0){ if((limit && len > limit) || offset){ res = res.slice(offset, offset + limit); } if(enrich){ res = apply_enrich.call(this, res); } - return res; } + + return res; } /** diff --git a/src/type.js b/src/type.js index c409e46..58d48e4 100644 --- a/src/type.js +++ b/src/type.js @@ -193,9 +193,10 @@ export let EnrichedDocumentSearchResults = []; /** * @typedef {{ * id: (number|string), - * doc: (Object|null), + * doc: (Object|null|undefined), * field: (Array|undefined), - * tag: (Array|undefined) + * tag: (Array|undefined), + * highlight: (Object|undefined) * }} */ export let MergedDocumentSearchEntry = {}; diff --git a/src/worker.js b/src/worker.js index ec812bd..3dc409c 100644 --- a/src/worker.js +++ b/src/worker.js @@ -84,20 +84,19 @@ export default function WorkerIndex(options = /** @type IndexOptions */ ({}), en }); } - this.worker.postMessage({ - "task": "init", - "factory": factory, - "options": options - }); - if(SUPPORT_ASYNC){ this.priority = options.priority || 4; } // assign encoder for result highlighting - if(encoder){ - this.encoder = encoder; - } + this.encoder = encoder || null; + + // initialize worker index + this.worker.postMessage({ + "task": "init", + "factory": factory, + "options": options + }); return this; } @@ -115,6 +114,7 @@ if(SUPPORT_WORKER){ register("add"); register("append"); register("search"); + register("searchCache"); register("update"); register("remove"); register("clear"); @@ -168,7 +168,7 @@ function create(factory, is_node_js, worker_path){ let worker worker = is_node_js ? - // if anyone would ask me what JS has delivered the past 10 years, + // if anyone asks me what JS has delivered the past 10 years, // those are the lines I definitively show up first ^^ typeof module !== "undefined" // This eval will be removed when compiling diff --git a/task/babel.js b/task/babel.js index 136dafc..77c2c28 100644 --- a/task/babel.js +++ b/task/babel.js @@ -26,6 +26,14 @@ fs.existsSync("dist") || fs.mkdirSync("dist"); `: (0,eval)('import("worker_threads").then(function(worker){return new worker["Worker"]((1,eval)(\\"import.meta.dirname\\")+"/worker/node.mjs")})')` ); } + let tmp; + while(tmp !== src){ + tmp = src; + // remove comments, keep annotations + src = src.replace(/[^:]\/\/(.*)(\r\n|\r|\n|$)/g, "$2"); + src = src.replace(/^\/\/(.*)(\r\n|\r|\n|$)/g, "$2"); + src = src.replace(/\/\*[^*](.*)\*\//g, ""); + } fs.writeFileSync("tmp/" + file, src); } }); @@ -65,6 +73,14 @@ fs.existsSync("dist") || fs.mkdirSync("dist"); // add the eval wrapper src = src.replace('options=(await import(filepath))["default"];', '//options=(await import(filepath))["default"];'); } + let tmp; + while(tmp !== src){ + tmp = src; + // remove comments, keep annotations + src = src.replace(/[^:]\/\/(.*)(\r\n|\r|\n|$)/g, "$2"); + src = src.replace(/^\/\/(.*)(\r\n|\r|\n|$)/g, "$2"); + src = src.replace(/\/\*[^*](.*)\*\//g, ""); + } fs.writeFileSync("tmp/" + path + "/" + file, src); } }); diff --git a/test/highlight.js b/test/highlight.js index 45493ca..efa2612 100644 --- a/test/highlight.js +++ b/test/highlight.js @@ -840,6 +840,66 @@ if(!build_light) describe("Result Highlighting", function(){ expect(result[1].highlight.length).to.below(80 + (7 * 7)); }); + it("Should have been highlighted merged results properly", function(){ + + // some test data + const data = [{ + "id": 1, + "title": "Carmencita", + "description": "Description: Carmencita" + },{ + "id": 2, + "title": "Le clown et ses chiens", + "description": "Description: Le clown et ses chiens" + }]; + + // create the document index + const index = new Document({ + encoder: Charset.LatinBalance, + document: { + store: true, + index: [{ + field: "title", + tokenize: "forward" + },{ + field: "description", + tokenize: "forward" + }] + } + }); + + // add test data + for(let i = 0; i < data.length; i++){ + index.add(data[i]); + } + + let result = index.search({ + query: "karmen or clown or not found", + suggest: true, + enrich: true, + merge: true, + highlight: "$1" + }); + + expect(result).to.eql([{ + id: 1, + doc: data[0], + field: ["title", "description"], + highlight: { + "title": 'Carmencita', + "description": 'Description: Carmencita', + } + },{ + id: 2, + doc: data[1], + field: ["title", "description"], + highlight: { + "title": 'Le clown et ses chiens', + "description": 'Description: Le clown et ses chiens', + } + }]); + }); + it("Should have been highlighted results properly (#480)", function(){ const index = new Document({