diff --git a/dist/db/clickhouse/index.cjs b/dist/db/clickhouse/index.cjs index 8883c2e..eab72f8 100644 --- a/dist/db/clickhouse/index.cjs +++ b/dist/db/clickhouse/index.cjs @@ -85,8 +85,8 @@ function ClickhouseDB(name, config = {}){ return new ClickhouseDB(name, config); } if(typeof name === "object"){ - name = name.name; config = name; + name = name.name; } if(!name){ console.info("Default storage space was used, because a name was not passed."); diff --git a/dist/db/indexeddb/index.cjs b/dist/db/indexeddb/index.cjs deleted file mode 100644 index cbaef6e..0000000 --- a/dist/db/indexeddb/index.cjs +++ /dev/null @@ -1,7071 +0,0 @@ -/** @define {string} */ - -/** @define {boolean} */ -const SUPPORT_PERSISTENT = true; - -/** @define {boolean} */ -const SUPPORT_KEYSTORE = true; - -/** - * @param {*} value - * @param {*} default_value - * @param {*=} merge_value - * @return {*} - */ - -function parse_option(value, default_value, merge_value){ - - const type_merge = typeof merge_value; - const type_value = typeof value; - - if(type_merge !== "undefined"){ - if(type_value !== "undefined"){ - - if(merge_value){ - if(type_value === "function" && - type_merge === type_value){ - return function(str){ - return /** @type Function */ (value)( - /** @type Function */ (merge_value)(str) - ); - } - } - - const constructor_value = value.constructor; - const constructor_merge = merge_value.constructor; - - if(constructor_value === constructor_merge){ - - if(constructor_value === Array){ - return merge_value.concat(value); - } - - if(constructor_value === Map){ - const map = new Map(/** @type !Map */ (merge_value)); - for(const item of /** @type !Map */ (value)){ - const key = item[0]; - const val = item[1]; - map.set(key, val); - } - return map; - } - - if(constructor_value === Set){ - const set = new Set(/** @type !Set */ (merge_value)); - for(const val of /** @type !Set */ (value).values()){ - set.add(val); - } - return set; - } - } - } - - return value; - } - else { - return merge_value; - } - } - - return type_value === "undefined" - ? default_value - : value; -} - -function create_object(){ - return Object.create(null); -} - -function concat(arrays){ - return [].concat.apply([], arrays); -} - -function sort_by_length_down(a, b){ - return b.length - a.length; -} - -function is_array(val){ - return val.constructor === Array; -} - -function is_string(val){ - return typeof val === "string"; -} - -function is_object(val){ - return typeof val === "object"; -} - -function is_function(val){ - return typeof val === "function"; -} - -/** - * @param {Map|Set} val - * @param {boolean=} stringify - * @return {Array} - */ - -function toArray(val, stringify){ - const result = []; - for(const key of val.keys()){ - result.push(key); - } - return result; -} - -// TODO support generic function created from string when tree depth > 1 -function parse_simple(obj, tree){ - - if(is_string(tree)){ - obj = obj[tree]; - } - else for(let i = 0; obj && (i < tree.length); i++){ - obj = obj[tree[i]]; - } - - return obj; -} - -function get_max_len(arr){ - let len = 0; - for(let i = 0, res; i < arr.length; i++){ - if((res = arr[i])){ - if(len < res.length){ - len = res.length; - } - } - } - return len; -} - -var normalize_polyfill = [ - - // 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} - // ["-", " "], - // [":", " "], - // ["_", " "], - // ["|", " "], - // ["/", " "], - // ["\\", " "] -]; - -// COMPILER BLOCK --> - -/* - -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 (Workflow) ----------------------------- -Pipeline: - 1. apply this.normalize: charset normalization: - applied on the whole input string e.g. lowercase, - will also apply on: filter, matcher, stemmer, mapper - 2. apply this.split: split input into terms (includes/excludes) - 3. apply this.filter (pre-filter) - 4. apply this.matcher (replace terms) - 5. apply this.stemmer (replace term endings) - 6. apply this.filter (post-filter) - 7. apply this.mapper (replace chars) - 8. apply this.replacer (custom regex) - 9. apply this.dedupe (letter deduplication) - 10. apply this.finalize -*/ - -const whitespace = /[^\p{L}\p{N}]+/u; // /[\p{Z}\p{S}\p{P}\p{C}]+/u; -//const numeric_split = /(\d{3})/g; -const numeric_split_length = /(\d{3})/g; -const numeric_split_prev_char = /(\D)(\d{3})/g; -const numeric_split_next_char = /(\d{3})(\D)/g; -//.replace(/(\d{3})/g, "$1 ") -//.replace(/([^\d])([\d])/g, "$1 $2") -//.replace(/([\d])([^\d])/g, "$1 $2") -const normalize = "".normalize && /[\u0300-\u036f]/g; // '´`’ʼ., -//const normalize_mapper = SUPPORT_CHARSET && !normalize && normalize_polyfill; - -/** - * @param {EncoderOptions=} options - * @constructor - */ - -function Encoder(options){ - - if(!this || this.constructor !== Encoder){ - return new Encoder(...arguments); - } - - for(let i = 0; i < arguments.length; i++){ - this.assign(arguments[i]); - } -} -/** - * @param {!EncoderOptions} options - */ -Encoder.prototype.assign = function(options){ - - /** - * pre-processing string input - * @type {Function|boolean} - */ - this.normalize = /** @type {Function|boolean} */ ( - parse_option(options.normalize, true, this.normalize) - ); - - // { - // letter: true, - // number: true, - // whitespace: true, - // symbol: true, - // punctuation: true, - // control: true, - // char: "" - // } - - let include = options.include; - let tmp = include || options.exclude || options.split; - - if(typeof tmp === "object"){ - let numeric = !include; - let regex = ""; - // split on whitespace by default - options.include || ( - regex += "\\p{Z}" - ); - if(tmp.letter){ - regex += "\\p{L}"; - } - if(tmp.number){ - regex += "\\p{N}"; - numeric = !!include; - } - if(tmp.symbol){ - regex += "\\p{S}"; - } - if(tmp.punctuation){ - regex += "\\p{P}"; - } - if(tmp.control){ - regex += "\\p{C}"; - } - if((tmp = tmp.char)){ - regex += typeof tmp === "object" ? tmp.join("") : tmp; - } - - try{ - // https://github.com/nextapps-de/flexsearch/issues/410 - /** - * 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+/; - } - this.numeric = numeric; - } - else { - try{ - // https://github.com/nextapps-de/flexsearch/issues/410 - this.split = /** @type {string|RegExp|boolean} */ (parse_option(tmp, whitespace, this.split)); - } - catch(e){ - // fallback to a simple whitespace splitter - this.split = /\s+/; - } - this.numeric = parse_option(this.numeric, true); - } - - /** - * post-processing terms - * @type {Function|null} - */ - this.prepare = /** @type {Function|null} */ ( - parse_option(options.prepare, null, this.prepare) - ); - /** - * final processing - * @type {Function|null} - */ - this.finalize = /** @type {Function|null} */ ( - parse_option(options.finalize, null, this.finalize) - ); - - // assign the normalization fallback to the mapper - if(!normalize){ - this.mapper = new Map( - /** @type {Array>} */ ( - normalize_polyfill - ) - ); - } - - // options - - this.rtl = options.rtl || false; - this.dedupe = parse_option(options.dedupe, true, this.dedupe); - this.filter = parse_option((tmp = options.filter) && new Set(tmp), null, this.filter); - this.matcher = parse_option((tmp = options.matcher) && new Map(tmp), null, this.matcher); - this.mapper = parse_option((tmp = options.mapper) && new Map(tmp), null, this.mapper); - this.stemmer = parse_option((tmp = options.stemmer) && new Map(tmp), null, this.stemmer); - this.replacer = parse_option(options.replacer, null, this.replacer); - this.minlength = parse_option(options.minlength, 1, this.minlength); - this.maxlength = parse_option(options.maxlength, 0, this.maxlength); - - // minimum required tokenizer by this encoder - //this.tokenize = options["tokenize"] || ""; - - // auto-balanced cache - { - this.cache = tmp = parse_option(options.cache, true, this.cache); - if(tmp){ - this.timer = null; - this.cache_size = typeof tmp === "number" ? 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; - } - } - if(this.stemmer){ - for(const key of this.stemmer.keys()){ - this.stemmer_str += (this.stemmer_str ? "|" : "") + key; - } - } - - // if(SUPPORT_COMPRESSION){ - // this.compression = parse_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; -}; - -Encoder.prototype.addMatcher = function(match, replace){ - // regex: - if(typeof match === "object"){ - return this.addReplacer(match, replace); - } - // a single char: - if(match.length < 2){ - return this.addMapper(match, replace); - } - this.matcher || (this.matcher = new Map()); - this.matcher.set(match , replace); - this.matcher_str += (this.matcher_str ? "|" : "") + match; - this.matcher_test = null; //new RegExp("(" + this.matcher_str + ")"); - this.cache && this.invalidate(); - return this; -}; - -Encoder.prototype.addStemmer = function(match, replace){ - this.stemmer || (this.stemmer = new Map()); - this.stemmer.set(match, replace); - this.stemmer_str += (this.stemmer_str ? "|" : "") + match; - this.stemmer_test = null; //new RegExp("(" + this.stemmer_str + ")"); - this.cache && this.invalidate(); - return this; -}; - -Encoder.prototype.addFilter = function(str){ - this.filter || (this.filter = new Set()); - this.filter.add(str); - this.cache && this.invalidate(); - return this; -}; - -Encoder.prototype.addMapper = function(char_match, char_replace){ - // regex: - if(typeof char_match === "object"){ - return this.addReplacer(char_match, char_replace); - } - // not a char: - if(char_match.length > 1){ - return this.addMatcher(char_match, char_replace); - } - this.mapper || (this.mapper = new Map()); - this.mapper.set(char_match, char_replace); - this.cache && this.invalidate(); - return this; -}; - -Encoder.prototype.addReplacer = function(match, replace){ - if(typeof match === "string") match = new RegExp(match, "g"); - this.replacer || (this.replacer = []); - this.replacer.push(match, replace || ""); - this.cache && this.invalidate(); - return this; -}; - -{ - Encoder.prototype.invalidate = function(){ - this.cache_enc.clear(); - this.cache_term.clear(); - }; -} - -Encoder.prototype.encode = function(str){ - - //if(!str) return str; - // todo remove dupe terms - - if(this.cache && str.length <= this.cache_enc_length){ - if(this.timer){ - if(this.cache_enc.has(str)){ - return this.cache_enc.get(str); - } - } - else { - this.timer = setTimeout(clear$1, 50, this); - } - } - - // 1. apply charset normalization - if(this.normalize){ - if(typeof this.normalize === "function"){ - str = this.normalize(str); - } - else if(normalize){ - str = str.normalize("NFKD").replace(normalize, "").toLowerCase(); - } - else { - str = str.toLowerCase(); - // if(SUPPORT_CHARSET){ - // this.mapper = this.mapper - // // todo replace spread - // ? new Map([.../** @type {!Iterable} */(normalize_mapper), ...this.mapper]) - // : new Map(/** @type {Map} */ (normalize_mapper)); - // } - } - //if(!str) return str; - } - - // 2. apply custom encoder (can replace split) - if(this.prepare){ - str = this.prepare(str); - } - - // 3. split numbers into triplets - if(this.numeric && str.length > 3){ - 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 = []; - let words = this.split || this.split === "" - ? str.split(/** @type {string|RegExp} */ (this.split)) - : str; //[str]; - - for(let i = 0, word, base; i < words.length; i++){ - // filter empty entries - if(!(word = base = words[i])){ - continue; - } - if(word.length < this.minlength){ - continue; - } - if(skip) { - final.push(word); - continue; - } - - // 1. pre-filter before cache - if(this.filter && this.filter.has(word)){ - continue; - } - - if(this.cache && word.length <= this.cache_term_length){ - if(this.timer){ - const tmp = this.cache_term.get(word); - //if(this.cache_term.has(word)){ - if(tmp || tmp === ""){ - //word = this.cache_term.get(word); - tmp && final.push(tmp); - //word ? words[i] = word : words.splice(i--, 1); - continue; - } - } - else { - this.timer = setTimeout(clear$1, 50, this); - } - } - - let postfilter; - - // if(this.normalize === true && normalize){ - // word = word.normalize("NFKD").replace(normalize, ""); - // postfilter = 1; - // } - - // if(this.normalize){ - // if(typeof this.normalize === "function"){ - // word = this.normalize(word); - // } - // else if(normalize){ - // word = word.normalize("NFKD").replace(normalize, "").toLowerCase(); - // } - // else{ - // word = word.toLowerCase(); - // this.mapper = this.mapper - // ? new Map([...normalize_mapper, ...this.mapper]) - // : new Map(/** @type {Map} */ normalize_mapper); - // } - // postfilter = 1; - // //if(!str) return str; - // } - - // 2. apply stemmer after matcher - if(this.stemmer && (word.length > 2)){ - // 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; - // // } - // } - this.stemmer_test || ( - this.stemmer_test = new RegExp("(?!^)(" + this.stemmer_str + ")$") - ); - word = word.replace(this.stemmer_test, match => this.stemmer.get(match)); - postfilter = 1; - } - - // 4. post-filter after matcher and stemmer was applied - if(word && postfilter && (word.length < this.minlength || (this.filter && this.filter.has(word)))){ - word = ""; - } - - // 5. apply mapper and collapsing - if(word && (this.mapper || (this.dedupe && word.length > 1))){ - //word = this.replace_dedupe(word); - //word = replace_deduped(word, this.mapper, true); - let final = ""; - for(let i = 0, prev = "", char, tmp; i < word.length; i++){ - char = word.charAt(i); - if(char !== prev || !this.dedupe){ - tmp = this.mapper && this.mapper.get(char); - if(!tmp && tmp !== "") - final += (prev = char); - else if((tmp !== prev || !this.dedupe) && (prev = tmp)) - final += tmp; - } - } - word = final; - } - - // 3. apply matcher - if(this.matcher && (word.length > 1)){ - this.matcher_test || ( - this.matcher_test = new RegExp("(" + this.matcher_str + ")", "g") - ); - word = word.replace(this.matcher_test, match => this.matcher.get(match)); - //postfilter = 1; - } - - // 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(word){ - // words[i] = word; - // } - - if(this.cache && base.length <= this.cache_term_length){ - this.cache_term.set(base, word); - if(this.cache_term.size > this.cache_size){ - this.cache_term.clear(); - this.cache_term_length = this.cache_term_length / 1.1 | 0; - } - } - - //word || words.splice(i--, 1); - word && final.push(word); - } - - //words = final; - // else if(this.filter){ - // for(let i = 0, word; i < words.length; i++){ - // if((word = words[i]) && !this.filter.has(word)){ - // //filtered.push(word); - // words.splice(i--, 1); - // } - // } - // } - - if(this.finalize){ - final = this.finalize(final) || final; - } - - if(this.cache && str.length <= this.cache_enc_length){ - this.cache_enc.set(str, final); - if(this.cache_enc.size > this.cache_size){ - this.cache_enc.clear(); - this.cache_enc_length = this.cache_enc_length / 1.1 | 0; - } - } - - return final; -}; - -// 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; -// } - -function clear$1(self){ - self.timer = null; - self.cache_enc.clear(); - self.cache_term.clear(); -} - -async function handler(data) { - - data = data["data"]; - - /** @type Index */ - const index = self["_index"]; - const args = data["args"]; - const task = data["task"]; - - switch(task){ - - case "init": - - /** @type {IndexOptions} */ - let options = data["options"] || {}; - let filepath = options.config; - if(filepath){ - 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); - - /** @type Index */ - self["_index"] = new self["FlexSearch"]["Index"](options); - - // destroy the exported payload - delete self["FlexSearch"]; - } - else { - - self["_index"] = new Index(options); - } - - postMessage({ "id": data["id"] }); - break; - - default: - - const id = data["id"]; - const message = index[task].apply(index, args); - postMessage( - task === "search" - ? { "id": id, "msg": message } - : { "id": id } - ); - } -} - -let pid = 0; - -/** - * @param {IndexOptions=} options - * @constructor - */ - -function WorkerIndex(options = /** @type IndexOptions */ ({})){ - - if(!this || this.constructor !== WorkerIndex) { - return new WorkerIndex(options); - } - - // the factory is the outer wrapper from the build - // it uses "self" as a trap for node.js - let factory = typeof self !== "undefined" - ? self["_factory"] - : typeof window !== "undefined" - ? window["_factory"] - : null; - if(factory){ - factory = factory.toString(); - } - - const is_node_js = typeof window === "undefined" /*&& self["exports"]*/; - const _self = this; - - /** - * @this {WorkerIndex} - */ - function init(worker){ - - this.worker = worker; - this.resolver = create_object(); - - if(!this.worker){ - return; - } - - function onmessage(msg){ - msg = msg["data"] || msg; - const id = msg["id"]; - const res = id && _self.resolver[id]; - if(res){ - res(msg["msg"]); - delete _self.resolver[id]; - } - } - - is_node_js - ? this.worker["on"]("message", onmessage) - : this.worker.onmessage = onmessage; - - 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(){ - resolve(_self); - }; - - _self.worker.postMessage({ - "id": pid, - "task": "init", - "factory": factory, - "options": options - }); - }); - } - - this.worker.postMessage({ - "task": "init", - "factory": factory, - "options": options - }); - - return this; - } - - const worker = create(factory, is_node_js, options.worker); - //worker.worker = true; - return worker.then - ? worker.then(function(worker){ - return init.call(_self, worker); - }) - : init.call(this, worker); -} - -register$1("add"); -register$1("append"); -register$1("search"); -register$1("update"); -register$1("remove"); - -function register$1(key){ - - WorkerIndex.prototype[key] = - WorkerIndex.prototype[key + "Async"] = async function(){ - - const self = this; - const args = [].slice.call(arguments); - const arg = args[args.length - 1]; - let callback; - - if(is_function(arg)){ - callback = arg; - args.splice(args.length - 1, 1); - } - - const promise = new Promise(function(resolve){ - //setTimeout(function(){ - self.resolver[++pid] = resolve; - self.worker.postMessage({ - "task": key, - "id": pid, - "args": args - }); - //}); - }); - - if(callback){ - promise.then(callback); - return this; - } - else { - - return promise; - } - }; -} - -function create(factory, is_node_js, worker_path){ - - let worker; - - worker = is_node_js ? - // This eval will be removed when compiling, it isn't there in final build - - typeof module !== "undefined" - ? (0, eval)('new (require("worker_threads")["Worker"])(__dirname + "/node/node.js")') - //: (0,eval)('new ((await import("worker_threads"))["Worker"])(import.meta.dirname + "/worker/node.mjs")') - //: (0,eval)('new ((await import("worker_threads"))["Worker"])((1,eval)(\"import.meta.dirname\") + "/node/node.mjs")') - : (0, eval)('import("worker_threads").then(function(worker){ return new worker["Worker"]((1,eval)(\"import.meta.dirname\") + "/node/node.mjs"); })') - //: import("worker_threads").then(function(worker){ return new worker["Worker"](import.meta.dirname + "/worker/node.mjs"); }) - - //eval('new (require("worker_threads")["Worker"])(__dirname + "/node/node.js")') - :( - factory ? - new window.Worker(URL.createObjectURL( - new Blob( - ["onmessage=" + handler.toString()], - { "type": "text/javascript" } - ) - )) - : - new window.Worker(is_string(worker_path) ? worker_path : import.meta.url.replace("/worker.js", "/worker/worker.js").replace("flexsearch.bundle.module.min.js", "module/worker/worker.js") /*"worker/worker.js"*/, { type: "module" }) - ); - - return worker; -} - -function apply_async(prototype){ - register.call(prototype, "add"); - register.call(prototype, "append"); - register.call(prototype, "search"); - register.call(prototype, "update"); - register.call(prototype, "remove"); - // prototype.addAsync = prototype.add; - // prototype.appendAsync = prototype.append; - // prototype.searchAsync = prototype.search; - // prototype.updateAsync = prototype.update; - // prototype.removeAsync = prototype.remove; -} - -// let cycle; -// let budget = 0; -// -// function tick(resolve){ -// cycle = null; -// budget = 0; -// resolve(); -// } - -/* - -automatisch - */ - -/** - * @param {!string} key - * @this {Index|Document} - */ - -function register(key){ - this[key + "Async"] = function(){ - - // // prevent stack overflow of adding too much tasks to the same event loop - // // actually limit stack to 1,000,000 tasks every ~4ms - // cycle || ( - // cycle = new Promise(resolve => setTimeout(tick, 0, resolve)) - // ); - // - // // apply different performance budgets - // if(key === "update" || key === "remove" && this.fastupdate === false){ - // budget += 1000 * this.resolution; - // if(this.depth) - // budget += 1000 * this.resolution_ctx; - // } - // else if(key === "search"){ - // budget++; - // } - // else{ - // budget += 20 * this.resolution; - // if(this.depth) - // budget += 20 * this.resolution_ctx; - // } - // - // // wait for the event loop cycle - // if(budget >= 1e6){ - // await cycle; - // } - - const args = /*[].slice.call*/(arguments); - const arg = args[args.length - 1]; - let callback; - - if(typeof arg === "function"){ - callback = arg; - delete args[args.length - 1]; - } - - //this.async = true; - const res = this[key].apply(this, args); - //this.async = false; - if(callback){ - res.then - ? res.then(callback) - : callback(res); - } - return res; - }; -} - -const chunk_size_reg = 250000; -const chunk_size_map = 5000; -const chunk_size_ctx = 1000; - -function map_to_json(map, size = 0){ - let chunk = []; - let json = []; - if(size){ - size = chunk_size_map * (chunk_size_reg / size) | 0; - } - for(const item of map.entries()){ - json.push(item); - if(json.length === size){ - chunk.push(json); - json = []; - } - } - json.length && chunk.push(json); - return chunk; -} - -function json_to_map(json, map){ - map || (map = new Map()); - for(let i = 0, entry; i < json.length; i++) { - entry = json[i]; - map.set(entry[0], entry[1]); - } - return map; -} - -function ctx_to_json(ctx, size = 0){ - let chunk = []; - let json = []; - if(size){ - size = chunk_size_ctx * (chunk_size_reg / size) | 0; - } - for(const item of ctx.entries()){ - const key = item[0]; - const value = item[1]; - json.push([key, map_to_json(value)[0]]); - if(json.length === size){ - chunk.push(json); - json = []; - } - } - json.length && chunk.push(json); - return chunk; -} - -function json_to_ctx(json, ctx){ - ctx || (ctx = new Map()); - for(let i = 0, entry, map; i < json.length; i++) { - entry = json[i]; - map = ctx.get(entry[0]); - ctx.set(entry[0], json_to_map(entry[1], map)); - } - return ctx; -} - -function reg_to_json(reg){ - let chunk = []; - let json = []; - for(const key of reg.keys()){ - json.push(key); - if(json.length === chunk_size_reg){ - chunk.push(json); - json = []; - } - } - json.length && chunk.push(json); - return chunk; -} - -function json_to_reg(json, reg){ - reg || (reg = new Set()); - for(let i = 0; i < json.length; i++) { - reg.add(json[i]); - } - return reg; -} - -/** - * @this {Index|Document} - */ - -function save(callback, field, key, chunk, index_doc, index_obj, index_prt = 0){ - - const is_arr = chunk && chunk.constructor === Array; - const data = is_arr ? chunk.shift() : chunk; - if(!data){ - return this.export( - callback, - field, - index_doc, - index_obj + 1 - ); - } - - const res = callback( - (field ? field + "." : "") + (index_prt + 1) + "." + key, - JSON.stringify(data) - ); - - if(res && res["then"]){ - const self = this; - return res["then"](function(){ - return save.call(self, - callback, - field, - key, - is_arr ? chunk : null, - index_doc, - index_obj, - index_prt + 1 - ); - }); - } - - return save.call(this, - callback, - field, - key, - is_arr ? chunk : null, - index_doc, - index_obj, - index_prt + 1 - ); -} - -/** - * @param {function(string,string):Promise|void} callback - * @param {string|null=} field - * @param {number=} index_doc - * @param {number=} index_obj - * @this {Index} - */ - -function exportIndex(callback, field, index_doc, index_obj = 0){ - - let key, chunk; - - switch(index_obj){ - - case 0: - - key = "reg"; - chunk = reg_to_json(this.reg); - break; - - case 1: - - // todo - key = "cfg"; - chunk = {}; - break; - - case 2: - - key = "map"; - chunk = map_to_json(this.map, this.reg.size); - break; - - case 3: - - key = "ctx"; - chunk = ctx_to_json(this.ctx, this.reg.size); - break; - - default: - - return; - } - - return save.call(this, - callback, - field, - key, - chunk, - index_doc, - index_obj - ); -} - -/** - * @param {string} key - * @param {string|*} data - * @this Index - */ - -function importIndex(key, data){ - - if(!data){ - return; - } - if(is_string(data)){ - data = JSON.parse(/** @type {string} */(data)); - } - - const split = key.split("."); - if(split[split.length - 1] === "json"){ - split.pop(); - } - key = split.length > 1 ? split[1] : split[0]; - - switch(key){ - - case "cfg": - // todo - break; - - case "reg": - - // fast update isn't supported by export/import - this.fastupdate = false; - this.reg = json_to_reg(data, this.reg); - break; - - case "map": - - this.map = json_to_map(data, this.map); - break; - - case "ctx": - - this.ctx = json_to_ctx(data, this.ctx); - break; - } -} - -/** - * @param {function(string,string):Promise|void} callback - * @param {string|null=} field - * @param {number=} index_doc - * @param {number=} index_obj - * @this {Document} - */ - -function exportDocument(callback, field, index_doc = 0, index_obj = 0){ - - if(index_doc < this.field.length){ - - const field = this.field[index_doc]; - const idx = this.index.get(field); - // start from index 1, because document indexes does not additionally store register - const res = idx.export(callback, field, index_doc, index_obj = 1); - - if(res && res["then"]){ - const self = this; - return res["then"](function(){ - return self.export(callback, field, index_doc + 1); - }); - } - - return this.export(callback, field, index_doc + 1); - } - else { - - let key, chunk; - - switch(index_obj){ - - case 0: - - key = "reg"; - chunk = reg_to_json(this.reg); - field = null; - break; - - case 1: - - key = "tag"; - chunk = ctx_to_json(this.tag, this.reg.size); - field = null; - break; - - case 2: - - key = "doc"; - chunk = map_to_json(this.store); - field = null; - break; - - case 3: - - key = "cfg"; - chunk = {}; - field = null; - break; - - default: - - return; - } - - return save.call(this, - callback, - field, - key, - chunk, - index_doc, - index_obj - ); - } -} - -/** - * @param key - * @param {string|*} data - * @this {Document} - */ - -function importDocument(key, data){ - - if(!data){ - return; - } - if(is_string(data)){ - data = JSON.parse(/** @type {string} */(data)); - } - - const split = key.split("."); - if(split[split.length - 1] === "json"){ - split.pop(); - } - const field = split.length > 2 ? split[0] : ""; - key = split.length > 2 ? split[2] : split[1]; - - if(!field){ - - switch(key){ - - case "reg": - - // fast update isn't supported by export/import - this.fastupdate = false; - this.reg = json_to_reg(data, this.reg); - - for(let i = 0, idx; i < this.field.length; i++){ - idx = this.index.get(this.field[i]); - idx.fastupdate = false; - idx.reg = this.reg; - } - - break; - - case "tag": - - this.tag = json_to_ctx(data, this.tag); - break; - - case "doc": - - this.store = json_to_map(data, this.store); - break; - - } - } - else { - - return this.index.get(field).import(key, data); - } -} - -/* -reg: "1,2,3,4,5,6,7,8,9" -map: "gulliver:1,2,3|4,5,6|7,8,9;" -ctx: "gulliver+travel:1,2,3|4,5,6|7,8,9;" -*/ - -/** - * @this {Index} - * @param {boolean} withFunctionWrapper - * @return {string} - */ - -function serialize(withFunctionWrapper = true){ - - if(!this.reg.size) return ""; - - let reg = ''; - let type = ""; - for(const key of this.reg.keys()){ - type || (type = typeof key); - reg += (reg ? ',' : '') + (type === "string" ? '"' + key + '"' : key); - } - reg = 'index.reg=new Set([' + reg + ']);'; - - let map = ''; - for(const item of this.map.entries()){ - const key = item[0]; - const value = item[1]; - let res = ''; - for(let i = 0, ids; i < value.length; i++){ - ids = value[i] || ['']; - let str = ''; - for(let j = 0; j < ids.length; j++){ - str += (str ? ',' : '') + (type === "string" ? '"' + ids[j] + '"' : ids[j]); - } - str = '[' + str + ']'; - res += (res ? ',' : '') + str; - } - res = '["' + key + '",[' + res + ']]'; - map += (map ? ',' : '') + res; - } - map = "index.map=new Map([" + map + "]);"; - - let ctx = ''; - for(const context of this.ctx.entries()){ - const key_ctx = context[0]; - const value_ctx = context[1]; - - for(const item of value_ctx.entries()){ - const key = item[0]; - const value = item[1]; - - let res = ''; - for(let i = 0, ids; i < value.length; i++){ - ids = value[i] || ['']; - let str = ''; - for(let j = 0; j < ids.length; j++){ - str += (str ? ',' : '') + (type === "string" ? '"' + ids[j] + '"' : ids[j]); - } - str = '[' + str + ']'; - res += (res ? ',' : '') + str; - } - res = 'new Map([["' + key + '",[' + res + ']]])'; - res = '["' + key_ctx + '",' + res + ']'; - ctx += (ctx ? ',' : '') + res; - } - } - ctx = "index.ctx=new Map([" + ctx + "]);"; - - return withFunctionWrapper - ? "function inject(index){" + reg + map + ctx + "}" - : reg + map + ctx -} - -// 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++){ - index = self.index[i]; - if(start >= index.length){ - start -= index.length; - } - else { - const tmp = index[splice ? "splice" : "slice"](start, end); - const length = tmp.length; - if(length){ - arr = arr.length - ? arr.concat(tmp) - : tmp; - end -= length; - if(splice) self.length -= length; - if(!end) break; - } - start = 0; - } - } - return arr; -} - -/** - * @param arr - * @constructor - */ - -function KeystoreArray(arr){ - - if(!this){ - return new KeystoreArray(arr); - } - - this.index = arr ? [arr] : []; - this.length = arr ? arr.length : 0; - const self = this; - - return /*this.proxy =*/ new Proxy([], { - get(target, key) { - if(key === "length"){ - return self.length; - } - if(key === "push"){ - return function(value){ - self.index[self.index.length - 1].push(value); - self.length++; - } - } - if(key === "pop"){ - return function(){ - if(self.length){ - self.length--; - return self.index[self.index.length - 1].pop(); - } - } - } - if(key === "indexOf"){ - 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(tmp >= 0) return index + tmp; - index += arr.length; - } - return -1; - } - } - if(key === "includes"){ - return function(key){ - for(let i = 0; i < self.index.length; i++){ - if(self.index[i].includes(key)){ - return true; - } - } - return false; - } - } - if(key === "slice"){ - return function(start, end){ - return _slice( - self, - start || 0, - end || self.length, - false - ); - } - } - if(key === "splice"){ - return function(start, end){ - return _slice( - self, - start || 0, - end || self.length, - // splice: - true - ); - } - } - if(key === "constructor"){ - return Array; - } - if(typeof key === "symbol" /*|| isNaN(key)*/){ - // not supported - return; - } - const index = key / (2**31) | 0; - const arr = self.index[index]; - return arr && arr[key]; - }, - set(target, key, value){ - const index = key / (2**31) | 0; - const arr = self.index[index] || (self.index[index] = []); - arr[key] = value; - self.length++; - return true; - } - }); -} - -KeystoreArray.prototype.clear = function(){ - this.index.length = 0; -}; - -KeystoreArray.prototype.destroy = function(){ - this.index = null; - this.proxy = null; -}; - -KeystoreArray.prototype.push = function(val){}; - -/** - * @param bitlength - * @constructor - */ - -function KeystoreMap(bitlength = 8){ - - if(!this){ - return new KeystoreMap(bitlength); - } - - this.index = create_object(); - this.refs = []; - this.size = 0; - - if(bitlength > 32){ - this.crc = lcg64; - this.bit = BigInt(bitlength); - } - else { - this.crc = lcg$1; - this.bit = bitlength; - } -} - -KeystoreMap.prototype.get = function(key) { - const address = this.crc(key); - const map = this.index[address]; - return map && map.get(key); -}; - -KeystoreMap.prototype.set = function(key, value){ - const address = this.crc(key); - let map = this.index[address]; - if(map){ - let size = map.size; - map.set(key, value); - size -= map.size; - size && this.size++; - } - else { - this.index[address] = map = new Map([[key, value]]); - this.refs.push(map); - } -}; - -/** - * @param bitlength - * @constructor - */ - -function KeystoreSet(bitlength = 8){ - - if(!this){ - return new KeystoreSet(bitlength); - } - - // using plain Object with numeric key access - // just for max performance - this.index = create_object(); - this.refs = []; - - if(bitlength > 32){ - this.crc = lcg64; - this.bit = BigInt(bitlength); - } - else { - this.crc = lcg$1; - this.bit = bitlength; - } -} - -KeystoreSet.prototype.add = function(key){ - const address = this.crc(key); - let set = this.index[address]; - if(set){ - let size = set.size; - set.add(key); - size -= set.size; - size && this.size++; - } - else { - this.index[address] = set = new Set([key]); - this.refs.push(set); - } -}; - -KeystoreMap.prototype.has = -KeystoreSet.prototype.has = function(key) { - const address = this.crc(key); - const map_or_set = this.index[address]; - return map_or_set && map_or_set.has(key); -}; - -/* -KeystoreMap.prototype.size = -KeystoreSet.prototype.size = function(){ - let size = 0; - const values = Object.values(this.index); - for(let i = 0; i < values.length; i++){ - size += values[i].size; - } - return size; -}; -*/ - -KeystoreMap.prototype.delete = -KeystoreSet.prototype.delete = function(key){ - const address = this.crc(key); - const 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--; -}; - -KeystoreMap.prototype.clear = -KeystoreSet.prototype.clear = function(){ - this.index = create_object(); - this.refs = []; - this.size = 0; -}; - -// KeystoreMap.prototype.destroy = -// KeystoreSet.prototype.destroy = function(){ -// this.index = null; -// this.refs = null; -// this.proxy = null; -// }; - -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; - } - } -}; - -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; - } - } -}; - -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; - } - } -}; - -/** - * Linear Congruential Generator (LCG) - * @param str - * @this {KeystoreMap|KeystoreSet} - */ - -function lcg$1(str) { - let range = 2 ** this.bit - 1; - if(typeof str == "number"){ - return str & range; - } - let crc = 0, bit = this.bit + 1; - 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 this.bit === 32 - ? crc + 2 ** 31 - : crc;// & 0xFFFF; -} - -/** - * @param str - * @this {KeystoreMap|KeystoreSet} - */ - -function lcg64(str) { - let range = BigInt(2) ** /** @type {!BigInt} */ (this.bit) - BigInt(1); - let type = typeof str; - if(type === "bigint"){ - return /** @type {!BigInt} */ (str) & range; - } - if(type === "number"){ - return BigInt(str) & range; - } - let crc = BigInt(0), bit = /** @type {!BigInt} */ (this.bit) + BigInt(1); - for(let i = 0; i < str.length; i++){ - crc = (crc * bit ^ BigInt(str.charCodeAt(i))) & range; - } - return crc;// & 0xFFFFFFFFFFFFFFFF; -} - -// COMPILER BLOCK --> - -/** - * - * @param id - * @param content - * @param {boolean=} _append - * @returns {Document|Promise} - */ - -Document.prototype.add = function(id, content, _append){ - - if(is_object(id)){ - - content = id; - id = parse_simple(content, this.key); - } - - if(content && (id || (id === 0))){ - - if(!_append && this.reg.has(id)){ - 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]; - - const index = this.index.get(this.field[i]); - if(typeof tree === "function"){ - const tmp = tree(content); - if(tmp){ - index.add(id, tmp, /* append: */ false, /* skip update: */ true); - } - } - else { - const filter = tree._filter; - if(filter && !filter(content)){ - continue; - } - if(tree.constructor === String){ - tree = ["" + tree]; - } - else if(is_string(tree)){ - tree = [tree]; - } - add_index(content, tree, this.marker, 0, index, id, tree[0], _append); - } - } - - if(this.tag){ - - //console.log(this.tag, this.tagtree) - - for(let x = 0; x < this.tagtree.length; x++){ - - let tree = this.tagtree[x]; - let field = this.tagfield[x]; - let ref = this.tag.get(field); - let dupes = create_object(); - let tags; - - if(typeof tree === "function"){ - tags = tree(content); - if(!tags) continue; - } - else { - const filter = tree._filter; - if(filter && !filter(content)){ - continue; - } - if(tree.constructor === String){ - tree = "" + tree; - } - tags = parse_simple(content, tree); - } - - if(!ref || !tags){ - ref || (console.warn("Tag '" + field + "' was not found")); - continue; - } - - if(is_string(tags)){ - tags = [tags]; - } - - 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; - - let tmp; - tmp = ref.get(tag); - 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(arr.length === 2**31-1 /*|| !(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; - } - } - } - 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]); - } - } - } - } - } - } - - if(this.store && (!_append || !this.store.has(id))){ - - let payload; - - if(this.storetree){ - - payload = create_object(); - - for(let i = 0, tree; i < this.storetree.length; i++){ - tree = this.storetree[i]; - - const filter = tree._filter; - if(filter && !filter(content)){ - continue; - } - let custom; - if(typeof tree === "function"){ - custom = tree(content); - if(!custom) continue; - tree = [tree._field]; - } - else if(is_string(tree) || tree.constructor === String){ - payload[tree] = content[tree]; - continue; - } - - store_value(content, payload, tree, 0, tree[0], custom); - } - } - - this.store.set(id, payload || content); - } - } - - return this; -}; - -// TODO support generic function created from string when tree depth > 1 - -/** - * @param obj - * @param store - * @param tree - * @param pos - * @param key - * @param {*=} custom - */ - -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){ - - if(is_array(obj)){ - - store = store[key] = new 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 { - - store = store[key] || (store[key] = create_object()); - key = tree[++pos]; - store_value(obj, store, tree, pos, key); - } - } -} - -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], /* append: */ true, /* skip update: */ true); - } - return; - } - - // or join array contents and use one scoring context - obj = obj.join(" "); - } - - index.add(id, obj, _append, /* skip_update: */ true); - } - else { - - 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 { - key = tree[++pos]; - add_index(obj, tree, marker, pos, index, id, key, _append); - } - } - } - else { - if(index.db){ - index.remove(id); - } - } -} - -// COMPILER BLOCK --> - -/* - - from -> result[ - res[score][id], - res[score][id], - ] - - to -> [id] - -*/ - -/** - * @param arrays - * @param {number} resolution - * @param limit - * @param offset - * @param suggest - * @param {number=} boost - * @param {boolean=} resolve - * @returns {Array} - */ - -function intersect$1(arrays, resolution, limit, offset, suggest, boost, resolve) { - - const length = arrays.length; - - let result = []; - let check; - let 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++){ - - for(let x = 0; x < length; x++){ - - res_arr = arrays[x]; - - if(y < res_arr.length && (ids = res_arr[y])){ - - for(let z = 0; z < ids.length; z++){ - - 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 ? 0 : boost || 0); - tmp = tmp[score] || (tmp[score] = []); - } - - tmp.push(id); - } - } - } - } - - // result.sort(function(a, b){ - // return check[a] - check[b]; - // }); - - const result_len = result.length; - - if(result_len){ - - if(!suggest){ - - if(result_len < length){ - return []; - } - - result = result[result_len - 1]; - - if(limit || offset){ - if(resolve){ - if((result.length > limit) || offset){ - result = result.slice(offset, limit + offset); - } - } - else { - const final = []; - for(let i = 0, arr; i < result.length; i++){ - arr = result[i]; - if(arr.length > offset){ - offset -= arr.length; - continue; - } - if((arr.length > limit) || offset){ - arr = arr.slice(offset, limit + offset); - limit -= arr.length; - if(offset) offset -= arr.length; - } - final.push(arr); - if(!limit){ - break; - } - } - result = final.length > 1 - ? concat(final) - : final[0]; - } - - return result; - } - } - else { - - result = result.length > 1 - ? union$1(result, offset, limit, resolve, 0) - : ((result = result[0]).length > limit) || offset - ? result.slice(offset, limit + offset) - : result; - } - } - - return result; -} - -function union$1(arrays, offset, limit, resolve, boost){ - - const result = []; - const check = create_object(); - let ids, id, arr_len = arrays.length, ids_len, count = 0; - - if(!resolve){ - - let maxres = get_max_len(arrays); - - for(let k = 0; k < maxres; k++){ - - for(let i = arr_len - 1; i >= 0; i--){ - - ids = arrays[i][k]; - ids_len = ids && ids.length; - - if(ids_len) for(let j = 0; j < ids_len; j++){ - - id = ids[j]; - - if(!check[id]){ - check[id] = 1; - if(offset){ - offset--; - } - else { - let score = k + (i < arr_len - 1 ? boost || 0 : 0); - const arr = result[score] || (result[score] = []); - arr.push(id); - if(++count === limit){ - return result; - } - } - } - } - } - } - } - else { - - for(let i = arr_len - 1; i >= 0; i--){ - - ids = arrays[i]; - ids_len = ids.length; - - for(let j = 0; j < ids_len; j++){ - - id = ids[j]; - - if(!check[id]){ - check[id] = 1; - if(offset){ - offset--; - } - else { - result.push(id); - if(result.length === limit){ - return result; - } - } - } - } - } - } - - return result; -} - -/** - * @param {Array} mandatory - * @param {Array>} arrays - * @returns {Array} - */ - -function intersect_union(mandatory, arrays) { - - const check = create_object(); - const result = []; - - for(let x = 0, ids; x < arrays.length; x++){ - ids = arrays[x]; - for(let i = 0; i < ids.length; i++){ - check[ids[i]] = 1; - } - } - - for(let i = 0, id; i < mandatory.length; i++){ - id = mandatory[i]; - if(check[id] === 1){ - result.push(id); - check[id] = 2; - } - } - - 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. - * Also on large indexes it does not scale well performance-wise. - * This strategy also lacks of suggestion capabilities (matching & sorting). - * - * @param arrays - * @param limit - * @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; -// } - -// COMPILER BLOCK --> - -/** - * @param {!string|DocumentSearchOptions} query - * @param {number|DocumentSearchOptions=} limit - * @param {DocumentSearchOptions=} options - * @param {Array=} _promises For internal use only. - * @returns {DocumentSearchResults|EnrichedDocumentSearchResults|MergedDocumentSearchResults|Promise} - */ - -Document.prototype.search = function(query, limit, options, _promises){ - - if(!options){ - if(!limit && is_object(query)){ - options = /** @type {DocumentSearchOptions} */ (query); - query = ""; - } - else if(is_object(limit)){ - options = /** @type {DocumentSearchOptions} */ (limit); - limit = 0; - } - } - - let result = []; - let result_field = []; - let pluck, enrich, merge, suggest; - let field, tag, offset, count = 0, highlight; - - if(options){ - - if(is_array(options)){ - options = /** @type DocumentSearchOptions */ ({ - index: options - }); - } - - query = options.query || query; - pluck = options.pluck; - merge = options.merge; - field = pluck || options.field || options.index; - tag = this.tag && options.tag; - enrich = this.store && options.enrich; - suggest = options.suggest; - highlight = options.highlight; - //resolve = !SUPPORT_RESOLVER || (options.resolve !== false); - limit = options.limit || limit; - offset = options.offset || 0; - limit || (limit = 100); - - if(tag && (!this.db || !_promises)){ - - if(tag.constructor !== Array){ - tag = [tag]; - } - - let pairs = []; - - for(let i = 0, field; i < tag.length; i++){ - field = tag[i]; - 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){ - for(let k = 0; k < value.length; k++){ - pairs.push(field.field, value[k]); - } - } - 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); - } - } - } - } - - 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 = []; - if(pairs.length) for(let j = 0; j < pairs.length; j+=2){ - let ids; - if(this.db){ - const index = this.index.get(pairs[j]); - if(!index){ - { - console.warn("Tag '" + pairs[j] + ":" + pairs[j + 1] + "' will be skipped because there is no field '" + pairs[j] + "'."); - } - continue; - } - promises.push(ids = index.db.tag(pairs[j + 1], limit, offset, enrich)); - } - else { - ids = get_tag.call(this, pairs[j], pairs[j + 1], limit, offset, enrich); - } - result.push({ - "field": pairs[j], - "tag": pairs[j + 1], - "result": ids - }); - } - - if(promises.length){ - return Promise.all(promises).then(function(promises){ - for(let j = 0; j < promises.length; j++){ - result[j].result = promises[j]; - } - return result; - }); - } - - return result; - } - } - - // extend to multi field search by default - if(is_string(field)){ - field = [field]; - } - } - - field || (field = this.field); - let promises = !_promises && (this.worker || this.db /*|| this.async*/) && []; - let db_tag_search; - - // 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; - } - } - - let field_options; - - if(!is_string(key)){ - field_options = key; - key = field_options.field; - query = field_options.query || query; - limit = field_options.limit || limit; - offset = field_options.offset || offset; - suggest = (field_options.suggest || suggest); - enrich = this.store && (field_options.enrich || enrich); - } - - if(_promises){ - res = _promises[i]; - } - else { - let opt = field_options || options; - let index = this.index.get(key); - - if(tag){ - if(this.db){ - opt.tag = tag; - db_tag_search = index.db.support_tag_search; - opt.field = field; - } - if(!db_tag_search){ - opt.enrich = false; - } - } - if(promises){ - promises[i] = index.search/*Async*/(query, limit, opt); - // restore enrich state - 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 && res.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]; - let len = ids && ids.length; - - if(len){ - count++; - arr.push(ids); - } - else if(!suggest){ - // no tags found - return result; - } - } - } - } - else { - - // tag[] are pairs at this line - for(let y = 0, ids, len; y < tag.length; y+=2){ - ids = this.tag.get(tag[y]); - - if(!ids){ - { - console.warn("Tag '" + tag[y] + ":" + tag[y + 1] + "' will be skipped because there is no field '" + tag[y] + "'."); - } - if(suggest){ - continue; - } - else { - return result; - } - } - - ids = ids && ids.get(tag[y + 1]); - len = ids && ids.length; - - if(len){ - count++; - arr.push(ids); - } - else if(!suggest){ - // no tags found - return result; - } - } - } - - if(count){ - res = intersect_union(res, arr); // intersect(arr, limit, offset) - len = res.length; - if(!len && !suggest){ - // nothing matched - return result; - } - // move counter back by 1 - count--; - } - } - - if(len){ - result_field[count] = key; - result.push(res); - count++; - } - else if(field.length === 1){ - // fast path: nothing matched - return result; - } - } - - 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] + "'."); - } - if(suggest){ - continue; - } - else { - return result; - } - } - promises.push(index.db.tag(tag[y + 1], limit, offset, /* enrich */ false)); - } - } - } - - 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; - }); - } - - if(!count){ - return result; - } - if(pluck && (!enrich || !this.store)){ - return result[0]; - } - - promises = []; - - for(let i = 0, res; i < result_field.length; i++){ - - res = result[i]; - - if(enrich && res.length && !res[0].doc){ - if(!this.db){ - if(res.length){ - res = apply_enrich.call(this, res); - } - } - else { - // the documents are stored on the first field - promises.push(res = this.index.get(this.field[0]).db.enrich(res)); - } - } - - if(pluck){ - return res; - } - - result[i] = { - "field": result_field[i], - "result": res - }; - } - - if(enrich && SUPPORT_PERSISTENT && this.db && promises.length){ - const self = this; - return Promise.all(promises).then(function(promises){ - for(let j = 0; j < promises.length; j++){ - result[j]["result"] = promises[j]; - } - return merge - ? merge_fields(result, limit) - : highlight - ? highlight_fields(result, query, self.index, self.field, self.tree, highlight) - : result; - }); - } - - return merge - ? merge_fields(result, limit) - : highlight - ? highlight_fields(result, query, this.index, this.field, this.tree, highlight) - : result; -}; - -/* - - karmen or clown or not found -[Carmen]cita - Le [clown] et ses chiens - - */ - -function highlight_fields(result, query, index, field, tree, template, limit, offset){ - - // if(typeof template === "string"){ - // template = new RegExp(template, "g"); - // } - - let encoder; - let query_enc; - let tokenize; - - for(let i = 0, res, res_field, enc, idx, path; i < result.length; i++){ - - res = result[i].result; - res_field = result[i].field; - idx = index.get(res_field); - enc = idx.encoder; - tokenize = idx.tokenize; - path = tree[field.indexOf(res_field)]; - - if(enc !== encoder){ - encoder = enc; - query_enc = encoder.encode(query); - } - - for(let j = 0; j < res.length; j++){ - let str = ""; - let content = parse_simple(res[j].doc, path); - let doc_enc = encoder.encode(content); - let doc_org = content.split(encoder.split); - - for(let k = 0, doc_enc_cur, doc_org_cur; k < doc_enc.length; k++){ - doc_enc_cur = doc_enc[k]; - doc_org_cur = doc_org[k]; - let found; - for(let l = 0, query_enc_cur; l < query_enc.length; l++){ - query_enc_cur = query_enc[l]; - // todo tokenize could be custom also when "strict" was used - if(tokenize === "strict"){ - if(doc_enc_cur === query_enc_cur){ - str += (str ? " " : "") + template.replace("$1", doc_org_cur); - found = true; - break; - } - } - else { - const position = doc_enc_cur.indexOf(query_enc_cur); - if(position > -1){ - str += (str ? " " : "") + - // prefix - doc_org_cur.substring(0, position) + - // match - template.replace("$1", doc_org_cur.substring(position, query_enc_cur.length)) + - // suffix - doc_org_cur.substring(position + query_enc_cur.length); - found = true; - break; - } - } - - //str += doc_enc[k].replace(new RegExp("(" + doc_enc[k] + ")", "g"), template.replace("$1", content)) - } - - if(!found){ - str += (str ? " " : "") + doc_org[k]; - } - } - - res[j].highlight = str; - } - } - - return result; -} - -// 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 - -function merge_fields(fields, limit, offset){ - const final = []; - const set = create_object(); - for(let i = 0, field, res; i < fields.length; i++){ - field = fields[i]; - res = field.result; - for(let j = 0, id, entry, tmp; j < res.length; j++){ - entry = res[j]; - id = entry.id; - tmp = set[id]; - if(!tmp){ - // offset was already applied on field indexes - // if(offset){ - // offset--; - // continue; - // } - // apply limit from last round, because just fields could - // be pushed without adding new results - if(final.length === limit){ - return final; - } - entry.field = set[id] = [field.field]; - final.push(entry); - } - else { - tmp.push(field.field); - } - } - } - return final; -} - -/** - * @this {Document} - */ - -function get_tag(tag, key, limit, offset, enrich){ - let res = this.tag.get(tag); - if(!res){ - console.warn("Tag '" + tag + "' was not found"); - return []; - } - res = res && res.get(key); - let len = res && (res.length - offset); - - if(len && (len > 0)){ - if((len > limit) || offset){ - res = res.slice(offset, offset + limit); - } - if(enrich){ - res = apply_enrich.call(this, res); - } - return res; - } -} - -/** - * @this {Document} - */ - -function apply_enrich(res){ - - const arr = new Array(res.length); - - for(let x = 0, id; x < res.length; x++){ - id = res[x]; - arr[x] = { - "id": id, - "doc": this.store.get(id) - }; - } - - return arr; -} - -/**! - * FlexSearch.js - * Author and Copyright: Thomas Wilkerling - * Licence: Apache-2.0 - * Hosted by Nextapps GmbH - * https://github.com/nextapps-de/flexsearch - */ - - -/** - * @constructor - * @param {!DocumentOptions} options - * @return {Document|Promise} - */ - -function Document(options){ - - if(!this || this.constructor !== Document) { - return new Document(options); - } - - const document = /** @type DocumentDescriptor */ ( - options.document || options.doc || options - ); - let tmp, keystore; - - this.tree = []; - this.field = []; - this.marker = []; - this.key = ((tmp = document.key || document.id) && parse_tree(tmp, this.marker)) || "id"; - - keystore = (options.keystore || 0); - keystore && (this.keystore = keystore); - this.fastupdate = !!options.fastupdate; - this.reg = this.fastupdate - ? (keystore && SUPPORT_KEYSTORE ? new KeystoreMap(keystore) : new Map()) - : (keystore && SUPPORT_KEYSTORE ? new KeystoreSet(keystore) : new Set()); - - { - // todo support custom filter function - this.storetree = (tmp = document.store || null) && tmp && tmp !== true && []; - this.store = tmp && ( - keystore && SUPPORT_KEYSTORE - ? new KeystoreMap(keystore) - : new Map() - ); - } - - { - this.cache = (tmp = options.cache || null) && new CacheClass(tmp); - // do not apply cache again for the indexes since .searchCache() - // is just a wrapper over .search() - options.cache = false; - } - - { - this.worker = options.worker; - } - - // if(SUPPORT_ASYNC){ - // // this switch is used by recall of promise callbacks - // this.async = false; - // } - - /** - * @type {Map} - * @export - */ - this.index = parse_descriptor.call(this, options, document); - - { - this.tag = null; - // TODO case-insensitive tags? - if((tmp = document.tag)){ - if(typeof tmp === "string"){ - tmp = [tmp]; - } - if(tmp.length){ - this.tag = new Map(); - this.tagtree = []; - this.tagfield = []; - for(let i = 0, params, field; i < tmp.length; i++){ - params = tmp[i]; - field = params.field || params; - if(!field){ - throw new Error("The tag field from the document descriptor is undefined."); - } - if(params.custom){ - this.tagtree[i] = params.custom; - } - else { - this.tagtree[i] = parse_tree(field, this.marker); - if(params.filter){ - if(typeof this.tagtree[i] === "string"){ - // 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 needs to be hold by indices - this.tagfield[i] = field; - this.tag.set(field, new Map()); - } - } - } - } - - // resolve worker promises and swap instances - if(this.worker){ - const promises = []; - for(const index of this.index.values()){ - index.then && promises.push(index); - } - if(promises.length){ - const self = this; - return Promise.all(promises).then(function(promises){ - let count = 0; - for(const item of self.index.entries()){ - const key = item[0]; - const index = item[1]; - index.then && self.index.set(key, promises[count++]); - } - return self; - }); - } - } - else { - options.db && this.mount(options.db); - } -} - -{ - - 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 - 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); - } - } - - const promises = []; - const config = { - db: db.db, - type: db.type, - fastupdate: db.fastupdate - }; - - // 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 = true; - if(i){ - // the register has to export just one time - // also it's needed by the index for ID contain check - index.bypass = true; - } - else { - // the datastore has to export one time - index.store = this.store; - } - } - - //this.async = true; - this.db = true; - return Promise.all(promises); - }; - - Document.prototype.commit = async function(replace, append){ - // parallel: - const promises = []; - for(const index of this.index.values()){ - promises.push(index.db.commit(index, 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(){ - const promises = []; - for(const idx of this.index.values()){ - promises.push(idx.destroy()); - } - return Promise.all(promises); - }; -} - -/** - * @this {Document} - */ - -function parse_descriptor(options, document){ - - const index = new Map(); - let field = document.index || document.field || document; - - if(is_string(field)){ - field = [field]; - } - - for(let i = 0, key, opt; i < field.length; i++){ - - key = field[i]; - - if(!is_string(key)){ - opt = key; - key = key.field; - } - - opt = /** @type IndexOptions */ ( - is_object(opt) - ? Object.assign({}, options, opt) - : options - ); - - if(this.worker){ - const worker = new WorkerIndex(opt); - 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 = false; - } - } - - if(!this.worker){ - index.set(key, new Index(/** @type IndexOptions */ (opt), this.reg)); - } - - if(opt.custom){ - this.tree[i] = opt.custom; - } - else { - this.tree[i] = parse_tree(key, this.marker); - if(opt.filter){ - if(typeof this.tree[i] === "string"){ - // it needs an object to put a property to it - this.tree[i] = new String(this.tree[i]); - } - this.tree[i]._filter = opt.filter; - } - } - - this.field[i] = key; - } - - if(this.storetree){ - - let stores = document.store; - if(is_string(stores)) stores = [stores]; - - for(let i = 0, store, field; i < stores.length; i++){ - store = /** @type Array */ (stores[i]); - field = store.field || store; - if(store.custom){ - this.storetree[i] = store.custom; - store.custom._field = field; - } - else { - this.storetree[i] = parse_tree(field, this.marker); - if(store.filter){ - if(typeof this.storetree[i] === "string"){ - // it needs an object to put a property to it - this.storetree[i] = new String(this.storetree[i]); - } - this.storetree[i]._filter = store.filter; - } - } - } - } - - return index; -} - -function parse_tree(key, marker){ - - const tree = key.split(":"); - let count = 0; - - 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){ - marker[count] = true; - } - } - if(key){ - tree[count++] = key; - } - } - - if(count < tree.length){ - tree.length = count; - } - - return count > 1 ? tree : tree[0]; -} - -Document.prototype.append = function(id, content){ - return this.add(id, content, true); -}; - -Document.prototype.update = function(id, content){ - return this.remove(id).add(id, content); -}; - -Document.prototype.remove = function(id){ - - if(is_object(id)){ - id = parse_simple(id, this.key); - } - - for(const index of this.index.values()){ - index.remove(id, /* skip deletion */ true); - } - - 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){ - const tag = item[0]; - const ids = item[1]; - const pos = ids.indexOf(id); - if(pos > -1){ - ids.length > 1 - ? ids.splice(pos, 1) - : field.delete(tag); - } - } - } - } - } - - if(this.store){ - this.store.delete(id); - } - - this.reg.delete(id); - } - - // the cache could be used outside the InMemory store - if(this.cache){ - this.cache.remove(id); - } - - return this; -}; - -Document.prototype.clear = function(){ - - //const promises = []; - - for(const index of this.index.values()){ - // db index will add clear task - index.clear(); - // const promise = index.clear(); - // if(promise instanceof Promise){ - // promises.push(promise); - // } - } - - if(this.tag){ - for(const tags of this.tag.values()){ - tags.clear(); - } - } - - if(this.store){ - this.store.clear(); - } - - return this; /*promises.length - ? Promise.all(promises) - :*/ -}; - -Document.prototype.contain = function(id){ - - if(this.db){ - return this.index.get(this.field[0]).db.has(id); - } - - return this.reg.has(id); -}; - -Document.prototype.cleanup = function(){ - - for(const index of this.index.values()){ - index.cleanup(); - } - - return this; -}; - -{ - - Document.prototype.get = function(id){ - - if(this.db){ - return this.index.get(this.field[0]).db.enrich(id).then(function(result){ - return result[0] && result[0].doc; - }); - } - - return this.store.get(id); - }; - - Document.prototype.set = function(id, store){ - - this.store.set(id, store); - return this; - }; -} - -{ - // todo mo - Document.prototype.searchCache = searchCache; -} - -{ - - Document.prototype.export = exportDocument; - Document.prototype.import = importDocument; -} - -{ - - apply_async(Document.prototype); -} - -/** - * @param {string|SearchOptions|DocumentSearchOptions} query - * @param {number|SearchOptions|DocumentSearchOptions=} limit - * @param {SearchOptions|DocumentSearchOptions=} options - * @this {Index|Document} - * @returns {Array|Promise} - */ - -function searchCache(query, limit, options){ - - query = (typeof query === "object" - ? "" + query.query - : "" + query - ).toLowerCase(); - - //let encoded = this.encoder.encode(query).join(" "); - let cache = this.cache.get(query); - if(!cache){ - cache = this.search(query, limit, options); - if(cache.then){ - const self = this; - cache.then(function(cache){ - self.cache.set(query, cache); - return cache; - }); - } - this.cache.set(query, cache); - } - return cache; -} - -/** - * @param {boolean|number=} limit - * @constructor - */ - -function CacheClass(limit){ - /** @private */ - this.limit = (!limit || limit === true) ? 1000 : limit; - /** @private */ - this.cache = new Map(); - /** @private */ - this.last = ""; -} - -CacheClass.prototype.set = function(key, value){ - //if(!this.cache.has(key)){ - this.cache.set(this.last = key, value); - if(this.cache.size > this.limit){ - this.cache.delete(this.cache.keys().next().value); - } - //} -}; - -CacheClass.prototype.get = function(key){ - const cache = this.cache.get(key); - if(cache && this.last !== key){ - this.cache.delete(key); - this.cache.set(this.last = key, cache); - } - return cache; -}; - -CacheClass.prototype.remove = function(id){ - for(const item of this.cache){ - const key = item[0]; - const value = item[1]; - if(value.includes(id)){ - this.cache.delete(key); - } - } -}; - -CacheClass.prototype.clear = function(){ - this.cache.clear(); - this.last = ""; -}; - -/** @type EncoderOptions */ -const options$9 = { - normalize: false, - dedupe: false -}; - -/** @type EncoderOptions */ -const options$8 = { - normalize: function(str){ - return str.toLowerCase(); - }, - dedupe: false -}; - -/** @type EncoderOptions */ -const options$7 = { - normalize: true, - dedupe: true -}; - -const soundex$1 = 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"] -]); - -/** @type EncoderOptions */ -const options$6 = { - normalize: true, - dedupe: true, - mapper: soundex$1 -}; - -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"], - ["pf", "f"] -]); - -const replacer = [ - /([^aeo])h(.)/g, "$1$2", - /([aeo])h([^aeo]|$)/g, "$1$2", - /([^0-9])\1+/g, "$1" -]; - -/** @type EncoderOptions */ -const options$5 = { - normalize: true, - dedupe: true, - mapper: soundex$1, - matcher: matcher, - replacer: replacer -}; - -const compact = [ - /(?!^)[aeo]/g, "" // before soundex: aeoy, old: aioy -]; - -/** @type EncoderOptions */ -const options$4 = { - normalize: true, - dedupe: true, - mapper: soundex$1, - replacer: replacer.concat(compact), - matcher: matcher -}; - -/** @type {EncoderOptions} */ -const options$3 = { - normalize: true, - dedupe: false, - include: { - letter: true - }, - finalize: function(arr){ - for(let i = 0; i < arr.length; i++){ - arr[i] = soundex(arr[i]); - } - } -}; - -const codes = { - "a": "", "e": "", "i": "", "o": "", "u": "", "y": "", - "b": 1, "f": 1, "p": 1, "v": 1, - "c": 2, "g": 2, "j": 2, "k": 2, "q": 2, "s": 2, "x": 2, "z": 2, "ß": 2, - "d": 3, "t": 3, - "l": 4, - "m": 5, "n": 5, - "r": 6 -}; - -function soundex(stringToEncode){ - - let encodedString = stringToEncode.charAt(0); - let last = codes[encodedString]; - for(let i = 1, char; i < stringToEncode.length; i++){ - char = stringToEncode.charAt(i); - // Remove all occurrences of "h" and "w" - if(char !== "h" && char !== "w"){ - // 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; - if(encodedString.length === 4){ - break; - } - } - } - } - } - // while(encodedString.length < 4){ - // encodedString += "0"; - // } - return encodedString; -} - -const regex$2 = /[\x00-\x7F]+/g; - -/** @type EncoderOptions */ -const options$2 = { - rtl: true, - normalize: false, - dedupe: true, - prepare: function(str){ - return ("" + str).replace(regex$2, " ") - } -}; - -const regex$1 = /[\x00-\x7F]+/g; - -/** @type EncoderOptions */ -const options$1 = { - normalize: false, - dedupe: true, - split: "", - prepare: function(str){ - return ("" + str).replace(regex$1, "") - } -}; - -const regex = /[\x00-\x7F]+/g; - -/** @type EncoderOptions */ -const options = { - normalize: false, - dedupe: true, - prepare: function(str){ - return ("" + str).replace(regex, " ") - } -}; - -// export const global_lang = create_object(); -//export const global_charset = create_object(); - -var Charset = { - LatinExact: options$9, - LatinDefault: options$8, - LatinSimple: options$7, - LatinBalance: options$6, - LatinAdvanced: options$5, - LatinExtra: options$4, - LatinSoundex: options$3, - ArabicDefault: options$2, - CjkDefault: options$1, - CyrillicDefault: options -}; - -// global_charset["latin:exact"] = charset_exact; -// global_charset["latin:default"] = charset_default; -// global_charset["latin:simple"] = charset_simple; -// global_charset["latin:balance"] = charset_balance; -// global_charset["latin:advanced"] = charset_advanced; -// global_charset["latin:extra"] = charset_extra; -// global_charset["latin:soundex"] = charset_soundex; - - -/** - * @param {!string} name - * @param {Object} charset - */ - -// export function registerCharset(name, charset){ -// global_charset[name] = charset; -// } - -/** - * @param {!string} name - * @param {Object} lang - */ - -// export function registerLanguage(name, lang){ -// global_lang[name] = lang; -// } - -// COMPILER BLOCK --> - -/** - * @type {Object} - * @const - */ - -const presets = { - - "memory": { - resolution: 1 - }, - - "performance": { - resolution: 6, - fastupdate: true, - context: { - depth: 1, - resolution: 3 - } - }, - - "match": { - tokenize: "forward" - }, - - "score": { - resolution: 9, - context: { - depth: 2, - resolution: 9 - } - } -}; - -/** - * - * @param {IndexOptions|string} options - * @return {IndexOptions} - */ - -function apply_preset(options){ - - const preset = /** @type string */ ( - is_string(options) - ? options - : options.preset - ); - - if(preset){ - if(!presets[preset]){ - console.warn("Preset not found: " + preset); - } - options = /** @type IndexOptions */ ( - Object.assign({}, presets[preset], /** @type {Object} */ (options)) - ); - } - - return /** @type IndexOptions */ (options); -} - -const data = create_object(); - -/** - * @param {!string} name - */ - -function tick(name){ - - /** @type {!Object} */ - const profiler = data["profiler"] || (data["profiler"] = {}); - - profiler[name] || (profiler[name] = 0); - profiler[name]++; -} - -// COMPILER BLOCK --> -// <-- COMPILER BLOCK - -let table;// = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz+/"; -let timer; -const cache = new Map(); - -function toRadix(number, radix = 255) { - - if(!table){ - table = new 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); - } - - let rixit; - let residual = number; - let result = ""; - - while(true){ - rixit = residual % radix; - result = table.charAt(rixit) + result; - residual = residual / radix | 0; - if(!residual) - break; - } - - return result; -} - -function default_compress(str){ - - { - if(timer){ - if(cache.has(str)){ - return cache.get(str); - } - } - else { - timer = setTimeout(clear); - } - } - - /* 2 ** ((level + 1.5) * 1.6 | 0) */ - - const result = toRadix( - typeof str == "number" - ? str - : lcg(str) - ); - - { - cache.size > 2e5 && cache.clear(); - cache.set(str, result); - } - - return result; -} - -function lcg(str) { - let range = 2 ** 32 - 1; - if(typeof str == "number"){ - return str & range; - } - let crc = 0, bit = 32 + 1; - for(let i = 0; i < str.length; i++) { - crc = (crc * bit ^ str.charCodeAt(i)) & range; - } - // shift up from Int32 to UInt32 range 0xFFFFFFFF - return crc + 2 ** 31; -} - -function clear(){ - timer = null; - cache.clear(); -} - -// COMPILER BLOCK --> - -// TODO: -// string + number as text -// boolean, null, undefined as ? - - -/** - * @param {!number|string} id - * @param {!string} content - * @param {boolean=} _append - * @param {boolean=} _skip_update - */ - -Index.prototype.add = function(id, content, _append, _skip_update){ - - if(content && (id || (id === 0))){ - - // todo check skip_update - //_skip_update = false; - - if(!_skip_update && !_append){ - if(this.reg.has(id)){ - return this.update(id, content); - } - } - - // do not force a string as input - // https://github.com/nextapps-de/flexsearch/issues/432 - content = this.encoder.encode(content); - const word_length = content.length; - - if(word_length){ - - // check context dupes to skip all contextual redundancy along a document - - const dupes_ctx = create_object(); - const dupes = create_object(); - const depth = this.depth; - const resolution = this.resolution; - - for(let i = 0; i < word_length; i++){ - - let term = content[this.rtl ? word_length - 1 - i : i]; - let term_length = term.length; - - // skip dupes will break the context chain - - if(term_length /*&& (term_length >= this.minlength)*/ && (depth || !dupes[term])){ - - let score = this.score - ? this.score(content, term, i, null, 0) - : get_score(resolution, word_length, i); - let token = ""; - - switch(this.tokenize){ - - case "full": - if(term_length > 2){ - for(let x = 0; x < term_length; x++){ - for(let y = term_length; y > x; y--){ - - //if((y - x) >= this.minlength){ - token = term.substring(x, y); - const partial_score = this.score - ? this.score(content, term, i, token, x) - : get_score(resolution, word_length, i, term_length, x); - this.push_index(dupes, token, partial_score, id, _append); - //} - } - } - break; - } - // fallthrough to next case when term length < 3 - case "reverse": - // skip last round (this token exist already in "forward") - if(term_length > 1){ - for(let x = term_length - 1; x > 0; x--){ - token = term[x] + token; - //if(token.length >= this.minlength){ - const partial_score = this.score - ? this.score(content, term, i, token, x) - : get_score(resolution, word_length, i, term_length, x); - this.push_index(dupes, token, partial_score, id, _append); - //} - } - token = ""; - } - - // fallthrough to next case to apply forward also - case "forward": - if(term_length > 1){ - for(let x = 0; x < term_length; x++){ - token += term[x]; - //if(token.length >= this.minlength){ - this.push_index(dupes, token, score, id, _append); - //} - } - break; - } - - // fallthrough to next case when token has a length of 1 - default: - // case "strict": - - // todo move boost to search - // if(this.boost){ - // score = Math.min((score / this.boost(content, term, i)) | 0, resolution - 1); - // } - - this.push_index(dupes, term, score, id, _append); - - // context is just supported by tokenizer "strict" - if(depth){ - - if((word_length > 1) && (i < (word_length - 1))){ - - // check inner dupes to skip repeating words in the current context - const dupes_inner = create_object(); - const resolution = this.resolution_ctx; - const keyword = term; - const size = Math.min(depth + 1, word_length - i); - - dupes_inner[keyword] = 1; - - for(let x = 1; x < size; x++){ - - term = content[this.rtl ? word_length - 1 - i - x : i + x]; - - if(term /*&& (term.length >= this.minlength)*/ && !dupes_inner[term]){ - - dupes_inner[term] = 1; - - const context_score = this.score - ? this.score(content, keyword, i, term, x) - : get_score(resolution + ((word_length / 2) > resolution ? 0 : 1), word_length, i, size - 1, x - 1); - const swap = this.bidirectional && (term > keyword); - this.push_index(dupes_ctx, swap ? keyword : term, context_score, id, _append, swap ? term : keyword); - } - } - } - } - } - } - } - - this.fastupdate || this.reg.add(id); - } - else { - content = ""; - } - } - - 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); - } - - return this; -}; - -/** - * @private - * @param dupes - * @param term - * @param score - * @param id - * @param {boolean=} append - * @param {string=} keyword - */ - -Index.prototype.push_index = function(dupes, term, score, id, append, keyword){ - - let arr = keyword ? this.ctx : this.map; - let tmp; - - if(!dupes[term] || (keyword && !(tmp = dupes[term])[keyword])){ - - if(keyword){ - - dupes = tmp || (dupes[term] = create_object()); - dupes[keyword] = 1; - - if(this.compress){ - keyword = default_compress(keyword); - } - - tmp = arr.get(keyword); - tmp ? arr = tmp - : arr.set(keyword, arr = new Map()); - } - else { - - dupes[term] = 1; - } - - if(this.compress){ - term = default_compress(term); - } - - 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(arr.length === 2**31-1 /*|| !(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; - } - } - } - 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]); - } - } - } -}; - -/** - * @param {number} resolution - * @param {number} length - * @param {number} i - * @param {number=} term_length - * @param {number=} x - * @returns {number} - */ - -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 && (resolution > 1) ? ( - - (length + (term_length || 0)) <= resolution ? - - i + (x || 0) - : - ((resolution - 1) / (length + (term_length || 0)) * (i + (x || 0)) + 1) | 0 - ): - 0; -} - -/* - from -> res[score][id] - to -> [id] -*/ - -/** - * Aggregate the union of a single raw result - * @param {!Array} result - * @param {!number} limit - * @param {number=} offset - * @param {boolean=} enrich - * @return Array - */ - -function resolve_default(result, limit, offset, enrich){ - - // fast path: when there is just one slot in the result - if(result.length === 1){ - result = result[0]; - result = offset || (result.length > limit) - ? (limit - ? result.slice(offset, offset + limit) - : result.slice(offset) - ) - : result; - return enrich - ? enrich_result(result) - : result; - } - - // this is an optimized workaround instead of - // just doing result = concat(result) - - let final = []; - - 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; - offset = 0; - } - } - - if(!final.length){ - // fast path: when limit was reached in first slot - if(len >= limit){ - if(len > limit){ - arr = arr.slice(0, limit); - } - return enrich - ? enrich_result(arr) - : arr; - } - final = [arr]; - } - else { - if(len > limit){ - arr = arr.slice(0, limit); - len = arr.length; - } - final.push(arr); - } - - // reduce limit - limit -= len; - - // todo remove - // if(limit < 0){ - // throw new Error("Impl.Error"); - // } - - // break if limit was reached - if(!limit){ - break; - } - } - - // todo remove - if(!final.length){ - //throw new Error("No results found"); - return final; - } - - final = final.length > 1 - ? concat(final) - : final[0]; - - return enrich - ? enrich_result(final) - : final; -} - -function enrich_result(ids){ - for(let i = 0; i < ids.length; i++){ - ids[i] = { - "score": i, - "id": ids[i] - }; - } - return ids; -} - -Resolver.prototype.or = function(){ - - const self = this; - let args = arguments; - let first_argument = args[0]; - - if(first_argument.then){ - return first_argument.then(function(){ - return self.or.apply(self, args); - }); - } - - if(first_argument[0]){ - // fix false passed parameter style - if(first_argument[0].index){ - return this.or.apply(this, first_argument); - } - } - - let final = []; - let promises = []; - let limit = 0, offset = 0, enrich, resolve; - - for(let i = 0, query; i < args.length; i++){ - - query = /** @type {string|ResolverOptions} */ ( - args[i] - ); - - if(query){ - - limit = query.limit || 0; - offset = query.offset || 0; - enrich = query.enrich; - resolve = query.resolve; - - let result; - if(query.constructor === Resolver){ - result = query.result; - } - else if(query.constructor === Array){ - result = query; - } - else if(query.index){ - query.resolve = false; - result = query.index.search(query).result; - } - else if(query.and){ - result = this.and(query.and); - } - else if(query.xor){ - result = this.xor(query.xor); - } - else if(query.not){ - result = this.not(query.not); - } - else { - continue; - } - - final[i] = result; - - if(result.then){ - promises.push(result); //{ query, result }; - } - } - } - - if(promises.length){ - return Promise.all(promises).then(function(){ - //self.result.length && (final = [self.result].concat(final)); - // the suggest-union was re-used from but there it needs reversed order - self.result.length && (final = final.concat([self.result])); - self.result = union(final, limit, offset, enrich, resolve, self.boostval); - return resolve ? self.result : self; - }); - } - - if(final.length){ - //this.result.length && (final = [this.result].concat(final)); - // the suggest-union was re-used but there it needs reversed order - this.result.length && (final = final.concat([this.result])); - this.result = union(final, limit, offset, enrich, resolve, this.boostval); - } - return resolve ? this.result : this; -}; - -/** - * Aggregate the union of N raw results - * @param result - * @param limit - * @param offset - * @param enrich - * @param resolve - * @param boost - * @return {Array} - */ - -function union(result, limit, offset, enrich, resolve, boost){ - - if(!result.length){ - // todo remove - //console.log("Empty Result") - return result; - } - - if(typeof limit === "object"){ - offset = limit.offset || 0; - enrich = limit.enrich || false; - limit = limit.limit || 0; - } - - if(result.length < 2){ - // todo remove - //console.log("Single Result") - if(resolve){ - return resolve_default(result[0], limit, offset, enrich); - } - else { - return result[0]; - } - } - - // the suggest-union - return union$1(result/*.reverse()*/, offset, limit, resolve, boost); - - // let final = []; - // let count = 0; - // let dupe = create_object(); - // let maxres = get_max_len(result); - // - // for(let j = 0, ids; j < maxres; j++){ - // for(let i = 0, res; i < result.length; i++){ - // res = result[i]; - // if(!res) continue; - // ids = res[j]; - // if(!ids) continue; - // - // for(let k = 0, id; k < ids.length; k++){ - // id = ids[k]; - // if(!dupe[id]){ - // dupe[id] = 1; - // if(offset){ - // offset--; - // continue; - // } - // if(resolve){ - // final.push(id); - // } - // else{ - // // shift resolution by boost (inverse) - // const index = j + (boost || 0); - // final[index] || (final[index] = []); - // final[index].push(id); - // } - // if(limit && ++count === limit){ - // //this.boost = 0; - // return final; - // } - // } - // } - // } - // } - // - // //this.boost = 0; - // return final; -} - -Resolver.prototype.and = function(){ - if(this.result.length){ - - const self = this; - let args = arguments; - let first_argument = args[0]; - - if(first_argument.then){ - return first_argument.then(function(){ - return self.and.apply(self, args); - }); - } - - if(first_argument[0]){ - // fix false passed parameter style - if(first_argument[0].index){ - return this.and.apply(this, first_argument); - } - } - - let final = []; - let promises = []; - let limit = 0, offset = 0, enrich, resolve, suggest; - - for(let i = 0, query; i < args.length; i++){ - - query = /** @type {string|ResolverOptions} */ ( - args[i] - ); - - if(query){ - - limit = query.limit || 0; - offset = query.offset || 0; - enrich = query.enrich; - resolve = query.resolve; - suggest = query.suggest; - - let result; - if(query.constructor === Resolver){ - result = query.result; - } - else if(query.constructor === Array){ - result = query; - } - else if(query.index){ - query.resolve = false; - result = query.index.search(query).result; - } - else if(query.or){ - result = this.or(query.or); - } - else if(query.xor){ - result = this.xor(query.xor); - } - else if(query.not){ - result = this.not(query.not); - } - else { - continue; - } - - final[i] = result; - - if(result.then){ - promises.push(result); //{ query, result }; - } - } - } - - if(!final.length){ - this.result = final; - return resolve ? this.result : this; - } - - if(promises.length){ - return Promise.all(promises).then(function(){ - final = [self.result].concat(final); - self.result = intersect(final, limit, offset, enrich, resolve, self.boostval, suggest); - return resolve ? self.result : self; - }); - } - - final = [this.result].concat(final); - this.result = intersect(final, limit, offset, enrich, resolve, this.boostval, suggest); - return resolve ? this.result : this; - } - return this; -}; - -/** - * Aggregate the intersection of N raw results - * @param result - * @param limit - * @param offset - * @param enrich - * @param resolve - * @param boost - * @param suggest - * @return {Array} - */ - -function intersect(result, limit, offset, enrich, resolve, boost, suggest){ - - // if(!result.length){ - // // todo remove - // console.log("Empty Result") - // return result; - // } - - if(result.length < 2){ - return []; - } - - let final = []; - let maxres = get_max_len(result); - if(!maxres) return final; - - //console.log(result) - - return intersect$1(result, maxres, limit, offset, suggest, boost, resolve); - - // for(let j = 0, ids, res = result[0]; j < res.length; j++){ - // ids = res[j]; - // for(let k = 0; k < ids.length; k++){ - // contain[ids[k]] = 1; - // } - // } - - // for(let i = 0, res; i < result.length; i++){ - // res = result[i]; - // if(!res || !res.length) return []; - // let contain_new = create_object(); - // let match = 0; - // let last_round = i === result.length - 1; - // - // for(let j = 0, ids; j < maxres; j++){ - // ids = res[j]; - // if(!ids) continue; - // - // for(let k = 0, id, min; k < ids.length; k++){ - // id = ids[k]; - // // fill in first round - // if(!i){ - // // shift resolution +1 - // // shift resolution by boost (inverse) - // contain_new[id] = j + 1 + (i ? boost : 0); - // match = 1; - // } - // // result in last round - // else if(last_round){ - // if((min = contain[id])){ - // match = 1; - // //if(!contain_new[id]){ - // if(offset){ - // offset--; - // continue; - // } - // if(resolve){ - // final.push(id); - // } - // else{ - // // reduce resolution -1 - // min--; - // if(j < min) min = j; - // final[min] || (final[min] = []); - // final[min].push(id); - // } - // if(limit && ++count === limit){ - // //this.boost = 0; - // return final; - // } - // // shift resolution +1 - // //contain_new[id] = min + 1; - // //} - // } - // } - // // check for intersection - // else if((min = contain[id])){ - // // shift resolution +1 - // if(j + 1 < min) min = j + 1; - // contain_new[id] = min; - // match = 1; - // } - // } - // } - // - // if(!match){ - // //this.boost = 0; - // return []; - // } - // - // contain = contain_new; - // } - // - // //this.boost = 0; - // return final; -} - -Resolver.prototype.xor = function(){ - const self = this; - let args = arguments; - let first_argument = args[0]; - - if(first_argument.then){ - return first_argument.then(function(){ - return self.xor.apply(self, args); - }); - } - - if(first_argument[0]){ - // fix false passed parameter style - if(first_argument[0].index){ - return this.xor.apply(this, first_argument); - } - } - - let final = []; - let promises = []; - let limit = 0, offset = 0, enrich, resolve; - - for(let i = 0, query; i < args.length; i++){ - - query = /** @type {string|ResolverOptions} */ ( - args[i] - ); - - if(query){ - - limit = query.limit || 0; - offset = query.offset || 0; - enrich = query.enrich; - resolve = query.resolve; - - let result; - if(query.constructor === Resolver){ - result = query.result; - } - else if(query.constructor === Array){ - result = query; - } - else if(query.index){ - query.resolve = false; - result = query.index.search(query).result; - } - else if(query.or){ - result = this.or(query.or); - } - else if(query.and){ - result = this.and(query.and); - } - else if(query.not){ - result = this.not(query.not); - } - else { - continue; - } - - final[i] = result; - - if(result.then){ - promises.push(result); //{ query, result }; - } - } - } - - if(promises.length){ - return Promise.all(promises).then(function(){ - self.result.length && (final = [self.result].concat(final)); - self.result = exclusive(final, limit, offset, enrich, !resolve, self.boostval); - return resolve ? self.result : self; - }); - } - - if(final.length){ - this.result.length && (final = [this.result].concat(final)); - this.result = exclusive(final, limit, offset, enrich, !resolve, self.boostval); - } - return resolve ? this.result : this; -}; - -/** - * @param result - * @param limit - * @param offset - * @param enrich - * @param resolve - * @param boost - * @return {Array} - */ - -function exclusive(result, limit, offset, enrich, resolve, boost){ - - if(!result.length){ - // todo remove - //console.log("Empty Result") - return result; - } - - if(result.length < 2){ - // todo remove - //console.log("Single Result") - if(resolve){ - return resolve_default(result[0], limit, offset, enrich); - } - else { - return result[0]; - } - } - - const final = []; - const check = create_object(); - let maxres = 0; - - for(let i = 0, res; i < result.length; i++){ - res = result[i]; - if(!res) continue; - - for(let j = 0, ids; j < res.length; j++){ - ids = res[j]; - if(!ids) continue - - if(maxres < ids.length) maxres = ids.length; - - for(let k = 0, id; k < ids.length; k++){ - id = ids[k]; - check[id] - ? check[id]++ - : check[id] = 1; - } - } - } - - for(let j = 0, ids, count = 0; j < maxres; j++){ - - for(let i = 0, res; i < result.length; i++){ - res = result[i]; - if(!res) continue; - - ids = res[j]; - if(!ids) continue; - - for(let k = 0, id; k < ids.length; k++){ - id = ids[k]; - if(check[id] === 1){ - if(offset){ - offset--; - continue; - } - if(resolve){ - final.push(id); - if(final.length === limit){ - return final; - } - } - else { - // shift resolution by boost (inverse) - const index = j + (i ? boost : 0); - final[index] || (final[index] = []); - final[index].push(id); - if(++count === limit){ - return final; - } - } - } - } - } - } - - //this.boost = 0; - return final; -} - -Resolver.prototype.not = function(){ - const self = this; - let args = arguments; - let first_argument = args[0]; - - if(first_argument.then){ - return first_argument.then(function(){ - return self.not.apply(self, args); - }); - } - - if(first_argument[0]){ - // fix false passed parameter style - if(first_argument[0].index){ - return this.not.apply(this, first_argument); - } - } - - let final = []; - let promises = []; - let limit = 0, offset = 0, resolve; - - for(let i = 0, query; i < args.length; i++){ - - query = /** @type {string|ResolverOptions} */ ( - args[i] - ); - - if(query){ - - limit = query.limit || 0; - offset = query.offset || 0; - query.enrich; - resolve = query.resolve; - - let result; - if(query.constructor === Resolver){ - result = query.result; - } - else if(query.constructor === Array){ - result = query; - } - else if(query.index){ - query.resolve = false; - result = query.index.search(query).result; - } - else if(query.or){ - result = this.or(query.or); - } - else if(query.and){ - result = this.and(query.and); - } - else if(query.xor){ - result = this.xor(query.xor); - } - else { - continue; - } - - final[i] = result; - - if(result.then){ - promises.push(result); //{ query, result }; - } - } - } - - if(promises.length){ - return Promise.all(promises).then(function(){ - self.result = exclusion.call(self, final, limit, offset, resolve); - return resolve ? self.result : self; - }); - } - - if(final.length){ - this.result = exclusion.call(this, final, limit, offset, resolve); - } - - return resolve ? this.result : this; -}; - -/** - * @param result - * @param limit - * @param offset - * @param resolve - * @this {Resolver} - * @return {Array} - */ - -function exclusion(result, limit, offset, resolve){ - - if(!result.length){ - return this.result; - } - - const final = []; - const exclude = new Set(result.flat().flat()); - - for(let j = 0, ids, count = 0; j < this.result.length; j++){ - ids = this.result[j]; - if(!ids) continue; - - for(let k = 0, id; k < ids.length; k++){ - id = ids[k]; - if(!exclude.has(id)){ - if(offset){ - offset--; - continue; - } - if(resolve){ - final.push(id); - if(final.length === limit){ - return final; - } - } - else { - final[j] || (final[j] = []); - final[j].push(id); - if(++count === limit){ - return final; - } - } - } - } - } - - return final; -} - -/** - * @param {Array|ResolverOptions=} result - * @constructor - */ - -function Resolver(result){ - if(!this || this.constructor !== Resolver){ - return new Resolver(result); - } - if(result && result.index){ - result.resolve = false; - this.index = result.index; - this.boostval = result.boost || 0; - this.result = result.index.search(result).result; - return this; - } - if(result.constructor === Resolver){ - // todo test this branch - //console.log("Resolver Loopback") - return result; - } - this.index = null; - this.result = result || []; - this.boostval = 0; -} - -Resolver.prototype.limit = function(limit){ - if(this.result.length){ - const final = []; - let count = 0; - for(let j = 0, ids; j < this.result.length; j++){ - ids = this.result[j]; - if(ids.length + count < limit){ - final[j] = ids; - count += ids.length; - } - else { - final[j] = ids.slice(0, limit - count); - this.result = final; - break; - } - } - } - return this; -}; - -Resolver.prototype.offset = function(offset){ - if(this.result.length){ - const final = []; - let count = 0; - for(let j = 0, ids; j < this.result.length; j++){ - ids = this.result[j]; - if(ids.length + count < offset){ - count += ids.length; - } - else { - final[j] = ids.slice(offset - count); - count = offset; - } - } - this.result = final; - } - return this; -}; - -Resolver.prototype.boost = function(boost){ - this.boostval += boost; - return this; -}; - -/** - * @param {number|ResolverOptions=} limit - * @param {number=} offset - * @param {boolean=} enrich - */ - -Resolver.prototype.resolve = function(limit, offset, enrich){ - set_resolve(1); - const result = this.result; - this.index = null; - this.result = null; - - if(result.length){ - if(typeof limit === "object"){ - enrich = limit.enrich; - offset = limit.offset; - limit = limit.limit; - } - return resolve_default(result, limit || 100, offset, enrich); - } - - return result; -}; - -// COMPILER BLOCK --> - -let global_resolve = 1; -function set_resolve(resolve){ - global_resolve = resolve; -} - -/** - * @param {string|SearchOptions} query - * @param {number|SearchOptions=} limit - * @param {SearchOptions=} options - * @returns {SearchResults|EnrichedSearchResults|Resolver|Promise} - */ - -Index.prototype.search = function(query, limit, options){ - - if(!options){ - if(!limit && is_object(query)){ - options = /** @type {!SearchOptions} */ (query); - query = ""; - } - else if(is_object(limit)){ - options = /** @type {!SearchOptions} */ (limit); - limit = 0; - } - } - - let result = []; - let length; - let context, suggest, offset = 0, resolve, enrich, tag, boost, resolution; - - if(options){ - query = options.query || query; - limit = options.limit || limit; - offset = options.offset || 0; - context = options.context; - suggest = options.suggest; - resolve = (global_resolve && options.resolve !== false); - resolve || (global_resolve = 0); - enrich = resolve && options.enrich; - boost = options.boost; - resolution = options.resolution; - tag = this.db && options.tag; - } - else { - resolve = this.resolve || global_resolve; - } - - // todo: term deduplication during encoding when context is disabled - - // do not force a string as input - // https://github.com/nextapps-de/flexsearch/issues/432 - /** @type {Array} */ - let query_terms = this.encoder.encode(query); - length = query_terms.length; - limit || !resolve || (limit = 100); - - // fast path single term - if(length === 1){ - return single_term_query.call( - this, - query_terms[0], // term - "", // ctx - limit, - offset, - resolve, - enrich, - tag - ); - } - - // TODO: dedupe terms within encoder? - // TODO: deduplication will break the context chain - - context = this.depth && context !== false; - - // 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 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 && !(this.db) && !this.get_array(term/*, keyword*/)){ - - // fast path "not found" - return 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.length; - } - - // the term length could be changed after deduplication - - if(!length){ - return resolve - ? result - : new Resolver(result); - } - - let index = 0, keyword; - - // 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 - ); - } - - 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 && resolution !== 0){ - resolution = 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(result !== false) return result; - } - - const self = this; - return (async function(){ - - for(let arr, term; index < length; index++){ - - term = query_terms[index]; - - if(keyword){ - - arr = await self.get_array(term, keyword, 0, 0, false, false); - arr = add_result( - arr, - result, - suggest, - self.resolution_ctx, - // 0, // /** @type {!number} */ (limit), - // 0, // offset, - // length === 2 - // /*, term, 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 !== false) || !result.length){ - keyword = term; - } - } - else { - - arr = await self.get_array(term, "", 0, 0, false, false); - arr = add_result( - arr, - result, - suggest, - resolution, - // 0, // /** @type {!number} */ (limit), - // 0, // offset, - // length === 1 - // /*, term*/ - ); - } - - // limit reached - if(arr){ - return arr; - } - - // apply suggestions on last loop - if(suggest && (index === length - 1)){ - let length = result.length; - if(!length){ - // fallback to non-contextual search when no result was found - if(keyword){ - keyword = ""; - index = -1; - continue; - } - return result; - } - else if(length === 1){ - return resolve - ? resolve_default(result[0], /** @type {number} */ (limit), offset) - : new Resolver(result[0]); - } - } - } - - return resolve - ? intersect$1(result, resolution, /** @type {number} */ (limit), offset, suggest, boost, resolve) - : new Resolver(result[0]) - }()); - } - - for(let arr, term; index < length; index++){ - - term = query_terms[index]; - - if(keyword){ - - arr = this.get_array(term, keyword, 0, 0, false, false); - arr = /*this.*/add_result( - arr, - result, - suggest, - this.resolution_ctx, - // 0, // /** @type {!number} */ (limit), - // 0, // offset, - // length === 2 - // /*, term, keyword*/ - ); - - // 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 !== false) || !result.length){ - keyword = term; - } - } - else { - - arr = this.get_array(term, "", 0, 0, false, false); - arr = /*this.*/add_result( - arr, - result, - suggest, - resolution, - // 0, // /** @type {!number} */ (limit), - // 0, // offset, - // length === 1 - // /*, term*/ - ); - } - - // limit reached - if(arr){ - return /** @type {Array} */ (arr); - } - - // apply suggestions on last loop - if(suggest && (index === length - 1)){ - const length = result.length; - if(!length){ - // fallback to non-contextual search when no result was found - if(keyword){ - keyword = ""; - index = -1; - continue; - } - return result; - } - else if(length === 1){ - return resolve - ? resolve_default(result[0], /** @type {number} */ (limit), offset) - : new Resolver(result[0]); - } - } - } - - result = intersect$1(result, resolution, limit, offset, suggest, boost, resolve); - - return resolve - ? result - : new Resolver(result); -}; - -/** - * @param term - * @param keyword - * @param limit - * @param offset - * @param resolve - * @param enrich - * @param tag - * @this {Index} - * @return {Array|Resolver} - */ - -function single_term_query(term, keyword, limit, offset, resolve, enrich, tag){ - - const result = this.get_array(term, keyword, limit, offset, resolve, enrich, tag); - - if(this.db){ - return result.then(function(result){ - if(resolve) return result; - return result && result.length - ? (resolve ? resolve_default(result, limit, offset): new Resolver(result)) - : resolve ? [] : new Resolver([]); - }); - } - - return result && result.length - ? (resolve ? resolve_default(result, limit, offset) : new Resolver(result)) - : resolve ? [] : new Resolver([]); -} - -/** - * Returns a 1-dimensional finalized array when the result is done (fast path return), - * returns false when suggestions is enabled and no result was found, - * or returns nothing when a set was pushed successfully to the results - * - * @private - * @param {Array} arr - * @param {Array} result - * @param {boolean|null=} suggest - * @param {number=} resolution - * @return {Array|boolean|undefined} - */ - -function add_result(arr, result, suggest, resolution/*, limit, offset single_term, term, keyword*/){ - - let word_arr = []; - //let arr;// = keyword ? this.ctx : this.map; - //arr = this.get_array(term, keyword); - - if(arr){ - - //const resolution = Math.min(arr.length, keyword ? this.resolution_ctx : this.resolution); - // apply reduced resolution for queries - resolution = Math.min(arr.length, resolution); - - for(let x = 0, size = 0, tmp; x < resolution; x++){ - if((tmp = arr[x])){ - - // if(offset){ - // // apply offset right here on single terms - // if(tmp && single_term){ - // if(tmp.length <= offset){ - // offset -= tmp.length; - // tmp = null; - // } - // else{ - // tmp = tmp.slice(offset); - // offset = 0; - // } - // } - // } - - if(tmp){ - - // keep score (sparse array): - word_arr[x] = tmp; - // simplified score order: - //word_arr.push(tmp); - - // if(single_term){ - // size += tmp.length; - // if(size >= limit){ - // // fast path: - // // a single term does not need to pre-collect results - // break; - // } - // } - } - } - } - - if(word_arr.length){ - // if(single_term){ - // // fast path optimization - // // offset was already applied at this point - // // return an array will stop the query process immediately - // return resolve_default(word_arr, limit, 0); - // } - - 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 - return !suggest && word_arr; -} - -Index.prototype.get_array = function(term, keyword, limit, offset, resolve, enrich, tag){ - - let arr, swap; - - if(keyword){ - swap = this.bidirectional && (term > keyword); - } - - if(this.compress){ - term = default_compress(term); - keyword && (keyword = default_compress(keyword)); - } - - if(this.db){ - return keyword - ? this.db.get( - swap ? keyword : term, // term - swap ? term : keyword, // ctx - limit, - offset, - resolve, - enrich, - tag - ) - : this.db.get( - term, - "", // ctx - limit, - offset, - resolve, - enrich, - tag - ); - } - - 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(swap ? term : keyword); - arr = arr && arr.get(swap ? keyword : term); - } - else { - arr = this.map.get(term); - } - - return arr; -}; - -// COMPILER BLOCK --> - -/** - * @param {boolean=} _skip_deletion - */ - -Index.prototype.remove = function(id, _skip_deletion){ - - const refs = this.reg.size && ( - this.fastupdate - ? this.reg.get(id) - : this.reg.has(id) - ); - - if(refs){ - - if(this.fastupdate){ - - // fast updates did not fully cleanup 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(tmp.length < 2){ - tmp.pop(); - } - else { - const index = tmp.indexOf(id); - index === refs.length - 1 - ? tmp.pop() - : tmp.splice(index, 1); - } - } - } - - // 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*/); - } - - _skip_deletion || this.reg.delete(id); - } - - 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); - } - - return this; -}; - -/** - * @param map - * @param id - * @return {number} - */ - -function remove_index(map, id){ - - // a check counter of filled resolution slots - // to prevent removing the field - let count = 0; - - if(is_array(map)){ - for(let x = 0, arr, index; x < map.length; x++){ - if((arr = map[x]) && arr.length){ - index = arr.indexOf(id); - if(index >= 0){ - if(arr.length > 1){ - arr.splice(index, 1); - count++; - } - else { - // remove resolution slot - delete map[x]; - } - // the index key:[res, id] is unique - break; - } - else { - count++; - } - } - } - } - else for(let item of map){ - const key = item[0]; - const value = item[1]; - const tmp = remove_index(value, id); - tmp ? count += tmp - : map.delete(key); - } - - return count; -} - -/**! - * FlexSearch.js - * Author and Copyright: Thomas Wilkerling - * Licence: Apache-2.0 - * Hosted by Nextapps GmbH - * https://github.com/nextapps-de/flexsearch - */ - - -/** - * @constructor - * @param {IndexOptions|string=} options Options or preset as string - * @param {Map|Set|KeystoreSet|KeystoreMap=} _register - */ - -function Index(options, _register){ - - if(!this || this.constructor !== Index){ - return new Index(options); - } - - tick("Index.create"); - - options = /** @type IndexOptions */ ( - options - ? apply_preset(options) - : {} - ); - - let tmp = options.context; - /** @type ContextOptions */ - const context = tmp === true - ? { depth: 1 } : tmp || {}; - const encoder = is_string(options.encoder) - ? Charset[options.encoder] - : options.encode || options.encoder || ( - options$8 - ); - /** @type Encoder */ - this.encoder = encoder.encode - ? encoder - : typeof encoder === "object" - ? (new Encoder(/** @type {EncoderOptions} */ (encoder)) - - ) - : { encode: encoder }; - - { - this.compress = options.compress || options.compression || false; - } - - this.resolution = options.resolution || 9; - this.tokenize = tmp = options.tokenize || "strict"; - this.depth = (tmp === "strict" && context.depth) || 0; - this.bidirectional = context.bidirectional !== false; - this.fastupdate = !!options.fastupdate; - this.score = options.score || null; - - tmp = (options.keystore || 0); - tmp && (this.keystore = tmp); - - this.map = tmp && SUPPORT_KEYSTORE ? new KeystoreMap(tmp) : new Map(); - this.ctx = tmp && SUPPORT_KEYSTORE ? new KeystoreMap(tmp) : new Map(); - this.reg = _register || ( - this.fastupdate - ? (tmp && SUPPORT_KEYSTORE ? new KeystoreMap(tmp) : new Map()) - : (tmp && SUPPORT_KEYSTORE ? new KeystoreSet(tmp) : new Set()) - ); - this.resolution_ctx = context.resolution || 3; - this.rtl = (encoder.rtl) || options.rtl || false; - - { - this.cache = (tmp = options.cache || null) && new CacheClass(tmp); - } - - { - this.resolve = options.resolve !== false; - } - - { - if((tmp = options.db)){ - this.db = this.mount(tmp); - } - this.commit_auto = options.commit !== false; - this.commit_task = []; - this.commit_timer = null; - } -} - -{ - Index.prototype.mount = function(db){ - if(this.commit_timer){ - clearTimeout(this.commit_timer); - this.commit_timer = null; - } - return db.mount(this); - }; - Index.prototype.commit = function(replace, append){ - if(this.commit_timer){ - clearTimeout(this.commit_timer); - this.commit_timer = null; - } - return this.db.commit(this, replace, append); - }; - Index.prototype.destroy = function(){ - if(this.commit_timer){ - clearTimeout(this.commit_timer); - this.commit_timer = null; - } - return this.db.destroy(); - }; -} - -/** - * @param {!Index} self - * @param {boolean=} replace - * @param {boolean=} append - */ - -function autoCommit(self, replace, append){ - if(!self.commit_timer){ - self.commit_timer = setTimeout(function(){ - self.commit_timer = null; - self.db.commit(self, replace, append); - }, 0); - } -} - -Index.prototype.clear = function(){ - - this.map.clear(); - this.ctx.clear(); - this.reg.clear(); - - { - this.cache && - this.cache.clear(); - } - - if(this.db){ - this.commit_timer && clearTimeout(this.commit_timer); - this.commit_timer = null; - this.commit_task = [{ "clear": true }]; - } - - return this; -}; - -/** - * @param {!number|string} id - * @param {!string} content - */ - -Index.prototype.append = function(id, content){ - return this.add(id, content, true); -}; - -Index.prototype.contain = function(id){ - return this.db - ? this.db.has(id) - : this.reg.has(id); -}; - -Index.prototype.update = function(id, content){ - - const self = this; - const res = this.remove(id); - 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){ - 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){ - console.info("Cleanup the index isn't required when not using \"fastupdate\"."); - return this; - } - - cleanup_index(this.map); - this.depth && - cleanup_index(this.ctx); - - return this; -}; - -{ - - Index.prototype.searchCache = searchCache; -} - -{ - - Index.prototype.export = exportIndex; - Index.prototype.import = importIndex; - Index.prototype.serialize = serialize; -} - -{ - - apply_async(Index.prototype); -} - -// COMPILER BLOCK --> - -const VERSION = 1; -const IndexedDB = typeof window !== "undefined" && ( - window.indexedDB || - window.mozIndexedDB || - window.webkitIndexedDB || - window.msIndexedDB -); -const fields = ["map", "ctx", "tag", "reg", "cfg"]; - -function sanitize(str) { - return str.toLowerCase().replace(/[^a-z0-9_\-]/g, ""); -} - -/** - * @param {string|PersistentOptions=} name - * @param {PersistentOptions=} config - * @constructor - * @implements StorageInterface - */ - -function IdxDB(name, config = {}){ - if(!this){ - return new IdxDB(name, config); - } - if(typeof name === "object"){ - name = name.name; - config = /** @type PersistentOptions */ (name); - } - if(!name){ - console.info("Default storage space was used, because a name was not passed."); - } - this.id = "flexsearch" + (name ? ":" + sanitize(name) : ""); - this.field = config.field ? sanitize(config.field) : ""; - this.support_tag_search = false; - this.db = null; - this.trx = {}; -} -IdxDB.prototype.mount = function(flexsearch){ - //if(flexsearch.constructor === Document){ - if(!flexsearch.encoder){ - return flexsearch.mount(this); - } - flexsearch.db = this; - return this.open(); -}; - -IdxDB.prototype.open = function(){ - - let self = this; - - navigator.storage && - navigator.storage.persist(); - - return this.db || new Promise(function(resolve, reject){ - - const req = IndexedDB.open(self.id + (self.field ? ":" + self.field : ""), VERSION); - - req.onupgradeneeded = function(event){ - - 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 :( - - fields.forEach(ref => { - db.objectStoreNames.contains(ref) || - db.createObjectStore(ref);//{ autoIncrement: true /*keyPath: "id"*/ } - //.createIndex("idx", "ids", { multiEntry: true, unique: false }); - }); - - // 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 - // } - }; - - 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(){ - this.db.close(); - this.db = null; -}; - -IdxDB.prototype.destroy = function(){ - return IndexedDB.deleteDatabase(this.id + (this.field ? ":" + this.field : "")); -}; - -// 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); -// }; - -IdxDB.prototype.clear = function(){ - const transaction = this.db.transaction(fields, "readwrite"); - for(let i = 0; i < fields.length; i++){ - transaction.objectStore(fields[i]).clear(); - } - return promisfy(transaction); -}; - -IdxDB.prototype.get = function(key, ctx, limit = 0, offset = 0, resolve = true, enrich = false){ - const transaction = this.db.transaction(ctx ? "ctx" : "map", "readonly"); - const map = transaction.objectStore(ctx ? "ctx" : "map"); - const req = map.get(ctx ? ctx + ":" + key : key); - const self = this; - return promisfy(req).then(function(res){ - let result = []; - if(!res || !res.length) return result; - if(resolve){ - if(!limit && !offset && res.length === 1){ - return res[0]; - } - for(let i = 0, arr; i < res.length; i++){ - if((arr = res[i]) && arr.length){ - if(offset >= arr.length){ - offset -= arr.length; - continue; - } - const end = limit - ? offset + Math.min(arr.length - offset, limit) - : arr.length; - for(let j = offset; j < end; j++){ - result.push(arr[j]); - } - offset = 0; - if(result.length === limit){ - break; - } - } - } - return enrich - ? self.enrich(result) - : result; - } - else { - return res; - } - }); -}; - -{ - - IdxDB.prototype.tag = function(tag, limit = 0, offset = 0, enrich = false){ - const transaction = this.db.transaction("tag", "readonly"); - const map = transaction.objectStore("tag"); - const req = map.get(tag); - const self = this; - return promisfy(req).then(function(ids){ - if(!ids || !ids.length || offset >= ids.length) return []; - if(!limit && !offset) return ids; - const result = ids.slice(offset, offset + limit); - return enrich - ? self.enrich(result) - : result; - }); - }; -} - -{ - - IdxDB.prototype.enrich = function(ids){ - if(typeof ids !== "object"){ - ids = [ids]; - } - const transaction = this.db.transaction("reg", "readonly"); - const map = transaction.objectStore("reg"); - const promises = []; - for(let i = 0; i < ids.length; i++){ - promises[i] = promisfy(map.get(ids[i])); - } - return Promise.all(promises).then(function(docs){ - for(let i = 0; i < docs.length; i++){ - docs[i] = { - id: ids[i], - doc: docs[i] ? JSON.parse(docs[i]) : null - }; - } - return docs; - }); - }; -} - -IdxDB.prototype.has = function(id){ - const transaction = this.db.transaction("reg", "readonly"); - const map = transaction.objectStore("reg"); - const req = map.getKey(id); - return promisfy(req); -}; - -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 -}; - -/** - * @param {!string} ref - * @param {!string} modifier - * @param {!Function} task - */ - -IdxDB.prototype.transaction = function(ref, modifier, task){ - - let store = this.trx[ref + ":" + modifier]; - if(store) return task.call(this, store); - - let transaction = this.db.transaction(ref, modifier); - this.trx[ref + ":" + modifier] = store = transaction.objectStore(ref); - - return new Promise((resolve, reject) => { - transaction.onerror = (err) => { - this.trx[ref+ ":" + modifier] = null; - transaction.abort(); - transaction = store = null; - reject(err); - //db.close; - }; - transaction.oncomplete = (res) => { - this.trx[ref+ ":" + modifier] = null; - transaction = store = null; - resolve(res || true); - //db.close; - }; - return task.call(this, store); - }); -}; - -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; - 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 = true; - break; - } - else { - tasks[i] = task.del; - } - } - if(!_replace){ - if(!_append){ - tasks = tasks.concat(toArray(flexsearch.reg)); - } - tasks.length && await this.remove(tasks); - } - } - - if(!flexsearch.reg.size){ - return; - } - - await this.transaction("map", "readwrite", function(store){ - - for(const item of flexsearch.map){ - - const key = item[0]; - const value = item[1]; - if(!value.length) continue; - - if(_replace){ - store.put(value, key); - continue; - } - - store.get(key).onsuccess = function(){ - let result = this.result; - let changed; - if(result && result.length){ - const maxlen = Math.max(result.length, value.length); - for(let i = 0, res, val; i < maxlen; i++){ - val = value[i]; - if(val && val.length){ - res = result[i]; - if(res && res.length){ - for(let j = 0; j < val.length; j++){ - 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); - }; - } - }); - - await this.transaction("ctx", "readwrite", function(store){ - - for(const ctx of flexsearch.ctx){ - const ctx_key = ctx[0]; - const ctx_value = ctx[1]; - - for(const item of ctx_value){ - const key = item[0]; - const value = item[1]; - if(!value.length) continue; - - if(_replace){ - store.put(value, ctx_key + ":" + key); - continue; - } - - store.get(ctx_key + ":" + key).onsuccess = function(){ - let result = this.result; - let changed; - if(result && result.length){ - const maxlen = Math.max(result.length, value.length); - for(let i = 0, res, val; i < maxlen; i++){ - val = value[i]; - if(val && val.length){ - res = result[i]; - if(res && res.length){ - for(let j = 0; j < val.length; j++){ - res.push(val[j]); - } - //result[i] = res.concat(val); - changed = 1; - } - else { - result[i] = val; - changed = 1; - } - } - } - } - else { - result = value; - changed = 1; - } - - changed && - store.put(result, ctx_key + ":" + key); - }; - } - } - }); - - if(flexsearch.store){ - await this.transaction("reg", "readwrite", function(store){ - for(const item of flexsearch.store){ - const id = item[0]; - const doc = item[1]; - store.put(typeof doc === "object" - ? JSON.stringify(doc) - : 1 - , id); - } - }); - } - else if(!flexsearch.bypass){ - await this.transaction("reg", "readwrite", function(store){ - for(const id of flexsearch.reg.keys()){ - store.put(1, id); - } - }); - } - - if(flexsearch.tag){ - await this.transaction("tag", "readwrite", function(store){ - for(const item of flexsearch.tag){ - const tag = item[0]; - const ids = item[1]; - if(!ids.length) continue; - - store.get(tag).onsuccess = function(){ - let result = this.result; - result = result && result.length - ? result.concat(ids) - : ids; - store.put(result, tag); - }; - } - }); - } - - // 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(); - { - flexsearch.tag && - flexsearch.tag.clear(); - } - { - flexsearch.store && - flexsearch.store.clear(); - } - flexsearch.document || - flexsearch.reg.clear(); -}; - -/** - * @param {IDBCursorWithValue} cursor - * @param {Array} ids - * @param {boolean=} _tag - */ - -function handle(cursor, ids, _tag){ - - const arr = cursor.value; - let changed; - let parse; - let count = 0; - - 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]; - pos = result.indexOf(parse ? parseInt(id, 10) : id); - if(pos < 0 && !parse && typeof id === "string" && !isNaN(id)){ - pos = result.indexOf(parseInt(id, 10)); - pos && (parse = 1); - } - if(pos >= 0){ - changed = 1; - if(result.length > 1){ - result.splice(pos, 1); - } - else { - arr[x] = []; - break; - } - } - } - - count += result.length; - } - if(_tag) break; - } - - if(!count){ - - cursor.delete(); - //store.delete(cursor.key); - } - else if(changed){ - - //await new Promise(resolve => { - cursor.update(arr);//.onsuccess = resolve; - //}); - } - - cursor.continue(); -} - -IdxDB.prototype.remove = function(ids){ - - if(typeof ids !== "object"){ - ids = [ids]; - } - - return /** @type {!Promise} */(Promise.all([ - this.transaction("map", "readwrite", function(store){ - store.openCursor().onsuccess = function(){ - const cursor = this.result; - cursor && handle(cursor, ids); - }; - }), - this.transaction("ctx", "readwrite", function(store){ - store.openCursor().onsuccess = function(){ - const cursor = this.result; - cursor && handle(cursor, ids); - }; - }), - this.transaction("tag", "readwrite", function(store){ - store.openCursor().onsuccess = function(){ - const cursor = this.result; - cursor && handle(cursor, ids, /* tag? */ true); - }; - }), - // let filtered = []; - this.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; - ])); -}; - -/** - * @param {IDBRequest} req - * @param {Function=} callback - * @return {!Promise} - */ - -function promisfy(req, callback){ - return new Promise((resolve, reject) => { - /** @this {IDBRequest} */ - req.onsuccess = function(){ - resolve(this.result); - }; - /** @this {IDBRequest} */ - req.oncomplete = function(){ - resolve(this.result); - }; - req.onerror = reject; - req = null; - }); -} - -export { IdxDB as default }; diff --git a/dist/db/indexeddb/index.js b/dist/db/indexeddb/index.js new file mode 100644 index 0000000..37fce61 --- /dev/null +++ b/dist/db/indexeddb/index.js @@ -0,0 +1,635 @@ +/** + * @param {*} value + * @param {*} default_value + * @param {*=} merge_value + * @return {*} + */ + + +/** + * @param {Map|Set} val + * @param {boolean=} stringify + * @return {Array} + */ + +function toArray(val, stringify){ + const result = []; + for(const key of val.keys()){ + result.push(key); + } + return result; +} + +// COMPILER BLOCK --> + +const VERSION = 1; +const IndexedDB = typeof window !== "undefined" && ( + window.indexedDB || + window.mozIndexedDB || + window.webkitIndexedDB || + window.msIndexedDB +); +const fields = ["map", "ctx", "tag", "reg", "cfg"]; + +function sanitize(str) { + return str.toLowerCase().replace(/[^a-z0-9_\-]/g, ""); +} + +/** + * @param {string|PersistentOptions=} name + * @param {PersistentOptions=} config + * @constructor + * @implements StorageInterface + */ + +function IdxDB(name, config = {}){ + if(!this){ + return new IdxDB(name, config); + } + if(typeof name === "object"){ + config = /** @type PersistentOptions */ (name); + name = name.name; + } + if(!name){ + console.info("Default storage space was used, because a name was not passed."); + } + this.id = "flexsearch" + (name ? ":" + sanitize(name) : ""); + this.field = config.field ? sanitize(config.field) : ""; + this.support_tag_search = false; + this.db = null; + this.trx = {}; +} +IdxDB.prototype.mount = function(flexsearch){ + //if(flexsearch.constructor === Document){ + if(!flexsearch.encoder){ + return flexsearch.mount(this); + } + flexsearch.db = this; + return this.open(); +}; + +IdxDB.prototype.open = function(){ + + let self = this; + + navigator.storage && + navigator.storage.persist(); + + return this.db || new Promise(function(resolve, reject){ + + const req = IndexedDB.open(self.id + (self.field ? ":" + self.field : ""), VERSION); + + req.onupgradeneeded = function(event){ + + 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 :( + + fields.forEach(ref => { + db.objectStoreNames.contains(ref) || + db.createObjectStore(ref);//{ autoIncrement: true /*keyPath: "id"*/ } + //.createIndex("idx", "ids", { multiEntry: true, unique: false }); + }); + + // 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 + // } + }; + + 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(){ + this.db.close(); + this.db = null; +}; + +IdxDB.prototype.destroy = function(){ + return IndexedDB.deleteDatabase(this.id + (this.field ? ":" + this.field : "")); +}; + +// 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); +// }; + +IdxDB.prototype.clear = function(){ + const transaction = this.db.transaction(fields, "readwrite"); + for(let i = 0; i < fields.length; i++){ + transaction.objectStore(fields[i]).clear(); + } + return promisfy(transaction); +}; + +IdxDB.prototype.get = function(key, ctx, limit = 0, offset = 0, resolve = true, enrich = false){ + const transaction = this.db.transaction(ctx ? "ctx" : "map", "readonly"); + const map = transaction.objectStore(ctx ? "ctx" : "map"); + const req = map.get(ctx ? ctx + ":" + key : key); + const self = this; + return promisfy(req).then(function(res){ + let result = []; + if(!res || !res.length) return result; + if(resolve){ + if(!limit && !offset && res.length === 1){ + return res[0]; + } + for(let i = 0, arr; i < res.length; i++){ + if((arr = res[i]) && arr.length){ + if(offset >= arr.length){ + offset -= arr.length; + continue; + } + const end = limit + ? offset + Math.min(arr.length - offset, limit) + : arr.length; + for(let j = offset; j < end; j++){ + result.push(arr[j]); + } + offset = 0; + if(result.length === limit){ + break; + } + } + } + return enrich + ? self.enrich(result) + : result; + } + else { + return res; + } + }); +}; + +{ + + IdxDB.prototype.tag = function(tag, limit = 0, offset = 0, enrich = false){ + const transaction = this.db.transaction("tag", "readonly"); + const map = transaction.objectStore("tag"); + const req = map.get(tag); + const self = this; + return promisfy(req).then(function(ids){ + if(!ids || !ids.length || offset >= ids.length) return []; + if(!limit && !offset) return ids; + const result = ids.slice(offset, offset + limit); + return enrich + ? self.enrich(result) + : result; + }); + }; +} + +{ + + IdxDB.prototype.enrich = function(ids){ + if(typeof ids !== "object"){ + ids = [ids]; + } + const transaction = this.db.transaction("reg", "readonly"); + const map = transaction.objectStore("reg"); + const promises = []; + for(let i = 0; i < ids.length; i++){ + promises[i] = promisfy(map.get(ids[i])); + } + return Promise.all(promises).then(function(docs){ + for(let i = 0; i < docs.length; i++){ + docs[i] = { + id: ids[i], + doc: docs[i] ? JSON.parse(docs[i]) : null + }; + } + return docs; + }); + }; +} + +IdxDB.prototype.has = function(id){ + const transaction = this.db.transaction("reg", "readonly"); + const map = transaction.objectStore("reg"); + const req = map.getKey(id); + return promisfy(req); +}; + +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 +}; + +/** + * @param {!string} ref + * @param {!string} modifier + * @param {!Function} task + */ + +IdxDB.prototype.transaction = function(ref, modifier, task){ + + let store = this.trx[ref + ":" + modifier]; + if(store) return task.call(this, store); + + let transaction = this.db.transaction(ref, modifier); + this.trx[ref + ":" + modifier] = store = transaction.objectStore(ref); + + return new Promise((resolve, reject) => { + transaction.onerror = (err) => { + this.trx[ref+ ":" + modifier] = null; + transaction.abort(); + transaction = store = null; + reject(err); + //db.close; + }; + transaction.oncomplete = (res) => { + this.trx[ref+ ":" + modifier] = null; + transaction = store = null; + resolve(res || true); + //db.close; + }; + return task.call(this, store); + }); +}; + +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; + 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 = true; + break; + } + else { + tasks[i] = task.del; + } + } + if(!_replace){ + if(!_append){ + tasks = tasks.concat(toArray(flexsearch.reg)); + } + tasks.length && await this.remove(tasks); + } + } + + if(!flexsearch.reg.size){ + return; + } + + await this.transaction("map", "readwrite", function(store){ + + for(const item of flexsearch.map){ + + const key = item[0]; + const value = item[1]; + if(!value.length) continue; + + if(_replace){ + store.put(value, key); + continue; + } + + store.get(key).onsuccess = function(){ + let result = this.result; + let changed; + if(result && result.length){ + const maxlen = Math.max(result.length, value.length); + for(let i = 0, res, val; i < maxlen; i++){ + val = value[i]; + if(val && val.length){ + res = result[i]; + if(res && res.length){ + for(let j = 0; j < val.length; j++){ + 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); + }; + } + }); + + await this.transaction("ctx", "readwrite", function(store){ + + for(const ctx of flexsearch.ctx){ + const ctx_key = ctx[0]; + const ctx_value = ctx[1]; + + for(const item of ctx_value){ + const key = item[0]; + const value = item[1]; + if(!value.length) continue; + + if(_replace){ + store.put(value, ctx_key + ":" + key); + continue; + } + + store.get(ctx_key + ":" + key).onsuccess = function(){ + let result = this.result; + let changed; + if(result && result.length){ + const maxlen = Math.max(result.length, value.length); + for(let i = 0, res, val; i < maxlen; i++){ + val = value[i]; + if(val && val.length){ + res = result[i]; + if(res && res.length){ + for(let j = 0; j < val.length; j++){ + res.push(val[j]); + } + //result[i] = res.concat(val); + changed = 1; + } + else { + result[i] = val; + changed = 1; + } + } + } + } + else { + result = value; + changed = 1; + } + + changed && + store.put(result, ctx_key + ":" + key); + }; + } + } + }); + + if(flexsearch.store){ + await this.transaction("reg", "readwrite", function(store){ + for(const item of flexsearch.store){ + const id = item[0]; + const doc = item[1]; + store.put(typeof doc === "object" + ? JSON.stringify(doc) + : 1 + , id); + } + }); + } + else if(!flexsearch.bypass){ + await this.transaction("reg", "readwrite", function(store){ + for(const id of flexsearch.reg.keys()){ + store.put(1, id); + } + }); + } + + if(flexsearch.tag){ + await this.transaction("tag", "readwrite", function(store){ + for(const item of flexsearch.tag){ + const tag = item[0]; + const ids = item[1]; + if(!ids.length) continue; + + store.get(tag).onsuccess = function(){ + let result = this.result; + result = result && result.length + ? result.concat(ids) + : ids; + store.put(result, tag); + }; + } + }); + } + + // 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(); + { + flexsearch.tag && + flexsearch.tag.clear(); + } + { + flexsearch.store && + flexsearch.store.clear(); + } + flexsearch.document || + flexsearch.reg.clear(); +}; + +/** + * @param {IDBCursorWithValue} cursor + * @param {Array} ids + * @param {boolean=} _tag + */ + +function handle(cursor, ids, _tag){ + + const arr = cursor.value; + let changed; + let parse; + let count = 0; + + 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]; + pos = result.indexOf(parse ? parseInt(id, 10) : id); + if(pos < 0 && !parse && typeof id === "string" && !isNaN(id)){ + pos = result.indexOf(parseInt(id, 10)); + pos && (parse = 1); + } + if(pos >= 0){ + changed = 1; + if(result.length > 1){ + result.splice(pos, 1); + } + else { + arr[x] = []; + break; + } + } + } + + count += result.length; + } + if(_tag) break; + } + + if(!count){ + + cursor.delete(); + //store.delete(cursor.key); + } + else if(changed){ + + //await new Promise(resolve => { + cursor.update(arr);//.onsuccess = resolve; + //}); + } + + cursor.continue(); +} + +IdxDB.prototype.remove = function(ids){ + + if(typeof ids !== "object"){ + ids = [ids]; + } + + return /** @type {!Promise} */(Promise.all([ + this.transaction("map", "readwrite", function(store){ + store.openCursor().onsuccess = function(){ + const cursor = this.result; + cursor && handle(cursor, ids); + }; + }), + this.transaction("ctx", "readwrite", function(store){ + store.openCursor().onsuccess = function(){ + const cursor = this.result; + cursor && handle(cursor, ids); + }; + }), + this.transaction("tag", "readwrite", function(store){ + store.openCursor().onsuccess = function(){ + const cursor = this.result; + cursor && handle(cursor, ids, /* tag? */ true); + }; + }), + // let filtered = []; + this.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; + ])); +}; + +/** + * @param {IDBRequest} req + * @param {Function=} callback + * @return {!Promise} + */ + +function promisfy(req, callback){ + return new Promise((resolve, reject) => { + /** @this {IDBRequest} */ + req.onsuccess = function(){ + resolve(this.result); + }; + /** @this {IDBRequest} */ + req.oncomplete = function(){ + resolve(this.result); + }; + req.onerror = reject; + req = null; + }); +} + +export { IdxDB as default }; diff --git a/dist/db/mongodb/index.cjs b/dist/db/mongodb/index.cjs index d566879..1502591 100644 --- a/dist/db/mongodb/index.cjs +++ b/dist/db/mongodb/index.cjs @@ -49,8 +49,8 @@ function MongoDB(name, config = {}){ return new MongoDB(name, config); } if(typeof name === "object"){ - name = name.name; config = name; + name = name.name; } if(!name){ console.info("Default storage space was used, because a name was not passed."); diff --git a/dist/db/postgres/index.cjs b/dist/db/postgres/index.cjs index 0b8af69..5fe210d 100644 --- a/dist/db/postgres/index.cjs +++ b/dist/db/postgres/index.cjs @@ -79,8 +79,8 @@ function PostgresDB(name, config = {}){ return new PostgresDB(name, config); } if(typeof name === "object"){ - name = name.name; config = name; + name = name.name; } if(!name){ console.info("Default storage space was used, because a name was not passed."); diff --git a/dist/db/redis/index.cjs b/dist/db/redis/index.cjs index 887a4f7..db2c2c2 100644 --- a/dist/db/redis/index.cjs +++ b/dist/db/redis/index.cjs @@ -48,8 +48,8 @@ function RedisDB(name, config = {}){ return new RedisDB(name, config); } if(typeof name === "object"){ - name = name.name; config = name; + name = name.name; } if(!name){ console.info("Default storage space was used, because a name was not passed."); diff --git a/dist/db/sqlite/index.cjs b/dist/db/sqlite/index.cjs index 051508e..aa579f1 100644 --- a/dist/db/sqlite/index.cjs +++ b/dist/db/sqlite/index.cjs @@ -72,8 +72,8 @@ function SqliteDB(name, config = {}){ return new SqliteDB(name, config); } if(typeof name === "object"){ - name = name.name; config = name; + name = name.name; } if(!name){ console.info("Default storage space was used, because a name was not passed."); diff --git a/dist/flexsearch.bundle.debug.js b/dist/flexsearch.bundle.debug.js index eaa5d8e..639fa05 100644 --- a/dist/flexsearch.bundle.debug.js +++ b/dist/flexsearch.bundle.debug.js @@ -1,5 +1,5 @@ /**! - * FlexSearch.js v0.8.0 (Bundle/Debug) + * FlexSearch.js v0.8.001 (Bundle/Debug) * Author and Copyright: Thomas Wilkerling * Licence: Apache-2.0 * Hosted by Nextapps GmbH @@ -2278,7 +2278,7 @@ function ib(a, b = {}) { if (!this) { return new ib(a, b); } - "object" === typeof a && (b = a = a.name); + "object" === typeof a && (b = a, a = a.name); a || console.info("Default storage space was used, because a name was not passed."); this.id = "flexsearch" + (a ? ":" + a.toLowerCase().replace(/[^a-z0-9_\-]/g, "") : ""); this.field = b.field ? b.field.toLowerCase().replace(/[^a-z0-9_\-]/g, "") : ""; diff --git a/dist/flexsearch.bundle.min.js b/dist/flexsearch.bundle.min.js index e816e99..33a5097 100644 --- a/dist/flexsearch.bundle.min.js +++ b/dist/flexsearch.bundle.min.js @@ -1,5 +1,5 @@ /**! - * FlexSearch.js v0.8.0 (Bundle) + * FlexSearch.js v0.8.001 (Bundle) * Author and Copyright: Thomas Wilkerling * Licence: Apache-2.0 * Hosted by Nextapps GmbH @@ -89,7 +89,7 @@ u.export=function(a,b,c,d=0){let e,f;switch(d){case 0:e="reg";f=ta(this.reg);bre u.import=function(a,b){if(b)switch(F(b)&&(b=JSON.parse(b)),a=a.split("."),"json"===a[a.length-1]&&a.pop(),a=1{e.objectStoreNames.contains(f)||e.createObjectStore(f)})};d.onblocked=function(e){console.error("blocked",e);c()};d.onerror=function(e){console.error(this.error,e);c()};d.onsuccess=function(){a.db=this.result;a.db.onversionchange=function(){a.close()};b(a)}})}; u.close=function(){this.db.close();this.db=null};u.destroy=function(){return gb.deleteDatabase(this.id+(this.field?":"+this.field:""))};u.clear=function(){const a=this.db.transaction(hb,"readwrite");for(let b=0;b=m.length){d-=m.length;continue}const q=c?d+Math.min(m.length-d,c):m.length;for(let n=d;n{e.objectStoreNames.contains(f)||e.createObjectStore(f)})};d.onblocked=function(e){console.error("blocked",e);c()};d.onerror=function(e){console.error(this.error,e);c()};d.onsuccess=function(){a.db=this.result;a.db.onversionchange=function(){a.close()};b(a)}})}; u.close=function(){this.db.close();this.db=null};u.destroy=function(){return hb.deleteDatabase(this.id+(this.field?":"+this.field:""))};u.clear=function(){const a=this.db.transaction(ib,"readwrite");for(let b=0;b=m.length){d-=m.length;continue}const q=c?d+Math.min(m.length-d,c):m.length;for(let n=d;n=m.length)d-=m.length;else{for(var p=c?d+Math.min(m.length-d,c):m.length,n=d;nthis.stemmer.get(l)),h=1);f&&h&&(f.length< -this.minlength||this.filter&&this.filter.has(f))&&(f="");if(f&&(this.mapper||this.dedupe&&1this.matcher.get(l)));if(f&&this.replacer)for(e=0;f&&ethis.la&&(this.W.clear(),this.D=this.D/1.1|0));f&&b.push(f)}this.finalize&&(b=this.finalize(b)||b);this.cache&&a.length<=this.h&&(this.R.set(a,b),this.R.size>this.la&&(this.R.clear(),this.h=this.h/1.1|0));return b};function ja(a){a.Z=null;a.R.clear();a.W.clear()};async function ka(a){a=a.data;var c=self._index;const b=a.args;var d=a.task;switch(d){case "init":d=a.options||{};(c=a.factory)?(Function("return "+c)()(self),self._index=new self.FlexSearch.Index(d),delete self.FlexSearch):self._index=new L(d);postMessage({id:a.id});break;default:a=a.id,c=c[d].apply(c,b),postMessage("search"===d?{id:a,msg:c}:{id:a})}};let la=0; -function M(a={}){function c(f){function k(h){h=h.data||h;const l=h.id,m=l&&e.h[l];m&&(m(h.msg),delete e.h[l])}this.F=f;this.h=C();if(this.F){d?this.F.on("message",k):this.F.onmessage=k;if(a.config)return new Promise(function(h){e.h[++la]=function(){h(e)};e.F.postMessage({id:la,task:"init",factory:b,options:a})});this.F.postMessage({task:"init",factory:b,options:a});return this}}if(!this||this.constructor!==M)return new M(a);let b="undefined"!==typeof self?self._factory:"undefined"!==typeof window?window._factory: -null;b&&(b=b.toString());const d="undefined"===typeof window,e=this,g=ma(b,d,a.F);return g.then?g.then(function(f){return c.call(e,f)}):c.call(this,g)}N("add");N("append");N("search");N("update");N("remove"); -function N(a){M.prototype[a]=M.prototype[a+"Async"]=async function(){const c=this,b=[].slice.call(arguments);var d=b[b.length-1];let e;"function"===typeof d&&(e=d,b.splice(b.length-1,1));d=new Promise(function(g){c.h[++la]=g;c.F.postMessage({task:a,id:la,args:b})});return e?(d.then(e),this):d}} -function ma(a,c,b){return c?"undefined"!==typeof module?(0,eval)('new (require("worker_threads")["Worker"])(__dirname + "/node/node.js")'):(0,eval)('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="+ka.toString()],{type:"text/javascript"}))):new window.Worker(G(b)?b:(0,eval)("import.meta.url").replace("/worker.js","/worker/worker.js").replace("flexsearch.bundle.module.min.js", -"module/worker/worker.js"),{type:"module"})};function na(a){O.call(a,"add");O.call(a,"append");O.call(a,"search");O.call(a,"update");O.call(a,"remove")}function O(a){this[a+"Async"]=function(){var c=arguments;const b=c[c.length-1];let d;"function"===typeof b&&(d=b,delete c[c.length-1]);c=this[a].apply(this,c);d&&(c.then?c.then(d):d(c));return c}};function oa(a,c){c||(c=new Map);for(let b=0,d;b=f.length)c-=f.length;else{c=f[d?"splice":"slice"](c,b);const k=c.length;if(k&&(e=e.length?e.concat(c):c,b-=k,d&&(a.length-=k),!b))break;c=0}return e} -function P(a){if(!this)return new P(a);this.index=a?[a]:[];this.length=a?a.length:0;const c=this;return new Proxy([],{get(b,d){if("length"===d)return c.length;if("push"===d)return function(e){c.index[c.index.length-1].push(e);c.length++};if("pop"===d)return function(){if(c.length)return c.length--,c.index[c.index.length-1].pop()};if("indexOf"===d)return function(e){let g=0;for(let f=0,k,h;fb||d?h.slice(d,b+d):h;else{if(ab||d)h=h.slice(d,b+d)}else{e=[];for(let u=0,n;ud)d-=n.length; -else{if(n.length>b||d)n=n.slice(d,b+d),b-=n.length,d&&(d-=n.length);e.push(n);if(!b)break}h=1b||d)g=g.slice(d,d+b);e&&(g=Aa.call(this,g));return g}}function Aa(a){const c=Array(a.length);for(let b=0,d;bthis.I&&this.cache.delete(this.cache.keys().next().value)};T.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};T.prototype.remove=function(a){for(const c of this.cache){const b=c[0];c[1].includes(a)&&this.cache.delete(b)}};T.prototype.clear=function(){this.cache.clear();this.h=""};const Fa={normalize:function(a){return a.toLowerCase()},dedupe:!1};const Ga=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"]]);const Ha=new Map([["ae","a"],["oe","o"],["sh","s"],["kh","k"],["th","t"],["pf","f"]]),Ia=[/([^aeo])h(.)/g,"$1$2",/([aeo])h([^aeo]|$)/g,"$1$2",/([^0-9])\1+/g,"$1"];const Ja={a:"",e:"",i:"",o:"",u:"",y:"",b:1,f:1,p:1,v:1,c:2,g:2,j:2,k:2,q:2,s:2,x:2,z:2,"\u00df":2,d:3,t:3,l:4,m:5,n:5,r:6};const Ka=/[\x00-\x7F]+/g;const La=/[\x00-\x7F]+/g;const Ma=/[\x00-\x7F]+/g;var Na={wa:{normalize:!1,dedupe:!1},va:Fa,ya:{normalize:!0,dedupe:!0},ua:{normalize:!0,dedupe:!0,mapper:Ga},ta:{normalize:!0,dedupe:!0,mapper:Ga,matcher:Ha,replacer:Ia},xa:{normalize:!0,dedupe:!0,mapper:Ga,replacer:Ia.concat([/(?!^)[aeo]/g,""]),matcher:Ha},za:{normalize:!0,dedupe:!1,include:{letter:!0},finalize:function(a){for(let b=0;bb;b++)U[b]=b+1;U=String.fromCharCode.apply(null,U)}b=c;for(d="";c=b%255,d=U.charAt(c)+d,b=b/255|0,b;);c=d;2E5g;k--){f=t.substring(g,k);var h=this.O?this.O(c,t,p,f,g):Ta(n,d,p,e,g);W(this,m,f,h,a,b)}break}case "reverse":if(1f?0:1),d,p,k-1,h-1),v=this.fa&&t>g;W(this,l,v?g:t,q,a,b,v?t:g)}}}}this.C||this.B.add(a)}else c=""}this.db&&(c||this.ga.push({del:a}),this.na&&Ua(this));return this}; -function W(a,c,b,d,e,g,f){let k=f?a.S:a.map,h;if(!c[b]||f&&!(h=c[b])[f])if(f?(c=h||(c[b]=C()),c[f]=1,a.aa&&(f=Ra(f)),(h=k.get(f))?k=h:k.set(f,k=new Map)):c[b]=1,a.aa&&(b=Ra(b)),(h=k.get(b))?k=h:k.set(b,k=h=[]),k=k[d]||(k[d]=[]),!g||!k.includes(e)){if(k.length===2**31-1){c=new P(k);if(a.C)for(let l of a.B.values())l.includes(k)&&(l[l.indexOf(k)]=c);h[d]=k=c}k.push(e);a.C&&((d=a.B.get(e))?d.push(k):a.B.set(e,[k]))}} -function Ta(a,c,b,d,e){return b&&1c?c?a.slice(b,b+c):a.slice(b):a,d?Va(a):a;let e=[];for(let g=0,f,k;g=k){b-=k;continue}bc&&(f=f.slice(0,c),k=f.length),e.push(f);else{if(k>=c)return k>c&&(f=f.slice(0,c)),d?Va(f):f;e=[f]}c-=k;if(!c)break}if(!e.length)return e;e=1a.length?e?X(a[0],c,b,d):a[0]:xa(a,b,c,e,g)};Y.prototype.and=function(){if(this.result.length){const c=this;let b=arguments;var a=b[0];if(a.then)return a.then(function(){return c.and.apply(c,b)});if(a[0]&&a[0].index)return this.and.apply(this,a);let d=[];a=[];let e=0,g=0,f,k;for(let h=0,l;ha.length)return[];let f=[];C();let k=ba(a);return k?wa(a,k,c,b,g,e,d):f};Y.prototype.xor=function(){const a=this;let c=arguments;var b=c[0];if(b.then)return b.then(function(){return a.xor.apply(a,c)});if(b[0]&&b[0].index)return this.xor.apply(this,b);let d=[];b=[];let e=0,g=0,f,k;for(let h=0,l;ha.length)return e?X(a[0],c,b,d):a[0];d=[];const f=C();let k=0;for(let h=0,l;hb);a.aa&&(c=Ra(c),b&&(b=Ra(b)));if(a.db)return b?a.db.get(h?b:c,h?c:b,d,e,g,f,k):a.db.get(c,"",d,e,g,f,k);a=b?(a=a.S.get(h?c:b))&&a.get(h?b:c):a.map.get(c);return a};L.prototype.remove=function(a,c){const b=this.B.size&&(this.C?this.B.get(a):this.B.has(a));if(b){if(this.C)for(let d=0,e;de.length)e.pop();else{const g=e.indexOf(a);g===b.length-1?e.pop():e.splice(g,1)}}else db(this.map,a),this.depth&&db(this.S,a);c||this.B.delete(a)}this.db&&(this.ga.push({del:a}),this.na&&Ua(this));this.cache&&this.cache.remove(a);return this}; -function db(a,c){let b=0;if(a.constructor===Array)for(let d=0,e,g;db.add(a,c)):this.add(a,c)}; -A.import=function(a,c){if(c)switch(G(c)&&(c=JSON.parse(c)),a=a.split("."),"json"===a[a.length-1]&&a.pop(),a=1eb.get(c)));return a.replace(/str\b/g,"strasse").replace(/(?!\b)strasse\b/g," strasse")},filter:new Set("aber als am an auch auf aus bei bin bis bist da dadurch daher darum das dass dass dein deine dem den der des dessen deshalb die dies dieser dieses doch dort du durch ein eine einem einen einer eines er es euer eure fuer hatte hatten hattest hattet hier hinter ich ihr ihre im in ist ja jede jedem jeden jeder jedes jener jenes jetzt ggf kann kannst koennen koennt machen mein meine mit muss musst musst muessen muesst nach nachdem nein nicht noch nun oder seid sein seine sich sie sind soll sollen sollst sollt sonst soweit sowie und unser unsere unter usw uvm vom von vor wann warum was weiter weitere wenn wer werde werden werdet weshalb wie wieder wieso wir wird wirst wo woher wohin zu zum zur ueber".split(" ")), -stemmer:new Map([["niss",""],["isch",""],["lich",""],["heit",""],["keit",""],["ell",""],["bar",""],["end",""],["ung",""],["est",""],["ern",""],["em",""],["er",""],["en",""],["es",""],["st",""],["ig",""],["ik",""],["e",""],["s",""]])};"undefined"!==typeof module&&module.exports?module.exports=fb:self.FlexSearch&&(self.FlexSearch.Language.de=fb);}(this||self)); +(function(self){'use strict';const b=new Map([["_"," "],["\u00e4","ae"],["\u00f6","oe"],["\u00fc","ue"],["\u00df","ss"],["&"," und "],["\u20ac"," EUR "]]),c={prepare:function(a){/[_\u00e4\u00f6\u00fc\u00df&\u20ac]/.test(a)&&(a=a.replace(/[_\u00e4\u00f6\u00fc\u00df&\u20ac]/g,d=>b.get(d)));return a.replace(/str\b/g,"strasse").replace(/(?!\b)strasse\b/g," strasse")},filter:new Set("aber als am an auch auf aus bei bin bis bist da dadurch daher darum das dass dass dein deine dem den der des dessen deshalb die dies dieser dieses doch dort du durch ein eine einem einen einer eines er es euer eure fuer hatte hatten hattest hattet hier hinter ich ihr ihre im in ist ja jede jedem jeden jeder jedes jener jenes jetzt ggf kann kannst koennen koennt machen mein meine mit muss musst musst muessen muesst nach nachdem nein nicht noch nun oder seid sein seine sich sie sind soll sollen sollst sollt sonst soweit sowie und unser unsere unter usw uvm vom von vor wann warum was weiter weitere wenn wer werde werden werdet weshalb wie wieder wieso wir wird wirst wo woher wohin zu zum zur ueber".split(" ")), +stemmer:new Map([["niss",""],["isch",""],["lich",""],["heit",""],["keit",""],["ell",""],["bar",""],["end",""],["ung",""],["est",""],["ern",""],["em",""],["er",""],["en",""],["es",""],["st",""],["ig",""],["ik",""],["e",""],["s",""]])};"undefined"!==typeof module&&module.exports?module.exports=c:self.FlexSearch&&(self.FlexSearch.Language.de=c);}(this||self)); diff --git a/dist/lang/en.min.js b/dist/lang/en.min.js index cf2b698..bb2617b 100644 --- a/dist/lang/en.min.js +++ b/dist/lang/en.min.js @@ -1,73 +1,3 @@ -(function(self){'use strict';var A;function B(a,c,b){const d=typeof b,e=typeof a;if("undefined"!==d){if("undefined"!==e){if(b){if("function"===e&&d===e)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 g=new Map(b);for(var f of a)g.set(f[0],f[1]);return g}if(c===Set){f=new Set(b);for(g of a.values())f.add(g);return f}}}return a}return b}return"undefined"===e?c:a}function C(){return Object.create(null)}function aa(a,c){return c.length-a.length} -function G(a){return"string"===typeof a}function H(a){return"object"===typeof a}function J(a,c){if(G(c))a=a[c];else for(let b=0;a&&bthis.stemmer.get(l)),h=1);f&&h&&(f.length< -this.minlength||this.filter&&this.filter.has(f))&&(f="");if(f&&(this.mapper||this.dedupe&&1this.matcher.get(l)));if(f&&this.replacer)for(e=0;f&&ethis.la&&(this.W.clear(),this.D=this.D/1.1|0));f&&b.push(f)}this.finalize&&(b=this.finalize(b)||b);this.cache&&a.length<=this.h&&(this.R.set(a,b),this.R.size>this.la&&(this.R.clear(),this.h=this.h/1.1|0));return b};function ja(a){a.Z=null;a.R.clear();a.W.clear()};async function ka(a){a=a.data;var c=self._index;const b=a.args;var d=a.task;switch(d){case "init":d=a.options||{};(c=a.factory)?(Function("return "+c)()(self),self._index=new self.FlexSearch.Index(d),delete self.FlexSearch):self._index=new L(d);postMessage({id:a.id});break;default:a=a.id,c=c[d].apply(c,b),postMessage("search"===d?{id:a,msg:c}:{id:a})}};let la=0; -function M(a={}){function c(f){function k(h){h=h.data||h;const l=h.id,m=l&&e.h[l];m&&(m(h.msg),delete e.h[l])}this.F=f;this.h=C();if(this.F){d?this.F.on("message",k):this.F.onmessage=k;if(a.config)return new Promise(function(h){e.h[++la]=function(){h(e)};e.F.postMessage({id:la,task:"init",factory:b,options:a})});this.F.postMessage({task:"init",factory:b,options:a});return this}}if(!this||this.constructor!==M)return new M(a);let b="undefined"!==typeof self?self._factory:"undefined"!==typeof window?window._factory: -null;b&&(b=b.toString());const d="undefined"===typeof window,e=this,g=ma(b,d,a.F);return g.then?g.then(function(f){return c.call(e,f)}):c.call(this,g)}N("add");N("append");N("search");N("update");N("remove"); -function N(a){M.prototype[a]=M.prototype[a+"Async"]=async function(){const c=this,b=[].slice.call(arguments);var d=b[b.length-1];let e;"function"===typeof d&&(e=d,b.splice(b.length-1,1));d=new Promise(function(g){c.h[++la]=g;c.F.postMessage({task:a,id:la,args:b})});return e?(d.then(e),this):d}} -function ma(a,c,b){return c?"undefined"!==typeof module?(0,eval)('new (require("worker_threads")["Worker"])(__dirname + "/node/node.js")'):(0,eval)('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="+ka.toString()],{type:"text/javascript"}))):new window.Worker(G(b)?b:(0,eval)("import.meta.url").replace("/worker.js","/worker/worker.js").replace("flexsearch.bundle.module.min.js", -"module/worker/worker.js"),{type:"module"})};function na(a){O.call(a,"add");O.call(a,"append");O.call(a,"search");O.call(a,"update");O.call(a,"remove")}function O(a){this[a+"Async"]=function(){var c=arguments;const b=c[c.length-1];let d;"function"===typeof b&&(d=b,delete c[c.length-1]);c=this[a].apply(this,c);d&&(c.then?c.then(d):d(c));return c}};function oa(a,c){c||(c=new Map);for(let b=0,d;b=f.length)c-=f.length;else{c=f[d?"splice":"slice"](c,b);const k=c.length;if(k&&(e=e.length?e.concat(c):c,b-=k,d&&(a.length-=k),!b))break;c=0}return e} -function P(a){if(!this)return new P(a);this.index=a?[a]:[];this.length=a?a.length:0;const c=this;return new Proxy([],{get(b,d){if("length"===d)return c.length;if("push"===d)return function(e){c.index[c.index.length-1].push(e);c.length++};if("pop"===d)return function(){if(c.length)return c.length--,c.index[c.index.length-1].pop()};if("indexOf"===d)return function(e){let g=0;for(let f=0,k,h;fb||d?h.slice(d,b+d):h;else{if(ab||d)h=h.slice(d,b+d)}else{e=[];for(let u=0,n;ud)d-=n.length; -else{if(n.length>b||d)n=n.slice(d,b+d),b-=n.length,d&&(d-=n.length);e.push(n);if(!b)break}h=1b||d)g=g.slice(d,d+b);e&&(g=Aa.call(this,g));return g}}function Aa(a){const c=Array(a.length);for(let b=0,d;bthis.I&&this.cache.delete(this.cache.keys().next().value)};T.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};T.prototype.remove=function(a){for(const c of this.cache){const b=c[0];c[1].includes(a)&&this.cache.delete(b)}};T.prototype.clear=function(){this.cache.clear();this.h=""};const Fa={normalize:function(a){return a.toLowerCase()},dedupe:!1};const Ga=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"]]);const Ha=new Map([["ae","a"],["oe","o"],["sh","s"],["kh","k"],["th","t"],["pf","f"]]),Ia=[/([^aeo])h(.)/g,"$1$2",/([aeo])h([^aeo]|$)/g,"$1$2",/([^0-9])\1+/g,"$1"];const Ja={a:"",e:"",i:"",o:"",u:"",y:"",b:1,f:1,p:1,v:1,c:2,g:2,j:2,k:2,q:2,s:2,x:2,z:2,"\u00df":2,d:3,t:3,l:4,m:5,n:5,r:6};const Ka=/[\x00-\x7F]+/g;const La=/[\x00-\x7F]+/g;const Ma=/[\x00-\x7F]+/g;var Na={wa:{normalize:!1,dedupe:!1},va:Fa,ya:{normalize:!0,dedupe:!0},ua:{normalize:!0,dedupe:!0,mapper:Ga},ta:{normalize:!0,dedupe:!0,mapper:Ga,matcher:Ha,replacer:Ia},xa:{normalize:!0,dedupe:!0,mapper:Ga,replacer:Ia.concat([/(?!^)[aeo]/g,""]),matcher:Ha},za:{normalize:!0,dedupe:!1,include:{letter:!0},finalize:function(a){for(let b=0;bb;b++)U[b]=b+1;U=String.fromCharCode.apply(null,U)}b=c;for(d="";c=b%255,d=U.charAt(c)+d,b=b/255|0,b;);c=d;2E5g;k--){f=t.substring(g,k);var h=this.O?this.O(c,t,p,f,g):Ta(n,d,p,e,g);W(this,m,f,h,a,b)}break}case "reverse":if(1f?0:1),d,p,k-1,h-1),v=this.fa&&t>g;W(this,l,v?g:t,q,a,b,v?t:g)}}}}this.C||this.B.add(a)}else c=""}this.db&&(c||this.ga.push({del:a}),this.na&&Ua(this));return this}; -function W(a,c,b,d,e,g,f){let k=f?a.S:a.map,h;if(!c[b]||f&&!(h=c[b])[f])if(f?(c=h||(c[b]=C()),c[f]=1,a.aa&&(f=Ra(f)),(h=k.get(f))?k=h:k.set(f,k=new Map)):c[b]=1,a.aa&&(b=Ra(b)),(h=k.get(b))?k=h:k.set(b,k=h=[]),k=k[d]||(k[d]=[]),!g||!k.includes(e)){if(k.length===2**31-1){c=new P(k);if(a.C)for(let l of a.B.values())l.includes(k)&&(l[l.indexOf(k)]=c);h[d]=k=c}k.push(e);a.C&&((d=a.B.get(e))?d.push(k):a.B.set(e,[k]))}} -function Ta(a,c,b,d,e){return b&&1c?c?a.slice(b,b+c):a.slice(b):a,d?Va(a):a;let e=[];for(let g=0,f,k;g=k){b-=k;continue}bc&&(f=f.slice(0,c),k=f.length),e.push(f);else{if(k>=c)return k>c&&(f=f.slice(0,c)),d?Va(f):f;e=[f]}c-=k;if(!c)break}if(!e.length)return e;e=1a.length?e?X(a[0],c,b,d):a[0]:xa(a,b,c,e,g)};Y.prototype.and=function(){if(this.result.length){const c=this;let b=arguments;var a=b[0];if(a.then)return a.then(function(){return c.and.apply(c,b)});if(a[0]&&a[0].index)return this.and.apply(this,a);let d=[];a=[];let e=0,g=0,f,k;for(let h=0,l;ha.length)return[];let f=[];C();let k=ba(a);return k?wa(a,k,c,b,g,e,d):f};Y.prototype.xor=function(){const a=this;let c=arguments;var b=c[0];if(b.then)return b.then(function(){return a.xor.apply(a,c)});if(b[0]&&b[0].index)return this.xor.apply(this,b);let d=[];b=[];let e=0,g=0,f,k;for(let h=0,l;ha.length)return e?X(a[0],c,b,d):a[0];d=[];const f=C();let k=0;for(let h=0,l;hb);a.aa&&(c=Ra(c),b&&(b=Ra(b)));if(a.db)return b?a.db.get(h?b:c,h?c:b,d,e,g,f,k):a.db.get(c,"",d,e,g,f,k);a=b?(a=a.S.get(h?c:b))&&a.get(h?b:c):a.map.get(c);return a};L.prototype.remove=function(a,c){const b=this.B.size&&(this.C?this.B.get(a):this.B.has(a));if(b){if(this.C)for(let d=0,e;de.length)e.pop();else{const g=e.indexOf(a);g===b.length-1?e.pop():e.splice(g,1)}}else db(this.map,a),this.depth&&db(this.S,a);c||this.B.delete(a)}this.db&&(this.ga.push({del:a}),this.na&&Ua(this));this.cache&&this.cache.remove(a);return this}; -function db(a,c){let b=0;if(a.constructor===Array)for(let d=0,e,g;db.add(a,c)):this.add(a,c)}; -A.import=function(a,c){if(c)switch(G(c)&&(c=JSON.parse(c)),a=a.split("."),"json"===a[a.length-1]&&a.pop(),a=1this.stemmer.get(l)),h=1);f&&h&&(f.length< -this.minlength||this.filter&&this.filter.has(f))&&(f="");if(f&&(this.mapper||this.dedupe&&1this.matcher.get(l)));if(f&&this.replacer)for(e=0;f&&ethis.la&&(this.W.clear(),this.D=this.D/1.1|0));f&&b.push(f)}this.finalize&&(b=this.finalize(b)||b);this.cache&&a.length<=this.h&&(this.R.set(a,b),this.R.size>this.la&&(this.R.clear(),this.h=this.h/1.1|0));return b};function ja(a){a.Z=null;a.R.clear();a.W.clear()};async function ka(a){a=a.data;var c=self._index;const b=a.args;var d=a.task;switch(d){case "init":d=a.options||{};(c=a.factory)?(Function("return "+c)()(self),self._index=new self.FlexSearch.Index(d),delete self.FlexSearch):self._index=new L(d);postMessage({id:a.id});break;default:a=a.id,c=c[d].apply(c,b),postMessage("search"===d?{id:a,msg:c}:{id:a})}};let la=0; -function M(a={}){function c(f){function k(h){h=h.data||h;const l=h.id,m=l&&e.h[l];m&&(m(h.msg),delete e.h[l])}this.F=f;this.h=C();if(this.F){d?this.F.on("message",k):this.F.onmessage=k;if(a.config)return new Promise(function(h){e.h[++la]=function(){h(e)};e.F.postMessage({id:la,task:"init",factory:b,options:a})});this.F.postMessage({task:"init",factory:b,options:a});return this}}if(!this||this.constructor!==M)return new M(a);let b="undefined"!==typeof self?self._factory:"undefined"!==typeof window?window._factory: -null;b&&(b=b.toString());const d="undefined"===typeof window,e=this,g=ma(b,d,a.F);return g.then?g.then(function(f){return c.call(e,f)}):c.call(this,g)}N("add");N("append");N("search");N("update");N("remove"); -function N(a){M.prototype[a]=M.prototype[a+"Async"]=async function(){const c=this,b=[].slice.call(arguments);var d=b[b.length-1];let e;"function"===typeof d&&(e=d,b.splice(b.length-1,1));d=new Promise(function(g){c.h[++la]=g;c.F.postMessage({task:a,id:la,args:b})});return e?(d.then(e),this):d}} -function ma(a,c,b){return c?"undefined"!==typeof module?(0,eval)('new (require("worker_threads")["Worker"])(__dirname + "/node/node.js")'):(0,eval)('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="+ka.toString()],{type:"text/javascript"}))):new window.Worker(G(b)?b:(0,eval)("import.meta.url").replace("/worker.js","/worker/worker.js").replace("flexsearch.bundle.module.min.js", -"module/worker/worker.js"),{type:"module"})};function na(a){O.call(a,"add");O.call(a,"append");O.call(a,"search");O.call(a,"update");O.call(a,"remove")}function O(a){this[a+"Async"]=function(){var c=arguments;const b=c[c.length-1];let d;"function"===typeof b&&(d=b,delete c[c.length-1]);c=this[a].apply(this,c);d&&(c.then?c.then(d):d(c));return c}};function oa(a,c){c||(c=new Map);for(let b=0,d;b=f.length)c-=f.length;else{c=f[d?"splice":"slice"](c,b);const k=c.length;if(k&&(e=e.length?e.concat(c):c,b-=k,d&&(a.length-=k),!b))break;c=0}return e} -function P(a){if(!this)return new P(a);this.index=a?[a]:[];this.length=a?a.length:0;const c=this;return new Proxy([],{get(b,d){if("length"===d)return c.length;if("push"===d)return function(e){c.index[c.index.length-1].push(e);c.length++};if("pop"===d)return function(){if(c.length)return c.length--,c.index[c.index.length-1].pop()};if("indexOf"===d)return function(e){let g=0;for(let f=0,k,h;fb||d?h.slice(d,b+d):h;else{if(ab||d)h=h.slice(d,b+d)}else{e=[];for(let u=0,n;ud)d-=n.length; -else{if(n.length>b||d)n=n.slice(d,b+d),b-=n.length,d&&(d-=n.length);e.push(n);if(!b)break}h=1b||d)g=g.slice(d,d+b);e&&(g=Aa.call(this,g));return g}}function Aa(a){const c=Array(a.length);for(let b=0,d;bthis.I&&this.cache.delete(this.cache.keys().next().value)};T.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};T.prototype.remove=function(a){for(const c of this.cache){const b=c[0];c[1].includes(a)&&this.cache.delete(b)}};T.prototype.clear=function(){this.cache.clear();this.h=""};const Fa={normalize:function(a){return a.toLowerCase()},dedupe:!1};const Ga=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"]]);const Ha=new Map([["ae","a"],["oe","o"],["sh","s"],["kh","k"],["th","t"],["pf","f"]]),Ia=[/([^aeo])h(.)/g,"$1$2",/([aeo])h([^aeo]|$)/g,"$1$2",/([^0-9])\1+/g,"$1"];const Ja={a:"",e:"",i:"",o:"",u:"",y:"",b:1,f:1,p:1,v:1,c:2,g:2,j:2,k:2,q:2,s:2,x:2,z:2,"\u00df":2,d:3,t:3,l:4,m:5,n:5,r:6};const Ka=/[\x00-\x7F]+/g;const La=/[\x00-\x7F]+/g;const Ma=/[\x00-\x7F]+/g;var Na={wa:{normalize:!1,dedupe:!1},va:Fa,ya:{normalize:!0,dedupe:!0},ua:{normalize:!0,dedupe:!0,mapper:Ga},ta:{normalize:!0,dedupe:!0,mapper:Ga,matcher:Ha,replacer:Ia},xa:{normalize:!0,dedupe:!0,mapper:Ga,replacer:Ia.concat([/(?!^)[aeo]/g,""]),matcher:Ha},za:{normalize:!0,dedupe:!1,include:{letter:!0},finalize:function(a){for(let b=0;bb;b++)U[b]=b+1;U=String.fromCharCode.apply(null,U)}b=c;for(d="";c=b%255,d=U.charAt(c)+d,b=b/255|0,b;);c=d;2E5g;k--){f=t.substring(g,k);var h=this.O?this.O(c,t,p,f,g):Ta(n,d,p,e,g);W(this,m,f,h,a,b)}break}case "reverse":if(1f?0:1),d,p,k-1,h-1),v=this.fa&&t>g;W(this,l,v?g:t,q,a,b,v?t:g)}}}}this.C||this.B.add(a)}else c=""}this.db&&(c||this.ga.push({del:a}),this.na&&Ua(this));return this}; -function W(a,c,b,d,e,g,f){let k=f?a.S:a.map,h;if(!c[b]||f&&!(h=c[b])[f])if(f?(c=h||(c[b]=C()),c[f]=1,a.aa&&(f=Ra(f)),(h=k.get(f))?k=h:k.set(f,k=new Map)):c[b]=1,a.aa&&(b=Ra(b)),(h=k.get(b))?k=h:k.set(b,k=h=[]),k=k[d]||(k[d]=[]),!g||!k.includes(e)){if(k.length===2**31-1){c=new P(k);if(a.C)for(let l of a.B.values())l.includes(k)&&(l[l.indexOf(k)]=c);h[d]=k=c}k.push(e);a.C&&((d=a.B.get(e))?d.push(k):a.B.set(e,[k]))}} -function Ta(a,c,b,d,e){return b&&1c?c?a.slice(b,b+c):a.slice(b):a,d?Va(a):a;let e=[];for(let g=0,f,k;g=k){b-=k;continue}bc&&(f=f.slice(0,c),k=f.length),e.push(f);else{if(k>=c)return k>c&&(f=f.slice(0,c)),d?Va(f):f;e=[f]}c-=k;if(!c)break}if(!e.length)return e;e=1a.length?e?X(a[0],c,b,d):a[0]:xa(a,b,c,e,g)};Y.prototype.and=function(){if(this.result.length){const c=this;let b=arguments;var a=b[0];if(a.then)return a.then(function(){return c.and.apply(c,b)});if(a[0]&&a[0].index)return this.and.apply(this,a);let d=[];a=[];let e=0,g=0,f,k;for(let h=0,l;ha.length)return[];let f=[];C();let k=ba(a);return k?wa(a,k,c,b,g,e,d):f};Y.prototype.xor=function(){const a=this;let c=arguments;var b=c[0];if(b.then)return b.then(function(){return a.xor.apply(a,c)});if(b[0]&&b[0].index)return this.xor.apply(this,b);let d=[];b=[];let e=0,g=0,f,k;for(let h=0,l;ha.length)return e?X(a[0],c,b,d):a[0];d=[];const f=C();let k=0;for(let h=0,l;hb);a.aa&&(c=Ra(c),b&&(b=Ra(b)));if(a.db)return b?a.db.get(h?b:c,h?c:b,d,e,g,f,k):a.db.get(c,"",d,e,g,f,k);a=b?(a=a.S.get(h?c:b))&&a.get(h?b:c):a.map.get(c);return a};L.prototype.remove=function(a,c){const b=this.B.size&&(this.C?this.B.get(a):this.B.has(a));if(b){if(this.C)for(let d=0,e;de.length)e.pop();else{const g=e.indexOf(a);g===b.length-1?e.pop():e.splice(g,1)}}else db(this.map,a),this.depth&&db(this.S,a);c||this.B.delete(a)}this.db&&(this.ga.push({del:a}),this.na&&Ua(this));this.cache&&this.cache.remove(a);return this}; -function db(a,c){let b=0;if(a.constructor===Array)for(let d=0,e,g;db.add(a,c)):this.add(a,c)}; -A.import=function(a,c){if(c)switch(G(c)&&(c=JSON.parse(c)),a=a.split("."),"json"===a[a.length-1]&&a.pop(),a=1{b.objectStoreNames.contains(a)||b.createObjectStore(a)})},d.onblocked=function(a){console.error("blocked",a),c()},d.onerror=function(a){console.error(this.error,a),c()},d.onsuccess=function(){a.db=this.result,a.db.onversionchange=function(){a.close()},b(a)}})},IdxDB.prototype.close=function(){this.db.close(),this.db=null},IdxDB.prototype.destroy=function(){return IndexedDB.deleteDatabase(this.id+(this.field?":"+this.field:""))},IdxDB.prototype.clear=function(){const a=this.db.transaction(fields,"readwrite");for(let b=0;b=e.length){d-=e.length;continue}const a=c?d+Math.min(e.length-d,c):e.length;for(let c=d;c=a.length)return[];if(!b&&!c)return a;const e=a.slice(c,c+b);return d?h.enrich(e):e})},IdxDB.prototype.enrich=function(a){"object"!=typeof a&&(a=[a]);const b=this.db.transaction("reg","readonly"),c=b.objectStore("reg"),d=[];for(let b=0;b(e.onerror=c=>{this.trx[a+":"+b]=null,e.abort(),e=d=null,g(c)},e.oncomplete=c=>{this.trx[a+":"+b]=null,e=d=null,f(c||!0)},c.call(this,d)))},IdxDB.prototype.commit=async function(a,b,c){if(b)await this.clear(),a.commit_task=[];else{let d=a.commit_task;a.commit_task=[];for(let a,c=0;ca)||f||"string"!=typeof c||isNaN(c)||(a=h.indexOf(parseInt(c,10)),a&&(f=1)),0<=a)if(e=1,1{a.onsuccess=function(){b&&b(this.result),c(this.result)},a.oncomplete=function(){b&&b(this.result),c(this.result)},a.onerror=d,a=null})} \ No newline at end of file +import{PersistentOptions}from"../../type.js";const VERSION=1,IndexedDB="undefined"!=typeof window&&(window.indexedDB||window.mozIndexedDB||window.webkitIndexedDB||window.msIndexedDB),IDBTransaction="undefined"!=typeof window&&(window.IDBTransaction||window.webkitIDBTransaction||window.msIDBTransaction),IDBKeyRange="undefined"!=typeof window&&(window.IDBKeyRange||window.webkitIDBKeyRange||window.msIDBKeyRange),fields=["map","ctx","tag","reg","cfg"];import StorageInterface from"../interface.js";import{toArray}from"../../common.js";function sanitize(a){return a.toLowerCase().replace(/[^a-z0-9_\-]/g,"")}export default function IdxDB(a,b={}){return this?void("object"==typeof a&&(b=a,a=a.name),!a&&console.info("Default storage space was used, because a name was not passed."),this.id="flexsearch"+(a?":"+sanitize(a):""),this.field=b.field?sanitize(b.field):"",this.support_tag_search=!1,this.db=null,this.trx={}):new IdxDB(a,b)}IdxDB.prototype.mount=function(a){return a.encoder?(a.db=this,this.open()):a.mount(this)},IdxDB.prototype.open=function(){let a=this;return navigator.storage&&navigator.storage.persist(),this.db||new Promise(function(b,c){const d=IndexedDB.open(a.id+(a.field?":"+a.field:""),VERSION);d.onupgradeneeded=function(){const b=a.db=this.result;fields.forEach(a=>{b.objectStoreNames.contains(a)||b.createObjectStore(a)})},d.onblocked=function(a){console.error("blocked",a),c()},d.onerror=function(a){console.error(this.error,a),c()},d.onsuccess=function(){a.db=this.result,a.db.onversionchange=function(){a.close()},b(a)}})},IdxDB.prototype.close=function(){this.db.close(),this.db=null},IdxDB.prototype.destroy=function(){return IndexedDB.deleteDatabase(this.id+(this.field?":"+this.field:""))},IdxDB.prototype.clear=function(){const a=this.db.transaction(fields,"readwrite");for(let b=0;b=e.length){d-=e.length;continue}const a=c?d+Math.min(e.length-d,c):e.length;for(let c=d;c=a.length)return[];if(!b&&!c)return a;const e=a.slice(c,c+b);return d?h.enrich(e):e})},IdxDB.prototype.enrich=function(a){"object"!=typeof a&&(a=[a]);const b=this.db.transaction("reg","readonly"),c=b.objectStore("reg"),d=[];for(let b=0;b(e.onerror=c=>{this.trx[a+":"+b]=null,e.abort(),e=d=null,g(c)},e.oncomplete=c=>{this.trx[a+":"+b]=null,e=d=null,f(c||!0)},c.call(this,d)))},IdxDB.prototype.commit=async function(a,b,c){if(b)await this.clear(),a.commit_task=[];else{let d=a.commit_task;a.commit_task=[];for(let a,c=0;ca)||f||"string"!=typeof c||isNaN(c)||(a=h.indexOf(parseInt(c,10)),a&&(f=1)),0<=a)if(e=1,1{a.onsuccess=function(){b&&b(this.result),c(this.result)},a.oncomplete=function(){b&&b(this.result),c(this.result)},a.onerror=d,a=null})} \ No newline at end of file diff --git a/dist/module-min/db/mongodb/index.js b/dist/module-min/db/mongodb/index.js index ae75ff8..9691b31 100644 --- a/dist/module-min/db/mongodb/index.js +++ b/dist/module-min/db/mongodb/index.js @@ -1 +1 @@ -import{MongoClient}from"mongodb";const defaults={host:"localhost",port:"27017",user:null,pass:null},VERSION=1,fields=["map","ctx","tag","reg","cfg"];import StorageInterface from"../interface.js";import{toArray}from"../../common.js";function sanitize(a){return a.toLowerCase().replace(/[^a-z0-9_\-]/g,"")}let CLIENT,DB=Object.create(null);export default function MongoDB(a,b={}){return this?void("object"==typeof a&&(a=a.name,b=a),!a&&console.info("Default storage space was used, because a name was not passed."),this.id="flexsearch"+(a?"-"+sanitize(a):""),this.field=b.field?"-"+sanitize(b.field):"",this.type=b.type||"",this.db=b.db||DB[this.id]||CLIENT||null,this.trx=!1,this.support_tag_search=!0,Object.assign(defaults,b),this.db&&delete defaults.db):new MongoDB(a,b)}MongoDB.prototype.mount=function(a){return a.encoder?(a.db=this,this.open()):a.mount(this)};async function createCollection(a,b,c){"map"===b?(await a.createCollection("map"+c),await a.collection("map"+c).createIndex({key:1}),await a.collection("map"+c).createIndex({id:1})):"ctx"===b?(await a.createCollection("ctx"+c),await a.collection("ctx"+c).createIndex({ctx:1,key:1}),await a.collection("ctx"+c).createIndex({id:1})):"tag"===b?(await a.createCollection("tag"+c),await a.collection("tag"+c).createIndex({tag:1}),await a.collection("tag"+c).createIndex({id:1})):"reg"===b?(await a.createCollection("reg"),await a.collection("reg").createIndex({id:1})):"cfg"===b?await a.createCollection("cfg"+c):void 0}MongoDB.prototype.open=async function(){if(!this.db&&!(this.db=DB[this.id])&&!(this.db=CLIENT)){let a=defaults.url;a||(a=defaults.user?`mongodb://${defaults.user}:${defaults.pass}@${defaults.host}:${defaults.port}`:`mongodb://${defaults.host}:${defaults.port}`),this.db=CLIENT=new MongoClient(a),await this.db.connect()}this.db.db&&(this.db=DB[this.id]=this.db.db(this.id));const a=await this.db.listCollections().toArray();for(let b,c=0;cl;k.push({ctx:d?j:l,key:d?l:j}),l=j}let m=f?{_id:1}:{_id:1,res:1};const n=[{$match:{$or:k}},{$group:{_id:"$id",res:e?{$sum:1}:{$min:1},count:{$sum:1}}}];if(e||n.push({$match:{count:b.length-1}}),g&&(m.doc="$doc.doc",n.push({$lookup:{from:"reg",localField:"_id",foreignField:"id",as:"doc"}},{$unwind:{path:"$doc",preserveNullAndEmptyArrays:!0}})),h){const a={};for(let b=0,c=1;bl;k.push({ctx:d?j:l,key:d?l:j}),l=j}let m=f?{_id:1}:{_id:1,res:1};const n=[{$match:{$or:k}},{$group:{_id:"$id",res:e?{$sum:1}:{$min:1},count:{$sum:1}}}];if(e||n.push({$match:{count:b.length-1}}),g&&(m.doc="$doc.doc",n.push({$lookup:{from:"reg",localField:"_id",foreignField:"id",as:"doc"}},{$unwind:{path:"$doc",preserveNullAndEmptyArrays:!0}})),h){const a={};for(let b=0,c=1;bconsole.error(a)).connect()},RedisDB.prototype.close=async function(){return await this.db.disconnect(),this.db=null,this},RedisDB.prototype.destroy=function(){return this.clear()},RedisDB.prototype.clear=function(){return this.db.unlink([this.id+"map"+this.field,this.id+"ctx"+this.field,this.id+"tag"+this.field,this.id+"cfg"+this.field,this.id+"doc",this.id+"reg"])};function create_result(a,b,c,d){if(c){for(let c,d,e=0;e=a.length)return[];if(!b&&!c)return a;const f=a.slice(c,c+b);return d?e.enrich(f):f})},RedisDB.prototype.enrich=function(a){return"object"!=typeof a&&(a=[a]),this.db.hmGet(this.id+"doc",a).then(function(b){for(let c=0;cf,e.push(c+(g?d:f)+":"+(g?f:d)),f=d;b=e}else{const a=this.id+"map"+this.field+":";for(let c=0;cconsole.error(a)).connect()},RedisDB.prototype.close=async function(){return await this.db.disconnect(),this.db=null,this},RedisDB.prototype.destroy=function(){return this.clear()},RedisDB.prototype.clear=function(){return this.db.unlink([this.id+"map"+this.field,this.id+"ctx"+this.field,this.id+"tag"+this.field,this.id+"cfg"+this.field,this.id+"doc",this.id+"reg"])};function create_result(a,b,c,d){if(c){for(let c,d,e=0;e=a.length)return[];if(!b&&!c)return a;const f=a.slice(c,c+b);return d?e.enrich(f):f})},RedisDB.prototype.enrich=function(a){return"object"!=typeof a&&(a=[a]),this.db.hmGet(this.id+"doc",a).then(function(b){for(let c=0;cf,e.push(c+(g?d:f)+":"+(g?f:d)),f=d;b=e}else{const a=this.id+"map"+this.field+":";for(let c=0;c=10" - } - }, - "node_modules/@tootallnate/once": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/@tootallnate/once/-/once-1.1.2.tgz", - "integrity": "sha512-RbzJvlNzmRq5c3O09UipeuXno4tA1FE6ikOjxZK0tuxVv3412l64l5t1W5pj4+rJq9vpkm/kwiR07aZXnsKPxw==", - "optional": true, - "engines": { - "node": ">= 6" - } - }, - "node_modules/abbrev": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.1.1.tgz", - "integrity": "sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==", - "optional": true - }, - "node_modules/agent-base": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-6.0.2.tgz", - "integrity": "sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==", - "optional": true, - "dependencies": { - "debug": "4" - }, - "engines": { - "node": ">= 6.0.0" - } - }, - "node_modules/agentkeepalive": { - "version": "4.6.0", - "resolved": "https://registry.npmjs.org/agentkeepalive/-/agentkeepalive-4.6.0.tgz", - "integrity": "sha512-kja8j7PjmncONqaTsB8fQ+wE2mSU2DJ9D4XKoJ5PFWIdRMa6SLSN1ff4mOr4jCbfRSsxR4keIiySJU0N9T5hIQ==", - "optional": true, - "dependencies": { - "humanize-ms": "^1.2.1" - }, - "engines": { - "node": ">= 8.0.0" - } - }, - "node_modules/aggregate-error": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/aggregate-error/-/aggregate-error-3.1.0.tgz", - "integrity": "sha512-4I7Td01quW/RpocfNayFdFVk1qSuoh0E7JrbRJ16nH01HhKFQ88INq9Sd+nd72zqRySlr9BmDA8xlEJ6vJMrYA==", - "optional": true, - "dependencies": { - "clean-stack": "^2.0.0", - "indent-string": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/ansi-regex": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", - "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", - "optional": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/aproba": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/aproba/-/aproba-2.0.0.tgz", - "integrity": "sha512-lYe4Gx7QT+MKGbDsA+Z+he/Wtef0BiwDOlK/XkBrdfsh9J/jPPXbX0tE9x9cl27Tmu5gg3QUbUrQYa/y+KOHPQ==", - "optional": true - }, - "node_modules/are-we-there-yet": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/are-we-there-yet/-/are-we-there-yet-3.0.1.tgz", - "integrity": "sha512-QZW4EDmGwlYur0Yyf/b2uGucHQMa8aFUP7eu9ddR73vvhFyt4V0Vl3QHPcTNJ8l6qYOBdxgXdnBXQrHilfRQBg==", - "deprecated": "This package is no longer supported.", - "optional": true, - "dependencies": { - "delegates": "^1.0.0", - "readable-stream": "^3.6.0" - }, - "engines": { - "node": "^12.13.0 || ^14.15.0 || >=16.0.0" - } - }, - "node_modules/balanced-match": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", - "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", - "optional": true - }, - "node_modules/base64-js": { - "version": "1.5.1", - "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", - "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ] - }, - "node_modules/bindings": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/bindings/-/bindings-1.5.0.tgz", - "integrity": "sha512-p2q/t/mhvuOj/UeLlV6566GD/guowlr0hHxClI0W9m7MWYkL1F0hLo+0Aexs9HSPCtR1SXQ0TD3MMKrXZajbiQ==", - "dependencies": { - "file-uri-to-path": "1.0.0" - } - }, - "node_modules/bl": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/bl/-/bl-4.1.0.tgz", - "integrity": "sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w==", - "dependencies": { - "buffer": "^5.5.0", - "inherits": "^2.0.4", - "readable-stream": "^3.4.0" - } - }, - "node_modules/brace-expansion": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", - "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", - "optional": true, - "dependencies": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" - } - }, - "node_modules/buffer": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz", - "integrity": "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ], - "dependencies": { - "base64-js": "^1.3.1", - "ieee754": "^1.1.13" - } - }, - "node_modules/cacache": { - "version": "15.3.0", - "resolved": "https://registry.npmjs.org/cacache/-/cacache-15.3.0.tgz", - "integrity": "sha512-VVdYzXEn+cnbXpFgWs5hTT7OScegHVmLhJIR8Ufqk3iFD6A6j5iSX1KuBTfNEv4tdJWE2PzA6IVFtcLC7fN9wQ==", - "optional": true, - "dependencies": { - "@npmcli/fs": "^1.0.0", - "@npmcli/move-file": "^1.0.1", - "chownr": "^2.0.0", - "fs-minipass": "^2.0.0", - "glob": "^7.1.4", - "infer-owner": "^1.0.4", - "lru-cache": "^6.0.0", - "minipass": "^3.1.1", - "minipass-collect": "^1.0.2", - "minipass-flush": "^1.0.5", - "minipass-pipeline": "^1.2.2", - "mkdirp": "^1.0.3", - "p-map": "^4.0.0", - "promise-inflight": "^1.0.1", - "rimraf": "^3.0.2", - "ssri": "^8.0.1", - "tar": "^6.0.2", - "unique-filename": "^1.1.1" - }, - "engines": { - "node": ">= 10" - } - }, - "node_modules/chownr": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/chownr/-/chownr-2.0.0.tgz", - "integrity": "sha512-bIomtDF5KGpdogkLd9VspvFzk9KfpyyGlS8YFVZl7TGPBHL5snIOnxeshwVgPteQ9b4Eydl+pVbIyE1DcvCWgQ==", - "engines": { - "node": ">=10" - } - }, - "node_modules/clean-stack": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/clean-stack/-/clean-stack-2.2.0.tgz", - "integrity": "sha512-4diC9HaTE+KRAMWhDhrGOECgWZxoevMc5TlkObMqNSsVU62PYzXZ/SMTjzyGAFF1YusgxGcSWTEXBhp0CPwQ1A==", - "optional": true, - "engines": { - "node": ">=6" - } - }, - "node_modules/color-support": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-support/-/color-support-1.1.3.tgz", - "integrity": "sha512-qiBjkpbMLO/HL68y+lh4q0/O1MZFj2RX6X/KmMa3+gJD3z+WwI1ZzDHysvqHGS3mP6mznPckpXmw1nI9cJjyRg==", - "optional": true, - "bin": { - "color-support": "bin.js" - } - }, - "node_modules/concat-map": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", - "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", - "optional": true - }, - "node_modules/console-control-strings": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/console-control-strings/-/console-control-strings-1.1.0.tgz", - "integrity": "sha512-ty/fTekppD2fIwRvnZAVdeOiGd1c7YXEixbgJTNzqcxJWKQnjJ/V1bNEEE6hygpM3WjwHFUVK6HTjWSzV4a8sQ==", - "optional": true - }, - "node_modules/debug": { - "version": "4.4.0", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.0.tgz", - "integrity": "sha512-6WTZ/IxCY/T6BALoZHaE4ctp9xm+Z5kY/pzYaCHRFeyVhojxlrm+46y68HA6hr0TcwEssoxNiDEUJQjfPZ/RYA==", - "optional": true, - "dependencies": { - "ms": "^2.1.3" - }, - "engines": { - "node": ">=6.0" - }, - "peerDependenciesMeta": { - "supports-color": { - "optional": true - } - } - }, - "node_modules/decompress-response": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/decompress-response/-/decompress-response-6.0.0.tgz", - "integrity": "sha512-aW35yZM6Bb/4oJlZncMH2LCoZtJXTRxES17vE3hoRiowU2kWHaJKFkSBDnDR+cm9J+9QhXmREyIfv0pji9ejCQ==", - "dependencies": { - "mimic-response": "^3.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/deep-extend": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.6.0.tgz", - "integrity": "sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==", - "engines": { - "node": ">=4.0.0" - } - }, - "node_modules/delegates": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/delegates/-/delegates-1.0.0.tgz", - "integrity": "sha512-bd2L678uiWATM6m5Z1VzNCErI3jiGzt6HGY8OVICs40JQq/HALfbyNJmp0UDakEY4pMMaN0Ly5om/B1VI/+xfQ==", - "optional": true - }, - "node_modules/detect-libc": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.0.3.tgz", - "integrity": "sha512-bwy0MGW55bG41VqxxypOsdSdGqLwXPI/focwgTYCFMbdUiBAxLg9CFzG08sz2aqzknwiX7Hkl0bQENjg8iLByw==", - "engines": { - "node": ">=8" - } - }, - "node_modules/emoji-regex": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", - "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", - "optional": true - }, - "node_modules/encoding": { - "version": "0.1.13", - "resolved": "https://registry.npmjs.org/encoding/-/encoding-0.1.13.tgz", - "integrity": "sha512-ETBauow1T35Y/WZMkio9jiM0Z5xjHHmJ4XmjZOq1l/dXz3lr2sRn87nJy20RupqSh1F2m3HHPSp8ShIPQJrJ3A==", - "optional": true, - "dependencies": { - "iconv-lite": "^0.6.2" - } - }, - "node_modules/end-of-stream": { - "version": "1.4.4", - "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz", - "integrity": "sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==", - "dependencies": { - "once": "^1.4.0" - } - }, - "node_modules/env-paths": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/env-paths/-/env-paths-2.2.1.tgz", - "integrity": "sha512-+h1lkLKhZMTYjog1VEpJNG7NZJWcuc2DDk/qsqSTRRCOXiLjeQ1d1/udrUGhqMxUgAlwKNZ0cf2uqan5GLuS2A==", - "optional": true, - "engines": { - "node": ">=6" - } - }, - "node_modules/err-code": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/err-code/-/err-code-2.0.3.tgz", - "integrity": "sha512-2bmlRpNKBxT/CRmPOlyISQpNj+qSeYvcym/uT0Jx2bMOlKLtSy1ZmLuVxSEKKyor/N5yhvp/ZiG1oE3DEYMSFA==", - "optional": true - }, - "node_modules/expand-template": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/expand-template/-/expand-template-2.0.3.tgz", - "integrity": "sha512-XYfuKMvj4O35f/pOXLObndIRvyQ+/+6AhODh+OKWj9S9498pHHn/IMszH+gt0fBCRWMNfk1ZSp5x3AifmnI2vg==", - "engines": { - "node": ">=6" - } - }, - "node_modules/file-uri-to-path": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/file-uri-to-path/-/file-uri-to-path-1.0.0.tgz", - "integrity": "sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw==" - }, - "node_modules/fs-constants": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/fs-constants/-/fs-constants-1.0.0.tgz", - "integrity": "sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow==" - }, - "node_modules/fs-minipass": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/fs-minipass/-/fs-minipass-2.1.0.tgz", - "integrity": "sha512-V/JgOLFCS+R6Vcq0slCuaeWEdNC3ouDlJMNIsacH2VtALiu9mV4LPrHc5cDl8k5aw6J8jwgWWpiTo5RYhmIzvg==", - "dependencies": { - "minipass": "^3.0.0" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/fs.realpath": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", - "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==", - "optional": true - }, - "node_modules/gauge": { - "version": "4.0.4", - "resolved": "https://registry.npmjs.org/gauge/-/gauge-4.0.4.tgz", - "integrity": "sha512-f9m+BEN5jkg6a0fZjleidjN51VE1X+mPFQ2DJ0uv1V39oCLCbsGe6yjbBnp7eK7z/+GAon99a3nHuqbuuthyPg==", - "deprecated": "This package is no longer supported.", - "optional": true, - "dependencies": { - "aproba": "^1.0.3 || ^2.0.0", - "color-support": "^1.1.3", - "console-control-strings": "^1.1.0", - "has-unicode": "^2.0.1", - "signal-exit": "^3.0.7", - "string-width": "^4.2.3", - "strip-ansi": "^6.0.1", - "wide-align": "^1.1.5" - }, - "engines": { - "node": "^12.13.0 || ^14.15.0 || >=16.0.0" - } - }, - "node_modules/github-from-package": { - "version": "0.0.0", - "resolved": "https://registry.npmjs.org/github-from-package/-/github-from-package-0.0.0.tgz", - "integrity": "sha512-SyHy3T1v2NUXn29OsWdxmK6RwHD+vkj3v8en8AOBZ1wBQ/hCAQ5bAQTD02kW4W9tUp/3Qh6J8r9EvntiyCmOOw==" - }, - "node_modules/glob": { - "version": "7.2.3", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", - "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", - "deprecated": "Glob versions prior to v9 are no longer supported", - "optional": true, - "dependencies": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.1.1", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - }, - "engines": { - "node": "*" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/graceful-fs": { - "version": "4.2.11", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz", - "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==", - "optional": true - }, - "node_modules/has-unicode": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/has-unicode/-/has-unicode-2.0.1.tgz", - "integrity": "sha512-8Rf9Y83NBReMnx0gFzA8JImQACstCYWUplepDa9xprwwtmgEZUF0h/i5xSA625zB/I37EtrswSST6OXxwaaIJQ==", - "optional": true - }, - "node_modules/http-cache-semantics": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/http-cache-semantics/-/http-cache-semantics-4.1.1.tgz", - "integrity": "sha512-er295DKPVsV82j5kw1Gjt+ADA/XYHsajl82cGNQG2eyoPkvgUhX+nDIyelzhIWbbsXP39EHcI6l5tYs2FYqYXQ==", - "optional": true - }, - "node_modules/http-proxy-agent": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-4.0.1.tgz", - "integrity": "sha512-k0zdNgqWTGA6aeIRVpvfVob4fL52dTfaehylg0Y4UvSySvOq/Y+BOyPrgpUrA7HylqvU8vIZGsRuXmspskV0Tg==", - "optional": true, - "dependencies": { - "@tootallnate/once": "1", - "agent-base": "6", - "debug": "4" - }, - "engines": { - "node": ">= 6" - } - }, - "node_modules/https-proxy-agent": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-5.0.1.tgz", - "integrity": "sha512-dFcAjpTQFgoLMzC2VwU+C/CbS7uRL0lWmxDITmqm7C+7F0Odmj6s9l6alZc6AELXhrnggM2CeWSXHGOdX2YtwA==", - "optional": true, - "dependencies": { - "agent-base": "6", - "debug": "4" - }, - "engines": { - "node": ">= 6" - } - }, - "node_modules/humanize-ms": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/humanize-ms/-/humanize-ms-1.2.1.tgz", - "integrity": "sha512-Fl70vYtsAFb/C06PTS9dZBo7ihau+Tu/DNCk/OyHhea07S+aeMWpFFkUaXRa8fI+ScZbEI8dfSxwY7gxZ9SAVQ==", - "optional": true, - "dependencies": { - "ms": "^2.0.0" - } - }, - "node_modules/iconv-lite": { - "version": "0.6.3", - "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz", - "integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==", - "optional": true, - "dependencies": { - "safer-buffer": ">= 2.1.2 < 3.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/ieee754": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz", - "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ] - }, - "node_modules/imurmurhash": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", - "integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==", - "optional": true, - "engines": { - "node": ">=0.8.19" - } - }, - "node_modules/indent-string": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-4.0.0.tgz", - "integrity": "sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==", - "optional": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/infer-owner": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/infer-owner/-/infer-owner-1.0.4.tgz", - "integrity": "sha512-IClj+Xz94+d7irH5qRyfJonOdfTzuDaifE6ZPWfx0N0+/ATZCbuTPq2prFl526urkQd90WyUKIh1DfBQ2hMz9A==", - "optional": true - }, - "node_modules/inflight": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", - "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", - "deprecated": "This module is not supported, and leaks memory. Do not use it. Check out lru-cache if you want a good and tested way to coalesce async requests by a key value, which is much more comprehensive and powerful.", - "optional": true, - "dependencies": { - "once": "^1.3.0", - "wrappy": "1" - } - }, - "node_modules/inherits": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", - "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" - }, - "node_modules/ini": { - "version": "1.3.8", - "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.8.tgz", - "integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==" - }, - "node_modules/ip-address": { - "version": "9.0.5", - "resolved": "https://registry.npmjs.org/ip-address/-/ip-address-9.0.5.tgz", - "integrity": "sha512-zHtQzGojZXTwZTHQqra+ETKd4Sn3vgi7uBmlPoXVWZqYvuKmtI0l/VZTjqGmJY9x88GGOaZ9+G9ES8hC4T4X8g==", - "optional": true, - "dependencies": { - "jsbn": "1.1.0", - "sprintf-js": "^1.1.3" - }, - "engines": { - "node": ">= 12" - } - }, - "node_modules/is-fullwidth-code-point": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", - "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", - "optional": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/is-lambda": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-lambda/-/is-lambda-1.0.1.tgz", - "integrity": "sha512-z7CMFGNrENq5iFB9Bqo64Xk6Y9sg+epq1myIcdHaGnbMTYOxvzsEtdYqQUylB7LxfkvgrrjP32T6Ywciio9UIQ==", - "optional": true - }, - "node_modules/isexe": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", - "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", - "optional": true - }, - "node_modules/jsbn": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-1.1.0.tgz", - "integrity": "sha512-4bYVV3aAMtDTTu4+xsDYa6sy9GyJ69/amsu9sYF2zqjiEoZA5xJi3BrfX3uY+/IekIu7MwdObdbDWpoZdBv3/A==", - "optional": true - }, - "node_modules/lru-cache": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", - "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", - "optional": true, - "dependencies": { - "yallist": "^4.0.0" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/make-fetch-happen": { - "version": "9.1.0", - "resolved": "https://registry.npmjs.org/make-fetch-happen/-/make-fetch-happen-9.1.0.tgz", - "integrity": "sha512-+zopwDy7DNknmwPQplem5lAZX/eCOzSvSNNcSKm5eVwTkOBzoktEfXsa9L23J/GIRhxRsaxzkPEhrJEpE2F4Gg==", - "optional": true, - "dependencies": { - "agentkeepalive": "^4.1.3", - "cacache": "^15.2.0", - "http-cache-semantics": "^4.1.0", - "http-proxy-agent": "^4.0.1", - "https-proxy-agent": "^5.0.0", - "is-lambda": "^1.0.1", - "lru-cache": "^6.0.0", - "minipass": "^3.1.3", - "minipass-collect": "^1.0.2", - "minipass-fetch": "^1.3.2", - "minipass-flush": "^1.0.5", - "minipass-pipeline": "^1.2.4", - "negotiator": "^0.6.2", - "promise-retry": "^2.0.1", - "socks-proxy-agent": "^6.0.0", - "ssri": "^8.0.0" - }, - "engines": { - "node": ">= 10" - } - }, - "node_modules/mimic-response": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-3.1.0.tgz", - "integrity": "sha512-z0yWI+4FDrrweS8Zmt4Ej5HdJmky15+L2e6Wgn3+iK5fWzb6T3fhNFq2+MeTRb064c6Wr4N/wv0DzQTjNzHNGQ==", - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/minimatch": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", - "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", - "optional": true, - "dependencies": { - "brace-expansion": "^1.1.7" - }, - "engines": { - "node": "*" - } - }, - "node_modules/minimist": { - "version": "1.2.8", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz", - "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==", - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/minipass": { - "version": "3.3.6", - "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.3.6.tgz", - "integrity": "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==", - "dependencies": { - "yallist": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/minipass-collect": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/minipass-collect/-/minipass-collect-1.0.2.tgz", - "integrity": "sha512-6T6lH0H8OG9kITm/Jm6tdooIbogG9e0tLgpY6mphXSm/A9u8Nq1ryBG+Qspiub9LjWlBPsPS3tWQ/Botq4FdxA==", - "optional": true, - "dependencies": { - "minipass": "^3.0.0" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/minipass-fetch": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/minipass-fetch/-/minipass-fetch-1.4.1.tgz", - "integrity": "sha512-CGH1eblLq26Y15+Azk7ey4xh0J/XfJfrCox5LDJiKqI2Q2iwOLOKrlmIaODiSQS8d18jalF6y2K2ePUm0CmShw==", - "optional": true, - "dependencies": { - "minipass": "^3.1.0", - "minipass-sized": "^1.0.3", - "minizlib": "^2.0.0" - }, - "engines": { - "node": ">=8" - }, - "optionalDependencies": { - "encoding": "^0.1.12" - } - }, - "node_modules/minipass-flush": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/minipass-flush/-/minipass-flush-1.0.5.tgz", - "integrity": "sha512-JmQSYYpPUqX5Jyn1mXaRwOda1uQ8HP5KAT/oDSLCzt1BYRhQU0/hDtsB1ufZfEEzMZ9aAVmsBw8+FWsIXlClWw==", - "optional": true, - "dependencies": { - "minipass": "^3.0.0" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/minipass-pipeline": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/minipass-pipeline/-/minipass-pipeline-1.2.4.tgz", - "integrity": "sha512-xuIq7cIOt09RPRJ19gdi4b+RiNvDFYe5JH+ggNvBqGqpQXcru3PcRmOZuHBKWK1Txf9+cQ+HMVN4d6z46LZP7A==", - "optional": true, - "dependencies": { - "minipass": "^3.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/minipass-sized": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/minipass-sized/-/minipass-sized-1.0.3.tgz", - "integrity": "sha512-MbkQQ2CTiBMlA2Dm/5cY+9SWFEN8pzzOXi6rlM5Xxq0Yqbda5ZQy9sU75a673FE9ZK0Zsbr6Y5iP6u9nktfg2g==", - "optional": true, - "dependencies": { - "minipass": "^3.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/minizlib": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/minizlib/-/minizlib-2.1.2.tgz", - "integrity": "sha512-bAxsR8BVfj60DWXHE3u30oHzfl4G7khkSuPW+qvpd7jFRHm7dLxOjUk1EHACJ/hxLY8phGJ0YhYHZo7jil7Qdg==", - "dependencies": { - "minipass": "^3.0.0", - "yallist": "^4.0.0" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/mkdirp": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz", - "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==", - "bin": { - "mkdirp": "bin/cmd.js" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/mkdirp-classic": { - "version": "0.5.3", - "resolved": "https://registry.npmjs.org/mkdirp-classic/-/mkdirp-classic-0.5.3.tgz", - "integrity": "sha512-gKLcREMhtuZRwRAfqP3RFW+TK4JqApVBtOIftVgjuABpAtpxhPGaDcfvbhNvD0B8iD1oUr/txX35NjcaY6Ns/A==" - }, - "node_modules/ms": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", - "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", - "optional": true - }, - "node_modules/napi-build-utils": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/napi-build-utils/-/napi-build-utils-2.0.0.tgz", - "integrity": "sha512-GEbrYkbfF7MoNaoh2iGG84Mnf/WZfB0GdGEsM8wz7Expx/LlWf5U8t9nvJKXSp3qr5IsEbK04cBGhol/KwOsWA==" - }, - "node_modules/negotiator": { - "version": "0.6.4", - "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.4.tgz", - "integrity": "sha512-myRT3DiWPHqho5PrJaIRyaMv2kgYf0mUVgBNOYMuCH5Ki1yEiQaf/ZJuQ62nvpc44wL5WDbTX7yGJi1Neevw8w==", - "optional": true, - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/node-abi": { - "version": "3.74.0", - "resolved": "https://registry.npmjs.org/node-abi/-/node-abi-3.74.0.tgz", - "integrity": "sha512-c5XK0MjkGBrQPGYG24GBADZud0NCbznxNx0ZkS+ebUTrmV1qTDxPxSL8zEAPURXSbLRWVexxmP4986BziahL5w==", - "dependencies": { - "semver": "^7.3.5" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/node-addon-api": { - "version": "7.1.1", - "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-7.1.1.tgz", - "integrity": "sha512-5m3bsyrjFWE1xf7nz7YXdN4udnVtXK6/Yfgn5qnahL6bCkf2yKt4k3nuTKAtT4r3IG8JNR2ncsIMdZuAzJjHQQ==" - }, - "node_modules/node-gyp": { - "version": "8.4.1", - "resolved": "https://registry.npmjs.org/node-gyp/-/node-gyp-8.4.1.tgz", - "integrity": "sha512-olTJRgUtAb/hOXG0E93wZDs5YiJlgbXxTwQAFHyNlRsXQnYzUaF2aGgujZbw+hR8aF4ZG/rST57bWMWD16jr9w==", - "optional": true, - "dependencies": { - "env-paths": "^2.2.0", - "glob": "^7.1.4", - "graceful-fs": "^4.2.6", - "make-fetch-happen": "^9.1.0", - "nopt": "^5.0.0", - "npmlog": "^6.0.0", - "rimraf": "^3.0.2", - "semver": "^7.3.5", - "tar": "^6.1.2", - "which": "^2.0.2" - }, - "bin": { - "node-gyp": "bin/node-gyp.js" - }, - "engines": { - "node": ">= 10.12.0" - } - }, - "node_modules/nopt": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/nopt/-/nopt-5.0.0.tgz", - "integrity": "sha512-Tbj67rffqceeLpcRXrT7vKAN8CwfPeIBgM7E6iBkmKLV7bEMwpGgYLGv0jACUsECaa/vuxP0IjEont6umdMgtQ==", - "optional": true, - "dependencies": { - "abbrev": "1" - }, - "bin": { - "nopt": "bin/nopt.js" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/npmlog": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/npmlog/-/npmlog-6.0.2.tgz", - "integrity": "sha512-/vBvz5Jfr9dT/aFWd0FIRf+T/Q2WBsLENygUaFUqstqsycmZAP/t5BvFJTK0viFmSUxiUKTUplWy5vt+rvKIxg==", - "deprecated": "This package is no longer supported.", - "optional": true, - "dependencies": { - "are-we-there-yet": "^3.0.0", - "console-control-strings": "^1.1.0", - "gauge": "^4.0.3", - "set-blocking": "^2.0.0" - }, - "engines": { - "node": "^12.13.0 || ^14.15.0 || >=16.0.0" - } - }, - "node_modules/once": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", - "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", - "dependencies": { - "wrappy": "1" - } - }, - "node_modules/p-map": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/p-map/-/p-map-4.0.0.tgz", - "integrity": "sha512-/bjOqmgETBYB5BoEeGVea8dmvHb2m9GLy1E9W43yeyfP6QQCZGFNa+XRceJEuDB6zqr+gKpIAmlLebMpykw/MQ==", - "optional": true, - "dependencies": { - "aggregate-error": "^3.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/path-is-absolute": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", - "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==", - "optional": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/prebuild-install": { - "version": "7.1.3", - "resolved": "https://registry.npmjs.org/prebuild-install/-/prebuild-install-7.1.3.tgz", - "integrity": "sha512-8Mf2cbV7x1cXPUILADGI3wuhfqWvtiLA1iclTDbFRZkgRQS0NqsPZphna9V+HyTEadheuPmjaJMsbzKQFOzLug==", - "dependencies": { - "detect-libc": "^2.0.0", - "expand-template": "^2.0.3", - "github-from-package": "0.0.0", - "minimist": "^1.2.3", - "mkdirp-classic": "^0.5.3", - "napi-build-utils": "^2.0.0", - "node-abi": "^3.3.0", - "pump": "^3.0.0", - "rc": "^1.2.7", - "simple-get": "^4.0.0", - "tar-fs": "^2.0.0", - "tunnel-agent": "^0.6.0" - }, - "bin": { - "prebuild-install": "bin.js" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/promise-inflight": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/promise-inflight/-/promise-inflight-1.0.1.tgz", - "integrity": "sha512-6zWPyEOFaQBJYcGMHBKTKJ3u6TBsnMFOIZSa6ce1e/ZrrsOlnHRHbabMjLiBYKp+n44X9eUI6VUPaukCXHuG4g==", - "optional": true - }, - "node_modules/promise-retry": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/promise-retry/-/promise-retry-2.0.1.tgz", - "integrity": "sha512-y+WKFlBR8BGXnsNlIHFGPZmyDf3DFMoLhaflAnyZgV6rG6xu+JwesTo2Q9R6XwYmtmwAFCkAk3e35jEdoeh/3g==", - "optional": true, - "dependencies": { - "err-code": "^2.0.2", - "retry": "^0.12.0" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/pump": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.2.tgz", - "integrity": "sha512-tUPXtzlGM8FE3P0ZL6DVs/3P58k9nk8/jZeQCurTJylQA8qFYzHFfhBJkuqyE0FifOsQ0uKWekiZ5g8wtr28cw==", - "dependencies": { - "end-of-stream": "^1.1.0", - "once": "^1.3.1" - } - }, - "node_modules/rc": { - "version": "1.2.8", - "resolved": "https://registry.npmjs.org/rc/-/rc-1.2.8.tgz", - "integrity": "sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw==", - "dependencies": { - "deep-extend": "^0.6.0", - "ini": "~1.3.0", - "minimist": "^1.2.0", - "strip-json-comments": "~2.0.1" - }, - "bin": { - "rc": "cli.js" - } - }, - "node_modules/readable-stream": { - "version": "3.6.2", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", - "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==", - "dependencies": { - "inherits": "^2.0.3", - "string_decoder": "^1.1.1", - "util-deprecate": "^1.0.1" - }, - "engines": { - "node": ">= 6" - } - }, - "node_modules/retry": { - "version": "0.12.0", - "resolved": "https://registry.npmjs.org/retry/-/retry-0.12.0.tgz", - "integrity": "sha512-9LkiTwjUh6rT555DtE9rTX+BKByPfrMzEAtnlEtdEwr3Nkffwiihqe2bWADg+OQRjt9gl6ICdmB/ZFDCGAtSow==", - "optional": true, - "engines": { - "node": ">= 4" - } - }, - "node_modules/rimraf": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", - "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", - "deprecated": "Rimraf versions prior to v4 are no longer supported", - "optional": true, - "dependencies": { - "glob": "^7.1.3" - }, - "bin": { - "rimraf": "bin.js" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/safe-buffer": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", - "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ] - }, - "node_modules/safer-buffer": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", - "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", - "optional": true - }, - "node_modules/semver": { - "version": "7.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.1.tgz", - "integrity": "sha512-hlq8tAfn0m/61p4BVRcPzIGr6LKiMwo4VM6dGi6pt4qcRkmNzTcWq6eCEjEh+qXjkMDvPlOFFSGwQjoEa6gyMA==", - "bin": { - "semver": "bin/semver.js" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/set-blocking": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz", - "integrity": "sha512-KiKBS8AnWGEyLzofFfmvKwpdPzqiy16LvQfK3yv/fVH7Bj13/wl3JSR1J+rfgRE9q7xUJK4qvgS8raSOeLUehw==", - "optional": true - }, - "node_modules/signal-exit": { - "version": "3.0.7", - "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", - "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==", - "optional": true - }, - "node_modules/simple-concat": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/simple-concat/-/simple-concat-1.0.1.tgz", - "integrity": "sha512-cSFtAPtRhljv69IK0hTVZQ+OfE9nePi/rtJmw5UjHeVyVroEqJXP1sFztKUy1qU+xvz3u/sfYJLa947b7nAN2Q==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ] - }, - "node_modules/simple-get": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/simple-get/-/simple-get-4.0.1.tgz", - "integrity": "sha512-brv7p5WgH0jmQJr1ZDDfKDOSeWWg+OVypG99A/5vYGPqJ6pxiaHLy8nxtFjBA7oMa01ebA9gfh1uMCFqOuXxvA==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ], - "dependencies": { - "decompress-response": "^6.0.0", - "once": "^1.3.1", - "simple-concat": "^1.0.0" - } - }, - "node_modules/smart-buffer": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/smart-buffer/-/smart-buffer-4.2.0.tgz", - "integrity": "sha512-94hK0Hh8rPqQl2xXc3HsaBoOXKV20MToPkcXvwbISWLEs+64sBq5kFgn2kJDHb1Pry9yrP0dxrCI9RRci7RXKg==", - "optional": true, - "engines": { - "node": ">= 6.0.0", - "npm": ">= 3.0.0" - } - }, - "node_modules/socks": { - "version": "2.8.4", - "resolved": "https://registry.npmjs.org/socks/-/socks-2.8.4.tgz", - "integrity": "sha512-D3YaD0aRxR3mEcqnidIs7ReYJFVzWdd6fXJYUM8ixcQcJRGTka/b3saV0KflYhyVJXKhb947GndU35SxYNResQ==", - "optional": true, - "dependencies": { - "ip-address": "^9.0.5", - "smart-buffer": "^4.2.0" - }, - "engines": { - "node": ">= 10.0.0", - "npm": ">= 3.0.0" - } - }, - "node_modules/socks-proxy-agent": { - "version": "6.2.1", - "resolved": "https://registry.npmjs.org/socks-proxy-agent/-/socks-proxy-agent-6.2.1.tgz", - "integrity": "sha512-a6KW9G+6B3nWZ1yB8G7pJwL3ggLy1uTzKAgCb7ttblwqdz9fMGJUuTy3uFzEP48FAs9FLILlmzDlE2JJhVQaXQ==", - "optional": true, - "dependencies": { - "agent-base": "^6.0.2", - "debug": "^4.3.3", - "socks": "^2.6.2" - }, - "engines": { - "node": ">= 10" - } - }, - "node_modules/sprintf-js": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.1.3.tgz", - "integrity": "sha512-Oo+0REFV59/rz3gfJNKQiBlwfHaSESl1pcGyABQsnnIfWOFt6JNj5gCog2U6MLZ//IGYD+nA8nI+mTShREReaA==", - "optional": true - }, - "node_modules/sqlite3": { - "version": "5.1.7", - "resolved": "https://registry.npmjs.org/sqlite3/-/sqlite3-5.1.7.tgz", - "integrity": "sha512-GGIyOiFaG+TUra3JIfkI/zGP8yZYLPQ0pl1bH+ODjiX57sPhrLU5sQJn1y9bDKZUFYkX1crlrPfSYt0BKKdkog==", - "hasInstallScript": true, - "dependencies": { - "bindings": "^1.5.0", - "node-addon-api": "^7.0.0", - "prebuild-install": "^7.1.1", - "tar": "^6.1.11" - }, - "optionalDependencies": { - "node-gyp": "8.x" - }, - "peerDependencies": { - "node-gyp": "8.x" - }, - "peerDependenciesMeta": { - "node-gyp": { - "optional": true - } - } - }, - "node_modules/ssri": { - "version": "8.0.1", - "resolved": "https://registry.npmjs.org/ssri/-/ssri-8.0.1.tgz", - "integrity": "sha512-97qShzy1AiyxvPNIkLWoGua7xoQzzPjQ0HAH4B0rWKo7SZ6USuPcrUiAFrws0UH8RrbWmgq3LMTObhPIHbbBeQ==", - "optional": true, - "dependencies": { - "minipass": "^3.1.1" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/string_decoder": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", - "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", - "dependencies": { - "safe-buffer": "~5.2.0" - } - }, - "node_modules/string-width": { - "version": "4.2.3", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", - "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", - "optional": true, - "dependencies": { - "emoji-regex": "^8.0.0", - "is-fullwidth-code-point": "^3.0.0", - "strip-ansi": "^6.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/strip-ansi": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", - "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", - "optional": true, - "dependencies": { - "ansi-regex": "^5.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/strip-json-comments": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz", - "integrity": "sha512-4gB8na07fecVVkOI6Rs4e7T6NOTki5EmL7TUduTs6bu3EdnSycntVJ4re8kgZA+wx9IueI2Y11bfbgwtzuE0KQ==", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/tar": { - "version": "6.2.1", - "resolved": "https://registry.npmjs.org/tar/-/tar-6.2.1.tgz", - "integrity": "sha512-DZ4yORTwrbTj/7MZYq2w+/ZFdI6OZ/f9SFHR+71gIVUZhOQPHzVCLpvRnPgyaMpfWxxk/4ONva3GQSyNIKRv6A==", - "dependencies": { - "chownr": "^2.0.0", - "fs-minipass": "^2.0.0", - "minipass": "^5.0.0", - "minizlib": "^2.1.1", - "mkdirp": "^1.0.3", - "yallist": "^4.0.0" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/tar-fs": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/tar-fs/-/tar-fs-2.1.2.tgz", - "integrity": "sha512-EsaAXwxmx8UB7FRKqeozqEPop69DXcmYwTQwXvyAPF352HJsPdkVhvTaDPYqfNgruveJIJy3TA2l+2zj8LJIJA==", - "dependencies": { - "chownr": "^1.1.1", - "mkdirp-classic": "^0.5.2", - "pump": "^3.0.0", - "tar-stream": "^2.1.4" - } - }, - "node_modules/tar-fs/node_modules/chownr": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/chownr/-/chownr-1.1.4.tgz", - "integrity": "sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg==" - }, - "node_modules/tar-stream": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-2.2.0.tgz", - "integrity": "sha512-ujeqbceABgwMZxEJnk2HDY2DlnUZ+9oEcb1KzTVfYHio0UE6dG71n60d8D2I4qNvleWrrXpmjpt7vZeF1LnMZQ==", - "dependencies": { - "bl": "^4.0.3", - "end-of-stream": "^1.4.1", - "fs-constants": "^1.0.0", - "inherits": "^2.0.3", - "readable-stream": "^3.1.1" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/tar/node_modules/minipass": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/minipass/-/minipass-5.0.0.tgz", - "integrity": "sha512-3FnjYuehv9k6ovOEbyOswadCDPX1piCfhV8ncmYtHOjuPwylVWsghTLo7rabjC3Rx5xD4HDx8Wm1xnMF7S5qFQ==", - "engines": { - "node": ">=8" - } - }, - "node_modules/tunnel-agent": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz", - "integrity": "sha512-McnNiV1l8RYeY8tBgEpuodCC1mLUdbSN+CYBL7kJsJNInOP8UjDDEwdk6Mw60vdLLrr5NHKZhMAOSrR2NZuQ+w==", - "dependencies": { - "safe-buffer": "^5.0.1" - }, - "engines": { - "node": "*" - } - }, - "node_modules/unique-filename": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/unique-filename/-/unique-filename-1.1.1.tgz", - "integrity": "sha512-Vmp0jIp2ln35UTXuryvjzkjGdRyf9b2lTXuSYUiPmzRcl3FDtYqAwOnTJkAngD9SWhnoJzDbTKwaOrZ+STtxNQ==", - "optional": true, - "dependencies": { - "unique-slug": "^2.0.0" - } - }, - "node_modules/unique-slug": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/unique-slug/-/unique-slug-2.0.2.tgz", - "integrity": "sha512-zoWr9ObaxALD3DOPfjPSqxt4fnZiWblxHIgeWqW8x7UqDzEtHEQLzji2cuJYQFCU6KmoJikOYAZlrTHHebjx2w==", - "optional": true, - "dependencies": { - "imurmurhash": "^0.1.4" - } - }, - "node_modules/util-deprecate": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", - "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==" - }, - "node_modules/which": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", - "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", - "optional": true, - "dependencies": { - "isexe": "^2.0.0" - }, - "bin": { - "node-which": "bin/node-which" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/wide-align": { - "version": "1.1.5", - "resolved": "https://registry.npmjs.org/wide-align/-/wide-align-1.1.5.tgz", - "integrity": "sha512-eDMORYaPNZ4sQIuuYPDHdQvf4gyCF9rEEV/yPxGfwPkRodwEgiMUUXTx/dex+Me0wxx53S+NgUHaP7y3MGlDmg==", - "optional": true, - "dependencies": { - "string-width": "^1.0.2 || 2 || 3 || 4" - } - }, - "node_modules/wrappy": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", - "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==" - }, - "node_modules/yallist": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", - "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==" - } - } -} diff --git a/task/build.js b/task/build.js index a4a2b2d..e911fec 100644 --- a/task/build.js +++ b/task/build.js @@ -115,7 +115,7 @@ if(options["DEBUG"]){ parameter += ' --formatting=PRETTY_PRINT'; } -if(!release.endsWith(".module")){ +if(!release.endsWith(".module") || release === "lang"){ //parameter += ' --isolation_mode=IIFE'; parameter += ' --output_wrapper=\"(function(self){%output%}(this||self));\"'; parameter += ' --emit_use_strict=true'; @@ -155,6 +155,13 @@ if(release === "lang"){ //fs.copyFileSync("src/lang/" + lang + ".js", "tmp/lang/" + lang + ".js"); //console.log(lang) + content = fs.readFileSync("tmp/type.js", "utf8"); + content = content.replace('import Index from "./index.js";', '') + .replace('import Encoder from "./encoder.js";', '') + .replace('import StorageInterface from "./db/interface.js";', ''); + fs.writeFileSync("tmp/type.js", content); + + fs.writeFileSync("tmp/lang.js", ` import { EncoderOptions, EncoderSplitOptions } from "./type.js"; import lang from "./lang/${lang}.js"; @@ -173,7 +180,6 @@ if(release === "lang"){ /** @export */ EncoderOptions.minlength; /** @export */ EncoderOptions.maxlength; /** @export */ EncoderOptions.cache; - /** @export */ EncoderSplitOptions.letter; /** @export */ EncoderSplitOptions.number; /** @export */ EncoderSplitOptions.symbol; @@ -188,7 +194,7 @@ if(release === "lang"){ process.platform === "darwin" ? "\"node_modules/google-closure-compiler-osx/compiler\"" : "java -jar node_modules/google-closure-compiler-java/compiler.jar"; - exec(executable + parameter + " --js='tmp/**.js' --js='!tmp/db/**.js' --js='tmp/db/interface.js'" + flag_str + " --js_output_file='dist/lang/" + lang + ".min.js' && exit 0", function(){ + exec(executable + parameter + " --js='tmp/lang.js' --js='tmp/lang/*.js' --js='tmp/type.js'" + flag_str + " --js_output_file='dist/lang/" + lang + ".min.js' && exit 0", function(){ console.log("Build Complete: " + lang + ".min.js"); next(++x, y, z);