From ef846b508d778fbd1d719a8253d737abdde97122 Mon Sep 17 00:00:00 2001 From: Thomas Wilkerling Date: Thu, 31 Jan 2019 16:37:27 +0100 Subject: [PATCH] v0.3.5 --- README.md | 58 ++++- compile.js | 1 + flexsearch.compact.js | 35 ++- flexsearch.js | 563 ++++++++++++++++++++++------------------- flexsearch.light.js | 24 +- flexsearch.min.js | 49 ++-- package.json | 13 +- test/flexsearch.es5.js | 61 ++--- test/test.js | 323 +++++++++++------------ 9 files changed, 599 insertions(+), 528 deletions(-) diff --git a/README.md b/README.md index 8301a1b..71e9673 100644 --- a/README.md +++ b/README.md @@ -1559,18 +1559,63 @@ Compare these presets: - Relevance Scoring
- Benchmarks - ## Best Practices __Split Complexity__ Whenever you can, try to divide content by categories and add them to its own index, e.g.: + ```js -var feeds_2017 = new FlexSearch(); -var feeds_2018 = new FlexSearch(); -var feeds_2019 = new FlexSearch(); +var action = new FlexSearch(); +var adventure = new FlexSearch(); +var comedy = new FlexSearch(); ``` +This way you can also provide different settings for each category. + +To make this workaround more extendable you can define a tiny helper: +```js +var settings = {}; +var index = {}; + +function add(id, cat, content){ + (index[cat] || ( + index[cat] = new FlexSearch(settings[cat]) + )).add(id, content); +} + +function search(cat, query){ + return index[cat] ? index[cat].search(query) : []; +} +``` + +Provide settings optionally (or skip and use defaults): +```js +settings = { + action: "score", + adventure: "match", + comedy: { + encode: "advanced", + tokenize: "forward", + threshold: 5 + } +}; +``` + +Add content to the index: +```js +add(1, "action", "Movie Title"); +add(2, "adventure", "Movie Title"); +add(3, "comedy", "Movie Title"); +``` + +Perform queries: +```js +var results = search("action", "movie title"); // --> [1] +``` + +Filter queries by categories will hugely improve performance. + __Use numeric IDs__ It is recommended to use numeric id values as reference when adding content to the index. The byte length of passed ids influences the memory consumption significantly. If this is not possible you should consider to use a index table and map the ids with indexes, this becomes important especially when using contextual indexes on a large amount of content. @@ -1771,6 +1816,11 @@ __Supported Build Flags__ SUPPORT_PRESETS true, false + + + SUPPORT_SERIALIZE + true, false +
Language Flags (includes stemmer and filter) diff --git a/compile.js b/compile.js index ff640e9..94b771f 100644 --- a/compile.js +++ b/compile.js @@ -72,6 +72,7 @@ var parameter = (function(opt){ export_local_property_definitions: true, language_in: "ECMASCRIPT6_STRICT", language_out: language_out || "ECMASCRIPT6_STRICT", + //rewrite_polyfills: false, process_closure_primitives: true, summary_detail_level: 3, warning_level: "VERBOSE", diff --git a/flexsearch.compact.js b/flexsearch.compact.js index d6c50c8..40f79e8 100644 --- a/flexsearch.compact.js +++ b/flexsearch.compact.js @@ -1,24 +1,23 @@ /* - FlexSearch v0.3.3 + FlexSearch v0.3.5 Copyright 2019 Nextapps GmbH Author: Thomas Wilkerling Released under the Apache 2.0 Licence https://github.com/nextapps-de/flexsearch */ -'use strict';(function(g,u,c){let m;(m=c.define)&&m.amd?m([],function(){return u}):(m=c.modules)?m[g.toLowerCase()]=u:"object"===typeof exports?module.exports=u:c[g]=u})("FlexSearch",function(){function g(a){y(a)&&(a=H[a]);a||(a=v);this.id=a.id||O++;this.init(a);u(this,"index",function(){return this.b});u(this,"length",function(){return Object.keys(this.b).length})}function u(a,b,d){Object.defineProperty(a,b,{get:d})}function c(a){return new RegExp(a,"g")}function m(a,b){for(let d=0;d=h&&(a=a[9-(f+.5>>0)],a=a[d]||(a[d]=[]),a[a.length]=e);return f}function D(a,b){if(a){const d=Object.keys(a);for(let e=0,f=d.length;ea?1:a?-1:0}function Q(a,b){a=a.length-b.length;return 0>a?-1:a?1:0}function R(a,b,d){let c=[],f;const z=a.length;if(1b&&(c=c.slice(0,b)));return c}function y(a){return"string"===typeof a}function A(a){return"function"===typeof a}function B(a){return"undefined"===typeof a}function F(a){a.l|| -(a.l=J(function(){a.l=0;{const b=a.async;let d;b&&(a.async=!1);if(a.c.length){const b=Date.now();let c;for(;(c=a.c.shift())||0===c;){d=a.g[c];switch(d[0]){case C.add:a.add(d[1],d[2]);break;case C.remove:a.remove(d[1])}delete a.g[c];if(100k;d--)h= -c.substring(k,d),x(r,p,h,a,b,g,n)}break;default:if(f=x(r,p,c,a,1,g,n),l&&1=n)for(f=p._ctx[c]||(p._ctx[c]=t()),c=this.f[c]||(this.f[c]=K(10-(n||0))),g=e-l,h=e+l+1,0>g&&(g=0),h>q&&(h=q);g=m&&(a=a[9-(e+.5>>0)],a=a[c]||(a[c]=[]),a[a.length]=g);return e}function C(a,b){if(a){const c=Object.keys(a);for(let g=0,d=c.length;ga?1:a?-1:0}function N(a,b){a=a.length-b.length;return 0>a?-1:a?1:0}function O(a,b,c){let d=[],e;const u=a.length;if(1b&&(d=d.slice(0,b)));return d}function z(a){return"string"===typeof a}function A(a){return"function"===typeof a}function B(a){return"undefined"===typeof a}function H(a){const b= +Array(a);for(let c=0;ck;c--)n=m.substring(k,c),y(u,h,n,a,b,l,p)}break;default:if(f=y(u,h,m,a,1,l,p),q&&1=p)for(f=h._ctx[m]||(h._ctx[m]=t()),m=this.c[m]||(this.c[m]=H(10-(p||0))),l=b-q,n=b+q+1,0>l&&(l= +0),n>w&&(n=w);l= limit)){ self._task_completed = self.worker; @@ -337,9 +343,6 @@ if(self._current_callback && (self._task_completed === self.worker)){ - // store result to cache - // TODO: add worker cache, may remove global cache - if(self.cache){ self._cache.set(query, self._task_result); @@ -375,7 +378,7 @@ if(SUPPORT_ASYNC) /** @private */ this.async = ( - is_undefined(custom = options["async"]) ? + (typeof Promise === "undefined") || is_undefined(custom = options["async"]) ? this.async || defaults.async @@ -474,9 +477,9 @@ /** @private */ this._ids = create_object(); /** @private */ - this._stack = create_object(); + //this._stack = create_object(); /** @private */ - this._stack_keys = []; + //this._stack_keys = []; /** * @type {number|null} @@ -605,252 +608,274 @@ /** * @param {number|string} id * @param {string} content + * @param {Function=} callback * @param {boolean=} _skip_update + * @param {boolean=} _recall * @this {FlexSearch} * @export */ - FlexSearch.prototype.add = function(id, content, _skip_update){ + FlexSearch.prototype.add = function(id, content, callback, _skip_update, _recall){ if(content && is_string(content) && ((id /*&& !index_blacklist[id]*/) || (id === 0))){ const index = "@" + id; - // check if index ID already exist - if(this._ids[index] && !_skip_update){ - this.update(id, content); + return this.update(id, content); } - else{ - if(SUPPORT_WORKER && this.worker){ + if(SUPPORT_WORKER && this.worker){ - if(++this._current_task >= this._worker.length){ + if(++this._current_task >= this._worker.length){ - this._current_task = 0; - } + this._current_task = 0; + } - this._worker[this._current_task].postMessage(this._current_task, { + this._worker[this._current_task].postMessage({ - "add": true, - "id": id, - "content": content - }); + "add": true, + "id": id, + "content": content + }); - this._ids[index] = "" + this._current_task; + this._ids[index] = "" + this._current_task; - // TODO: improve auto-balancing - //this._ids_count[this._current_task]++; + // TODO: provide worker auto-balancing instead of rotation + //this._ids_count[this._current_task]++; - return this; - } + if(callback){ - // collect tasks for non-blocking processing - // TODO: actually auto-enabled in worker + callback(); + } - if(SUPPORT_ASYNC && this.async){ + return this; + } - this._stack[index] || ( + if(!_recall){ - this._stack_keys[this._stack_keys.length] = index - ); + if(SUPPORT_ASYNC && this.async && (typeof importScripts !== "function")){ - this._stack[index] = [ + let self = this; - enum_task.add, - id, - content - ]; + /** + * @param fn + * @constructor + */ - register_task(this); + const promise = new Promise(function(resolve){ - return this; - } + setTimeout(function(){ - if(PROFILER){ + self.add(id, content, null, _skip_update, true); + self = null; + resolve(); + }); + }); - profile_start("add"); - } + if(callback){ - content = this.encode(content); + promise.then(callback); + } + else{ - if(!content.length){ + return promise; + } return this; } + else if(callback){ - const tokenizer = this.tokenize; + this.add(id, content, null, _skip_update, true); + callback(); - const words = ( + return this; + } + } - is_function(tokenizer) ? + if(PROFILER){ - tokenizer(content) - :( - //SUPPORT_ENCODER && (tokenizer === "ngram") ? + profile_start("add"); + } - /** @type {!Array} */ - //(ngram(/** @type {!string} */(content))) - //: - /** @type {string} */ - (content).split(regex_split) - ) - ); + content = this.encode(content); - const dupes = create_object(); - dupes["_ctx"] = create_object(); + if(!content.length){ - const threshold = this.threshold; - const depth = this.depth; - const map = this._map; - const word_length = words.length; + return this; + } - // tokenize + const tokenizer = this.tokenize; - for(let i = 0; i < word_length; i++){ + const words = ( - /** @type {string} */ - const value = words[i]; + is_function(tokenizer) ? - if(value){ + tokenizer(content) + :( + //SUPPORT_ENCODER && (tokenizer === "ngram") ? - const length = value.length; - const context_score = (word_length - i) / word_length; - - let tmp = ""; + /** @type {!Array} */ + //(ngram(/** @type {!string} */(content))) + //: + /** @type {string} */ + (content).split(regex_split) + ) + ); - switch(tokenizer){ + const dupes = create_object(); + dupes["_ctx"] = create_object(); - case "reverse": - case "both": + const threshold = this.threshold; + const depth = this.depth; + const map = this._map; + const word_length = words.length; - for(let a = length - 1; a >= 1; a--){ + // tokenize - tmp = value[a] + tmp; + for(let i = 0; i < word_length; i++){ - add_index( + /** @type {string} */ + const value = words[i]; - map, - dupes, - tmp, - id, - (length - a) / length, - context_score, - threshold - ); - } - - tmp = ""; + if(value){ - // Note: no break here, fallthrough to next case + const length = value.length; + const context_score = (word_length - i) / word_length; - case "forward": + let tmp = ""; - for(let a = 0; a < length; a++){ + switch(tokenizer){ - tmp += value[a]; + case "reverse": + case "both": - add_index( + for(let a = length - 1; a >= 1; a--){ - map, - dupes, - tmp, - id, - 1, - context_score, - threshold - ); - } + tmp = value[a] + tmp; - break; + add_index( - case "full": - - for(let x = 0; x < length; x++){ - - const partial_score = (length - x) / length; - - for(let y = length; y > x; y--){ + map, + dupes, + tmp, + id, + (length - a) / length, + context_score, + threshold + ); + } - tmp = value.substring(x, y); + tmp = ""; - add_index( + // Note: no break here, fallthrough to next case - map, - dupes, - tmp, - id, - partial_score, - context_score, - threshold - ); - } - } + case "forward": - break; + for(let a = 0; a < length; a++){ - //case "strict": - //case "ngram": - default: + tmp += value[a]; - const score = add_index( + add_index( map, dupes, - value, + tmp, id, - // Note: ngrams has partial scoring (sequence->word) and contextual scoring (word->context) - // TODO compute and pass distance of ngram sequences as the initial score for each word 1, context_score, threshold ); + } - if(depth && (word_length > 1) && (score >= threshold)){ + break; - const ctxDupes = dupes["_ctx"][value] || (dupes["_ctx"][value] = create_object()); - const ctxTmp = this._ctx[value] || (this._ctx[value] = create_object_array(10 - (threshold || 0))); + case "full": - let x = i - depth; - let y = i + depth + 1; + for(let x = 0; x < length; x++){ - if(x < 0) x = 0; - if(y > word_length) y = word_length; + const partial_score = (length - x) / length; - for(; x < y; x++){ + for(let y = length; y > x; y--){ - if(x !== i) add_index( + tmp = value.substring(x, y); - ctxTmp, - ctxDupes, - words[x], - id, - 0, - 10 - (x < i ? i - x : x - i), - threshold - ); - } + add_index( + + map, + dupes, + tmp, + id, + partial_score, + context_score, + threshold + ); } + } - break; - } + break; + + //case "strict": + //case "ngram": + default: + + const score = add_index( + + map, + dupes, + value, + id, + // Note: ngrams has partial scoring (sequence->word) and contextual scoring (word->context) + // TODO compute and pass distance of ngram sequences as the initial score for each word + 1, + context_score, + threshold + ); + + if(depth && (word_length > 1) && (score >= threshold)){ + + const ctxDupes = dupes["_ctx"][value] || (dupes["_ctx"][value] = create_object()); + const ctxTmp = this._ctx[value] || (this._ctx[value] = create_object_array(10 - (threshold || 0))); + + let x = i - depth; + let y = i + depth + 1; + + if(x < 0) x = 0; + if(y > word_length) y = word_length; + + for(; x < y; x++){ + + if(x !== i) add_index( + + ctxTmp, + ctxDupes, + words[x], + id, + 0, + 10 - (x < i ? i - x : x - i), + threshold + ); + } + } + + break; } } + } - // update status + // update status - this._ids[index] = 1; + this._ids[index] = 1; - if(SUPPORT_CACHE){ + if(SUPPORT_CACHE){ - this._cache_status = false; - } + this._cache_status = false; + } - if(PROFILER){ + if(PROFILER){ - profile_end("add"); - } + profile_end("add"); } } @@ -858,12 +883,13 @@ }; /** - * @param id - * @param content + * @param {number|string} id + * @param {string} content + * @param {Function=} callback * @export */ - FlexSearch.prototype.update = function(id, content){ + FlexSearch.prototype.update = function(id, content, callback){ const index = "@" + id; @@ -875,7 +901,7 @@ } this.remove(id); - this.add(id, content, /* skip_update: */ true); + this.add(id, content, callback, /* skip_update: */ true); if(PROFILER){ @@ -887,11 +913,13 @@ }; /** - * @param id + * @param {number|string} id + * @param {Function=} callback + * @param {boolean=} _recall * @export */ - FlexSearch.prototype.remove = function(id){ + FlexSearch.prototype.remove = function(id, callback, _recall){ const index = "@" + id; @@ -901,7 +929,7 @@ const current_task = this._ids[index]; - this._worker[current_task].postMessage(current_task, { + this._worker[current_task].postMessage({ "remove": true, "id": id @@ -911,25 +939,48 @@ delete this._ids[index]; + if(callback){ + + callback(); + } + return this; } - if(SUPPORT_ASYNC && this.async){ + if(!_recall){ - this._stack[index] || ( + if(SUPPORT_ASYNC && this.async && (typeof importScripts !== "function")){ - this._stack_keys[this._stack_keys.length] = index - ); + let self = this; + + const promise = new Promise(function(resolve){ - this._stack[index] = [ + setTimeout(function(){ - enum_task.remove, - id - ]; + self.remove(id, null, true); + self = null; + resolve(); + }); + }); - register_task(this); + if(callback){ - return this; + promise.then(callback); + } + else{ + + return promise; + } + + return this; + } + else if(callback){ + + this.remove(id, null, true); + callback(); + + return this; + } } if(PROFILER){ @@ -968,7 +1019,7 @@ * @param {number|Function=} limit * @param {Function=} callback * @param {boolean=} _recall - * @returns {Array|Promise|undefined} + * @returns {FlexSearch|Array|Promise|undefined} * @export */ @@ -1024,7 +1075,7 @@ for(let i = 0; i < this.worker; i++){ - this._worker[i].postMessage(i, { + this._worker[i].postMessage({ "search": true, "limit": limit, @@ -1036,37 +1087,38 @@ return; } - if(callback){ + if(!_recall){ - if(SUPPORT_ASYNC){ + if(SUPPORT_ASYNC && this.async && (typeof importScripts !== "function")){ - /** @type {FlexSearch} */ let self = this; - queue(function(){ + const promise = new Promise(function(resolve){ - callback(self.search(_query, limit, null, true)); - self = null; + setTimeout(function(){ - }, 1, "search-" + this.id); - } - else{ + resolve(self.search(_query, limit, null, true)); + self = null; + }); + }); - callback(this.search(_query, limit, null, true)); - } + if(callback){ - return; - } - else if(SUPPORT_ASYNC && !_recall && this.async && (typeof importScripts !== "function")){ + promise.then(callback); + } + else{ - /** @type {FlexSearch} */ - let self = this; + return promise; + } - return new Promise(function(resolve){ + return this; + } + else if(callback){ - resolve(self.search(_query, limit, null, true)); - self = null; - }); + callback(this.search(_query, limit, null, true)); + + return this; + } } if(PROFILER){ @@ -1258,7 +1310,7 @@ return result; }; - if(DEBUG){ + if(SUPPORT_INFO){ /** * @export @@ -1268,7 +1320,7 @@ if(SUPPORT_WORKER && this.worker){ - for(let i = 0; i < this.worker; i++) this._worker[i].postMessage(i, { + for(let i = 0; i < this.worker; i++) this._worker[i].postMessage({ "info": true, "id": this.id @@ -1331,13 +1383,9 @@ FlexSearch.prototype.clear = function(){ - // destroy index - - this.destroy(); - - // initialize index + // destroy + initialize index - return this.init(); + return this.destroy().init(); }; /** @@ -1356,44 +1404,47 @@ // release references - this.filter = - this.stemmer = - this._scores = + //this.filter = + //this.stemmer = + //this._scores = this._map = this._ctx = this._ids = - this._stack = - this._stack_keys = null; + /*this._stack = + this._stack_keys =*/ null; return this; }; - /** - * @export - */ + if(SUPPORT_SERIALIZE){ + + /** + * @export + */ - FlexSearch.prototype.export = function(){ + FlexSearch.prototype.export = function(){ - return JSON.stringify([ + return JSON.stringify([ - this._map, - this._ctx, - this._ids - ]); - }; + this._map, + this._ctx, + this._ids + ]); + }; - /** - * @export - */ + /** + * @export + */ - FlexSearch.prototype.import = function(payload){ + FlexSearch.prototype.import = function(payload){ - payload = JSON.parse(payload); + payload = JSON.parse(payload); - this._map = payload[0]; - this._ctx = payload[1]; - this._ids = payload[2]; - }; + this._map = payload[0]; + this._ctx = payload[1]; + this._ids = payload[2]; + }; + } /** @const */ @@ -1641,6 +1692,7 @@ // Async Handler + /* const queue = SUPPORT_ASYNC ? (function(){ const stack = create_object(); @@ -1661,6 +1713,7 @@ }; })() : null; + */ // Flexi-Cache @@ -2578,6 +2631,7 @@ * @param {FlexSearch} ref */ + /* function runner(ref){ const async = ref.async; @@ -2637,11 +2691,13 @@ ref.async = async; } } + */ /** * @param {FlexSearch} ref */ + /* function register_task(ref){ ref._timer || ( @@ -2655,6 +2711,7 @@ }, 1, "@" + ref.id) ); } + */ /** * @returns {number} @@ -2704,7 +2761,7 @@ let id; /** @type {FlexSearch} */ - let flexsearch; + let FlexSearchWorker; /** @lends {Worker} */ self.onmessage = function(event){ @@ -2715,7 +2772,7 @@ if(data["search"]){ - const results = flexsearch["search"](data["content"], + const results = FlexSearchWorker["search"](data["content"], data["threshold"] ? @@ -2738,23 +2795,23 @@ } else if(data["add"]){ - flexsearch["add"](data["id"], data["content"]); + FlexSearchWorker["add"](data["id"], data["content"]); } else if(data["update"]){ - flexsearch["update"](data["id"], data["content"]); + FlexSearchWorker["update"](data["id"], data["content"]); } else if(data["remove"]){ - flexsearch["remove"](data["id"]); + FlexSearchWorker["remove"](data["id"]); } else if(data["clear"]){ - flexsearch["clear"](); + FlexSearchWorker["clear"](); } - else if(DEBUG && data["info"]){ + else if(SUPPORT_INFO && data["info"]){ - const info = flexsearch["info"](); + const info = FlexSearchWorker["info"](); info["worker"] = id; @@ -2768,10 +2825,10 @@ id = data["id"]; data["options"]["cache"] = false; - data["options"]["async"] = true; + data["options"]["async"] = false; data["options"]["worker"] = false; - flexsearch = new Function( + FlexSearchWorker = new Function( data["register"].substring( @@ -2780,7 +2837,7 @@ ) )(); - flexsearch = new flexsearch(data["options"]); + FlexSearchWorker = new FlexSearchWorker(data["options"]); } } }; @@ -2805,7 +2862,7 @@ options["id"] = core; - thread.postMessage(core, { + thread.postMessage({ "register": fnStr, "options": options, @@ -2814,7 +2871,7 @@ return thread; } - })( + }( // Worker Handler SUPPORT_WORKER ? (function register_worker(){ @@ -2857,6 +2914,8 @@ "var SUPPORT_ENCODER = " + (SUPPORT_ENCODER ? "true" : "false") + ";" + "var SUPPORT_CACHE = " + (SUPPORT_CACHE ? "true" : "false") + ";" + "var SUPPORT_ASYNC = " + (SUPPORT_ASYNC ? "true" : "false") + ";" + + "var SUPPORT_SERIALIZE = " + (SUPPORT_SERIALIZE ? "true" : "false") + ";" + + "var SUPPORT_INFO = " + (SUPPORT_INFO ? "true" : "false") + ";" + "var SUPPORT_WORKER = true;" ) + "(" + _worker.toString() + ")()" @@ -2881,18 +2940,12 @@ console.log("Register Worker: " + name + "@" + _core); } - return { - - "postMessage": function(id, data){ - - worker_stack[name][id]["postMessage"](data); - } - }; + return worker_stack[name][_core]; } ); - })() : false + }()) : false - ), this); + )), this); /** -------------------------------------------------------------------------------------- * UMD Wrapper for Browser and Node.js diff --git a/flexsearch.light.js b/flexsearch.light.js index 387a9ff..df824cd 100644 --- a/flexsearch.light.js +++ b/flexsearch.light.js @@ -1,18 +1,18 @@ /* - FlexSearch v0.3.3 + FlexSearch v0.3.5 Copyright 2019 Nextapps GmbH Author: Thomas Wilkerling Released under the Apache 2.0 Licence https://github.com/nextapps-de/flexsearch */ -'use strict';(function(e,u,v){let k;(k=v.define)&&k.amd?k([],function(){return u}):(k=v.modules)?k[e.toLowerCase()]=u:"object"===typeof exports?module.exports=u:v[e]=u})("FlexSearch",function(){function e(a){a||(a=x);this.id=a.id||G++;this.init(a);u(this,"index",function(){return this.a});u(this,"length",function(){return Object.keys(this.a).length})}function u(a,b,c){Object.defineProperty(a,b,{get:c})}function v(a,b){for(let c=0;c=g&&(a=a[9-(d+.5>>0)],a=a[c]||(a[c]=[]),a[a.length]=f);return d}function z(a,b){if(a){const c=Object.keys(a);for(let f=0,d=c.length;fa?1:a?-1:0}function I(a,b){a=a.length-b.length;return 0>a?-1:a?1:0}function y(a){return"function"===typeof a} -function A(a){return"undefined"===typeof a}function C(a){const b=Array(a);for(let c=0;ch;c--)g=f.substring(h,c),k(q,l,g,a,b,m,n)}break;default:if(d=k(q,l,f,a,1,m,n),t&&1=n)for(d=l._ctx[f]||(l._ctx[f]=r()),f=this.b[f]||(this.b[f]=C(10-(n||0))),m=e-t,g=e+t+1,0>m&&(m=0),g>p&&(g= -p);mb&&(e=e.slice(0,b)));d=e}return d}};e.prototype.clear=function(){this.destroy();return this.init()};e.prototype.destroy=function(){this.filter=this.stemmer=this.c=this.b= -this.a=null;return this};e.prototype.export=function(){return JSON.stringify([this.c,this.b,this.a])};e.prototype.import=function(a){a=JSON.parse(a);this.c=a[0];this.b=a[1];this.a=a[2]};const w={icase:function(a){return a.toLowerCase()}};return e}(!1),this); +'use strict';(function(e,u,v){let m;(m=v.define)&&m.amd?m([],function(){return u}):(m=v.modules)?m[e.toLowerCase()]=u:"object"===typeof exports?module.exports=u:v[e]=u})("FlexSearch",function(){function e(a){a||(a=x);this.id=a.id||G++;this.init(a);u(this,"index",function(){return this.a});u(this,"length",function(){return Object.keys(this.a).length})}function u(a,b,c){Object.defineProperty(a,b,{get:c})}function v(a,b){for(let c=0;c=g&&(a=a[9-(d+.5>>0)],a=a[c]||(a[c]=[]),a[a.length]=f);return d}function z(a,b){if(a){const c=Object.keys(a);for(let f=0,d=c.length;fa?1:a?-1:0}function I(a,b){a=a.length-b.length;return 0>a?-1:a?1:0}function y(a){return"function"===typeof a} +function A(a){return"undefined"===typeof a}function C(a){const b=Array(a);for(let c=0;ch;c--)l=n.substring(h,c),m(q,f,l,a,b,k,d)}break;default:if(g=m(q,f,n,a,1,k,d),t&&1=d)for(g=f._ctx[n]||(f._ctx[n]=r()),n=this.c[n]||(this.c[n]=C(10-(d|| +0))),k=e-t,l=e+t+1,0>k&&(k=0),l>p&&(l=p);kb&&(g=g.slice(0,b)));e=g}return e};e.prototype.clear=function(){return this.destroy().init()}; +e.prototype.destroy=function(){this.g=this.c=this.a=null;return this};const w={icase:function(a){return a.toLowerCase()}};return e}(!1),this); diff --git a/flexsearch.min.js b/flexsearch.min.js index d881c1f..f74dc17 100644 --- a/flexsearch.min.js +++ b/flexsearch.min.js @@ -1,30 +1,31 @@ /* - FlexSearch v0.3.3 + FlexSearch v0.3.5 Copyright 2019 Nextapps GmbH Author: Thomas Wilkerling Released under the Apache 2.0 Licence https://github.com/nextapps-de/flexsearch */ -'use strict';(function(t,A,g){let v;(v=g.define)&&v.amd?v([],function(){return A}):(v=g.modules)?v[t.toLowerCase()]=A:"object"===typeof exports?module.exports=A:g[t]=A})("FlexSearch",function P(t){function g(a){C(a)&&(a=I[a]);a||(a=w);this.id=a.id||Q++;this.init(a);v(this,"index",function(){return this.a});v(this,"length",function(){return Object.keys(this.a).length})}function v(a,b,d){Object.defineProperty(a,b,{get:d})}function e(a){return new RegExp(a,"g")}function x(a,b){for(let d=0;d=h&&(a=a[9-(f+.5>>0)],a=a[d]||(a[d]=[]),a[a.length]=c);return f}function q(a,b){if(a){const d=Object.keys(a);for(let c=0,f=d.length;ca?1:a?-1:0}function U(a,b){a=a.length-b.length;return 0>a?-1:a?1:0}function V(a,b,d){let c=[],f;const k=a.length;if(1b&&(c=c.slice(0,b)));return c}function C(a){return"string"===typeof a}function D(a){return"function"===typeof a}function z(a){return"undefined"===typeof a}function G(a){a.D||(a.D=K(function(){a.D=0;{const b=a.async;let d;b&&(a.async=!1);if(a.f.length){const b=Date.now();let f;for(;(f=a.f.shift())||0===f;){d=a.h[f];switch(d[0]){case E.add:a.add(d[1],d[2]);break;case E.remove:a.remove(d[1])}delete a.h[f]; -if(100=f&&(c.s=c.c),c.B&&c.s===c.c&&(c.cache&&c.j.set(b,c.i),c.B(c.i),c.i=[]),c})}else a.worker=!1,this.m=null;this.b=a.tokenize||d.b||this.b||w.b;this.async=z(b=a.async)?this.async||w.async:b;this.c=z(b=a.worker)?this.c||w.c:b;this.threshold=z(b=a.threshold)?d.threshold||this.threshold||w.threshold:b;this.depth=z(b=a.depth)?d.depth||this.depth||w.depth:b;this.v=z(b=a.suggest)?this.v||w.v:b;this.u=(b=z(b=a.encode)?d.encode:b)&&B[b]&&B[b].bind(B)|| -(D(b)?b:this.u||!1);(b=a.matcher)&&this.addMatcher(b);if(b=a.filter)this.filter=R(N[b]||b,this.u);if(b=a.stemmer)this.stemmer=S(O[b]||b,this.u);this.l=L(10-(this.threshold||0));this.g=n();this.a=n();this.h=n();this.f=[];this.D=0;this.w=!0;this.j=(this.cache=b=z(b=a.cache)?this.cache||w.cache:b)?new X(b):!1;return this};g.prototype.encode=function(a){a&&H.length&&(a=x(a,H));a&&this.C.length&&(a=x(a,this.C));a&&this.u&&(a=this.u(a));a&&this.stemmer&&(a=x(a,this.stemmer));return a};g.prototype.addMatcher= -function(a){const b=this.C;for(const d in a)a.hasOwnProperty(d)&&b.push(e(d),a[d]);return this};g.prototype.add=function(a,b,d){if(b&&C(b)&&(a||0===a)){const k="@"+a;if(this.a[k]&&!d)this.update(a,b);else{if(this.c)return++this.o>=this.m.length&&(this.o=0),this.m[this.o].postMessage(this.o,{add:!0,id:a,content:b}),this.a[k]=""+this.o,this;if(this.async)return this.h[k]||(this.f[this.f.length]=k),this.h[k]=[E.add,a,b],G(this),this;b=this.encode(b);if(!b.length)return this;d=this.b;b=D(d)?d(b):b.split(M); -const u=n();u._ctx=n();const p=this.threshold,r=this.depth,l=this.l,m=b.length;for(let k=0;kg;d--)h=c.substring(g,d),y(l,u,h,a,b,e,p)}break;default:if(f=y(l,u,c,a,1,e,p),r&&1=p)for(f=u._ctx[c]||(u._ctx[c]=n()),c=this.g[c]|| -(this.g[c]=L(10-(p||0))),e=k-r,h=k+r+1,0>e&&(e=0),h>m&&(h=m);ed;c--)f=e[c-1],e[c]=f,b[f]=c;e[d]=a;b[a]=d}}}return b};return a}();return g}(function(){const t={},A="undefined"!==typeof Blob&&"undefined"!==typeof URL&&URL.createObjectURL;return function(g,v,e,x,y){let q=g;g=A?URL.createObjectURL(new Blob(["("+e.toString()+")()"],{type:"text/javascript"})):q+".min.js";q+="-"+v;t[q]||(t[q]=[]);t[q][y]=new Worker(g);t[q][y].onmessage= -x;return{postMessage:function(e,g){t[q][e].postMessage(g)}}}}()),this); +'use strict';(function(u,B,g){let v;(v=g.define)&&v.amd?v([],function(){return B}):(v=g.modules)?v[u.toLowerCase()]=B:"object"===typeof exports?module.exports=B:g[u]=B})("FlexSearch",function O(u){function g(a){E(a)&&(a=J[a]);a||(a=w);this.id=a.id||P++;this.init(a);v(this,"index",function(){return this.a});v(this,"length",function(){return Object.keys(this.a).length})}function v(a,b,c){Object.defineProperty(a,b,{get:c})}function e(a){return new RegExp(a,"g")}function x(a,b){for(let c=0;c=h&&(a=a[9-(f+.5>>0)],a=a[c]||(a[c]=[]),a[a.length]=d);return f}function H(a,b){if(a){const c=Object.keys(a);for(let d=0,f=c.length;da?1:a?-1:0}function T(a,b){a=a.length-b.length;return 0>a?-1:a?1:0}function U(a,b,c){let d=[],f;const l=a.length;if(1b&&(d=d.slice(0,b)));return d}function E(a){return"string"===typeof a}function F(a){return"function"===typeof a}function A(a){return"undefined"===typeof a}function K(a){const b=Array(a);for(let c=0;c=f&&(c.o=c.c),c.B&&c.o===c.c&&(c.cache&&c.j.set(b,c.h),c.B(c.h),c.h=[]),c})}else a.worker=!1,this.i=null;this.b=a.tokenize||c.b||this.b||w.b;this.async="undefined"===typeof Promise||A(b=a.async)?this.async|| +w.async:b;this.c=A(b=a.worker)?this.c||w.c:b;this.threshold=A(b=a.threshold)?c.threshold||this.threshold||w.threshold:b;this.depth=A(b=a.depth)?c.depth||this.depth||w.depth:b;this.u=A(b=a.suggest)?this.u||w.u:b;this.s=(b=A(b=a.encode)?c.encode:b)&&D[b]&&D[b].bind(D)||(F(b)?b:this.s||!1);(b=a.matcher)&&this.addMatcher(b);if(b=a.filter)this.filter=Q(M[b]||b,this.s);if(b=a.stemmer)this.stemmer=R(N[b]||b,this.s);this.f=K(10-(this.threshold||0));this.g=r();this.a=r();this.v=!0;this.j=(this.cache=b=A(b= +a.cache)?this.cache||w.cache:b)?new W(b):!1;return this};g.prototype.encode=function(a){a&&G.length&&(a=x(a,G));a&&this.m.length&&(a=x(a,this.m));a&&this.s&&(a=this.s(a));a&&this.stemmer&&(a=x(a,this.stemmer));return a};g.prototype.addMatcher=function(a){const b=this.m;for(const c in a)a.hasOwnProperty(c)&&b.push(e(c),a[c]);return this};g.prototype.add=function(a,b,c,d,f){if(b&&E(b)&&(a||0===a)){var e="@"+a;if(this.a[e]&&!d)return this.update(a,b);if(this.c)return++this.w>=this.i.length&&(this.w= +0),this.i[this.w].postMessage({add:!0,id:a,content:b}),this.a[e]=""+this.w,c&&c(),this;if(!f){if(this.async&&"function"!==typeof importScripts){let f=this;e=new Promise(function(c){setTimeout(function(){f.add(a,b,null,d,!0);f=null;c()})});if(c)e.then(c);else return e;return this}if(c)return this.add(a,b,null,d,!0),c(),this}b=this.encode(b);if(!b.length)return this;c=this.b;f=F(c)?c(b):b.split(L);const l=r();l._ctx=r();const p=this.threshold,t=this.depth,z=this.f,C=f.length;for(let b=0;bk;c--)n=h.substring(k,c),y(z,l,n,a,b,m,p)}break;default:if(g=y(z,l,h,a,1,m,p),t&&1=p)for(g=l._ctx[h]||(l._ctx[h]=r()),h=this.g[h]||(this.g[h]=K(10-(p||0))),m=b-t,n=b+t+1,0>m&&(m=0),n>C&&(n=C);mc;d--)f=e[d-1],e[d]=f,b[f]=d;e[c]=a;b[a]=c}}}return b};return a}();return g}(function(){const u={},B="undefined"!==typeof Blob&&"undefined"!==typeof URL&&URL.createObjectURL;return function(g,v,e,x,y){e=B?URL.createObjectURL(new Blob(["("+e.toString()+")()"],{type:"text/javascript"})):g+".min.js";g+="-"+v;u[g]||(u[g]=[]);u[g][y]=new Worker(e);u[g][y].onmessage=x;return u[g][y]}}()), +this); diff --git a/package.json b/package.json index 4e92d51..11f8519 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "flexsearch", - "version": "0.3.3", + "version": "0.3.5", "description": "Next-Generation full text search library with zero dependencies.", "homepage": "https://github.com/nextapps-de/flexsearch/", "author": "Thomas Wilkerling", @@ -25,11 +25,11 @@ "url": "https://github.com/nextapps-de/flexsearch.git" }, "scripts": { - "build": "node compile RELEASE=min DEBUG=false PROFILER=false SUPPORT_WORKER=true SUPPORT_ENCODER=true SUPPORT_CACHE=true SUPPORT_ASYNC=true SUPPORT_PRESETS=true SUPPORT_SUGGESTIONS=true SUPPORT_LANG_DE=false SUPPORT_LANG_EN=false", - "build-light": "node compile RELEASE=light DEBUG=false PROFILER=false SUPPORT_WORKER=false SUPPORT_ENCODER=false SUPPORT_CACHE=false SUPPORT_ASYNC=false SUPPORT_PRESETS=false SUPPORT_SUGGESTIONS=false SUPPORT_LANG_DE=false SUPPORT_LANG_EN=false", - "build-compact": "node compile RELEASE=compact DEBUG=false PROFILER=false SUPPORT_WORKER=false SUPPORT_ENCODER=true SUPPORT_CACHE=false SUPPORT_ASYNC=true SUPPORT_PRESETS=true SUPPORT_SUGGESTIONS=false SUPPORT_LANG_DE=false SUPPORT_LANG_EN=false", - "build-custom": "node compile RELEASE=custom DEBUG=false PROFILER=false SUPPORT_WORKER=false SUPPORT_ENCODER=false SUPPORT_CACHE=false SUPPORT_ASYNC=false SUPPORT_PRESETS=false SUPPORT_SUGGESTIONS=false SUPPORT_LANG_DE=false SUPPORT_LANG_EN=false", - "build-es5": "node compile RELEASE=es5 DEBUG=false PROFILER=false SUPPORT_WORKER=true SUPPORT_ENCODER=true SUPPORT_CACHE=true SUPPORT_ASYNC=true SUPPORT_PRESETS=true SUPPORT_SUGGESTIONS=true SUPPORT_LANG_DE=false SUPPORT_LANG_EN=false LANGUAGE_OUT=ECMASCRIPT5_STRICT", + "build": "node compile RELEASE=min DEBUG=false PROFILER=false SUPPORT_WORKER=true SUPPORT_ENCODER=true SUPPORT_CACHE=true SUPPORT_ASYNC=true SUPPORT_PRESETS=true SUPPORT_SUGGESTIONS=true SUPPORT_SERIALIZE=true SUPPORT_INFO=true SUPPORT_LANG_DE=false SUPPORT_LANG_EN=false", + "build-light": "node compile RELEASE=light DEBUG=false PROFILER=false SUPPORT_WORKER=false SUPPORT_ENCODER=false SUPPORT_CACHE=false SUPPORT_ASYNC=false SUPPORT_PRESETS=false SUPPORT_SUGGESTIONS=false SUPPORT_SERIALIZE=false SUPPORT_INFO=false SUPPORT_LANG_DE=false SUPPORT_LANG_EN=false", + "build-compact": "node compile RELEASE=compact DEBUG=false PROFILER=false SUPPORT_WORKER=false SUPPORT_ENCODER=true SUPPORT_CACHE=false SUPPORT_ASYNC=true SUPPORT_PRESETS=true SUPPORT_SUGGESTIONS=false SUPPORT_SERIALIZE=false SUPPORT_INFO=false SUPPORT_LANG_DE=false SUPPORT_LANG_EN=false", + "build-custom": "node compile RELEASE=custom DEBUG=false PROFILER=false SUPPORT_WORKER=false SUPPORT_ENCODER=false SUPPORT_CACHE=false SUPPORT_ASYNC=false SUPPORT_PRESETS=false SUPPORT_SUGGESTIONS=false SUPPORT_SERIALIZE=false SUPPORT_INFO=false SUPPORT_LANG_DE=false SUPPORT_LANG_EN=false", + "build-es5": "node compile RELEASE=es5 DEBUG=true PROFILER=false SUPPORT_WORKER=true SUPPORT_ENCODER=true SUPPORT_CACHE=true SUPPORT_ASYNC=true SUPPORT_PRESETS=true SUPPORT_SUGGESTIONS=true SUPPORT_SERIALIZE=true SUPPORT_INFO=true SUPPORT_LANG_DE=false SUPPORT_LANG_EN=false LANGUAGE_OUT=ECMASCRIPT5_STRICT", "build-lang": "node compile RELEASE=lang", "build-all": "npm run build && npm run build-light && npm run build-compact && npm run build-es5 && npm run build-lang", "test-production": "nyc --reporter=html --reporter=text mocha --timeout=3000 test --exit", @@ -42,7 +42,6 @@ }, "files": [ "flexsearch.js", - "flexsearch.min.js", "lang/", "test/", "compile.js", diff --git a/test/flexsearch.es5.js b/test/flexsearch.es5.js index 33058b1..26a26c4 100644 --- a/test/flexsearch.es5.js +++ b/test/flexsearch.es5.js @@ -1,36 +1,37 @@ /* - FlexSearch v0.3.3 + FlexSearch v0.3.5 Copyright 2019 Nextapps GmbH Author: Thomas Wilkerling Released under the Apache 2.0 Licence https://github.com/nextapps-de/flexsearch */ -'use strict';function I(g){var h=0;return function(){return h=e&&(b=b[9-(d+.5>>0)],b=b[a]||(b[a]=[]),b[b.length]=f);return d}function l(b,c){if(b)for(var a=Object.keys(b),f=0,d=a.length;fb?1:b?-1:0}function V(b,c){b= -b.length-c.length;return 0>b?-1:b?1:0}function W(b,c,a){var f=[],d=b.length;if(1c&&(f=f.slice(0,c)));return f}function G(b){return"string"===typeof b}function F(b){return"function"===typeof b}function x(b){return"undefined"===typeof b}function D(b){b.F||(b.F=M(function(){b.F=0;var c=b.async;c&&(b.async=!1);if(b.b.length){for(var a=Date.now(),f;(f=b.b.shift())||0===f;){var d=b.f[f];switch(d[0]){case E.add:b.add(d[1],d[2]);break;case E.remove:b.remove(d[1])}delete b.f[f];if(100=d&&(f.s=f.i),f.C&& -f.s===f.i&&(f.cache&&f.j.set(c,f.g),f.C(f.g),f.g=[]),f})}else b.worker=!1,this.m=null;this.h=b.tokenize||a.h||this.h||u.h;this.async=x(c=b.async)?this.async||u.async:c;this.i=x(c=b.worker)?this.i||u.i:c;this.threshold=x(c=b.threshold)?a.threshold||this.threshold||u.threshold:c;this.depth=x(c=b.depth)?a.depth||this.depth||u.depth:c;this.w=x(c=b.suggest)?this.w||u.w:c;this.u=(c=x(c=b.encode)?a.encode:c)&&B[c]&&B[c].bind(B)||(F(c)?c:this.u||!1);(c=b.matcher)&&this.addMatcher(c);if(c=b.filter)this.filter= -C(P[c]||c,this.u);if(c=b.stemmer)this.stemmer=U(Q[c]||c,this.u);this.l=N(10-(this.threshold||0));this.c=v();this.a=v();this.f=v();this.b=[];this.F=0;this.v=!0;this.j=(this.cache=c=x(c=b.cache)?this.cache||u.cache:c)?new ba(c):!1;return this};e.prototype.encode=function(b){b&&H.length&&(b=m(b,H));b&&this.D.length&&(b=m(b,this.D));b&&this.u&&(b=this.u(b));b&&this.stemmer&&(b=m(b,this.stemmer));return b};e.prototype.addMatcher=function(b){var c=this.D,d;for(d in b)b.hasOwnProperty(d)&&c.push(a(d),b[d]); -return this};e.prototype.add=function(b,c,a){if(c&&G(c)&&(b||0===b)){var f="@"+b;if(this.a[f]&&!a)this.update(b,c);else{if(this.i)return++this.o>=this.m.length&&(this.o=0),this.m[this.o].postMessage(this.o,{add:!0,id:b,content:c}),this.a[f]=""+this.o,this;if(this.async)return this.f[f]||(this.b[this.b.length]=f),this.f[f]=[E.add,b,c],D(this),this;c=this.encode(c);if(!c.length)return this;a=this.h;c=F(a)?a(c):c.split(O);var e=v();e._ctx=v();for(var g=this.threshold,k=this.depth,w=this.l,m=c.length, -l=0;ln;z--)t=r.substring(n,z),d(w,e,t,b,y,q,g);break;default:if(p=d(w,e,r,b,1,q,g),k&&1=g)for(p=e._ctx[r]||(e._ctx[r]=v()),r=this.c[r]||(this.c[r]=N(10-(g||0))),q=l-k,t=l+k+1,0>q&&(q=0),t>m&&(t=m);qe;c--)k=g[c-1],g[c]=k,d[k]=c;g[e]=a;d[a]=e}}}return b};return a}();return e}(function(){var g={},h="undefined"!==typeof Blob&&"undefined"!==typeof URL&&URL.createObjectURL;return function(e,k,a,m,d){var l=e;e=h?URL.createObjectURL(new Blob(["("+a.toString()+")()"],{type:"text/javascript"})):l+".es5.js";l+="-"+k;g[l]||(g[l]=[]);g[l][d]=new Worker(e);g[l][d].onmessage=m;return{postMessage:function(a,d){g[l][a].postMessage(d)}}}}()),this); +'use strict';function I(g){var k=0;return function(){return k=e&&(b=b[9-(d+.5>>0)],b=b[a]||(b[a]=[]),b[b.length]=f);return d}function G(b,c){if(b)for(var a=Object.keys(b),f=0,d=a.length;fb?1:b?-1:0}function U(b,c){b=b.length-c.length;return 0>b?-1:b?1:0}function V(b,c,a){var f=[],d=b.length;if(1c&&(f=f.slice(0,c)));return f}function E(b){return"string"===typeof b}function C(b){return"function"===typeof b}function w(b){return"undefined"===typeof b}function M(b){for(var c=Array(b),a=0;a=d&&(f.m=f.i),f.w&&f.m===f.i&&(f.cache&&f.j.set(c,f.f),f.w(f.f),f.f=[]),f})}else b.worker=!1,this.g=null;this.h=b.tokenize||a.h||this.h||x.h;this.async="undefined"===typeof Promise||w(c=b.async)?this.async||x.async:c; +this.i=w(c=b.worker)?this.i||x.i:c;this.threshold=w(c=b.threshold)?a.threshold||this.threshold||x.threshold:c;this.depth=w(c=b.depth)?a.depth||this.depth||x.depth:c;this.A=w(c=b.suggest)?this.A||x.A:c;this.o=(c=w(c=b.encode)?a.encode:c)&&B[c]&&B[c].bind(B)||(C(c)?c:this.o||!1);(c=b.matcher)&&this.addMatcher(c);if(c=b.filter)this.filter=D(O[c]||c,this.o);if(c=b.stemmer)this.stemmer=T(P[c]||c,this.o);this.b=M(10-(this.threshold||0));this.c=y();this.a=y();this.u=!0;this.j=(this.cache=c=w(c=b.cache)? +this.cache||x.cache:c)?new aa(c):!1;return this};e.prototype.encode=function(b){b&&F.length&&(b=l(b,F));b&&this.l.length&&(b=l(b,this.l));b&&this.o&&(b=this.o(b));b&&this.stemmer&&(b=l(b,this.stemmer));return b};e.prototype.addMatcher=function(b){var c=this.l,d;for(d in b)b.hasOwnProperty(d)&&c.push(a(d),b[d]);return this};e.prototype.add=function(b,c,a,f,e){if(c&&E(c)&&(b||0===b)){var g="@"+b;if(this.a[g]&&!f)return this.update(b,c);if(this.i)return++this.v>=this.g.length&&(this.v=0),this.g[this.v].postMessage({add:!0, +id:b,content:c}),this.a[g]=""+this.v,a&&a(),this;if(!e){if(this.async&&"function"!==typeof importScripts){var z=this;g=new Promise(function(a){setTimeout(function(){z.add(b,c,null,f,!0);z=null;a()})});if(a)g.then(a);else return g;return this}if(a)return this.add(b,c,null,f,!0),a(),this}c=this.encode(c);if(!c.length)return this;a=this.h;e=C(a)?a(c):c.split(N);var h=y();h._ctx=y();for(var l=this.threshold,H=this.depth,q=this.b,t=e.length,r=0;rv;w--)p=u.substring(v,w),d(q,h,p,b,x,m,l);break;default:if(n=d(q,h,u,b,1,m,l),H&&1=l)for(n=h._ctx[u]||(h._ctx[u]=y()),u=this.c[u]||(this.c[u]=M(10-(l||0))),m=r-H,p=r+H+1,0>m&&(m=0),p>t&&(p=t);me;c--)h=g[c-1],g[c]=h,d[h]= +c;g[e]=a;d[a]=e}}}return b};return a}();return e}(function(){var g={},k="undefined"!==typeof Blob&&"undefined"!==typeof URL&&URL.createObjectURL;return function(e,h,a,l,d){a=k?URL.createObjectURL(new Blob(["("+a.toString()+")()"],{type:"text/javascript"})):e+".es5.js";e+="-"+h;g[e]||(g[e]=[]);g[e][d]=new Worker(a);g[e][d].onmessage=l;console.log("Register Worker: "+e+"@"+d);return g[e][d]}}()),this); diff --git a/test/test.js b/test/test.js index 1047181..6e6f2fa 100644 --- a/test/test.js +++ b/test/test.js @@ -396,6 +396,8 @@ if(env !== "light"){ it("Should have been added to the index", function(done){ + expect(flexsearch_async.length).to.equal(0); + flexsearch_async.add(0, "foo"); flexsearch_async.add(2, "bar"); flexsearch_async.add(1, "foobar"); @@ -422,8 +424,7 @@ if(env !== "light"){ flexsearch_async.add(3, false); flexsearch_async.add(3, []); flexsearch_async.add(3, {}); - flexsearch_async.add(3, function(){ - }); + flexsearch_async.add(3, function(){}); setTimeout(function(){ @@ -453,14 +454,9 @@ if(env !== "light"){ flexsearch_async.search("foobar", function(result){ expect(result).to.include(1); - }); - - // (async function(){ - // - // expect(await flexsearch_async.search("foo")).to.have.members([0, 1]); - // })(); - setTimeout(done, 25); + done(); + }); }); it("Should have been limited", function(done){ @@ -469,9 +465,9 @@ if(env !== "light"){ expect(result).to.include(0); expect(result).to.not.include(1); - }); - setTimeout(done, 25); + done(); + }); }); it("Should not have been matched from index", function(done){ @@ -494,9 +490,9 @@ if(env !== "light"){ flexsearch_async.search(" o ", function(result){ expect(result).to.have.lengthOf(0); - }); - setTimeout(done, 25); + done(); + }); }); }); @@ -508,24 +504,6 @@ if(env !== "light"){ flexsearch_async.update(2, "foobar"); flexsearch_async.update(1, "foo"); - expect(flexsearch_async.length).to.equal(3); - - flexsearch_async.search("foo").then(function(result){ - expect(result).to.not.have.members([2, 1]); - }); - - flexsearch_async.search("bar").then(function(result){ - expect(result).to.not.include(0); - }); - - flexsearch_async.search("bar").then(function(result){ - expect(result).to.include(2); - }); - - flexsearch_async.search("foobar").then(function(result){ - expect(result).to.not.include(2); - }); - setTimeout(function(){ expect(flexsearch_async.length).to.equal(3); @@ -544,9 +522,9 @@ if(env !== "light"){ flexsearch_async.search("foobar", function(result){ expect(result).to.include(2); - }); - done(); + done(); + }); }, 25); }); @@ -581,9 +559,9 @@ if(env !== "light"){ flexsearch_async.search("foobar").then(function(result){ expect(result).to.include(2); - }); - done(); + done(); + }); }, 25); }); @@ -595,29 +573,25 @@ if(env !== "light"){ flexsearch_async.remove(0); flexsearch_async.remove(2); - flexsearch_async.remove(1); + flexsearch_async.remove(1).then(function(){ + expect(flexsearch_async.length).to.equal(0); + }); expect(flexsearch_async.length).to.equal(3); - setTimeout(function(){ - - expect(flexsearch_async.length).to.equal(0); - - flexsearch_async.search("foo", function(result){ - expect(result).to.have.lengthOf(0); - }); + flexsearch_async.search("foo", function(result){ + expect(result).to.have.lengthOf(0); + }); - flexsearch_async.search("bar", function(result){ - expect(result).to.have.lengthOf(0); - }); + flexsearch_async.search("bar", function(result){ + expect(result).to.have.lengthOf(0); + }); - flexsearch_async.search("foobar", function(result){ - expect(result).to.have.lengthOf(0); - }); + flexsearch_async.search("foobar", function(result){ + expect(result).to.have.lengthOf(0); done(); - - }, 25); + }); }); }); @@ -625,176 +599,169 @@ if(env !== "light"){ // Worker Tests // ------------------------------------------------------------------------ - describe("Add (Worker)", function(){ + if(typeof Worker !== "undefined" && !this._phantom){ - it("Should support worker", function(){ + describe("Add (Worker)", function(){ - if(typeof Worker === "undefined"){ + it("Should support worker", function(){ - Worker = function(){}; - - Worker.prototype.postMessage = function(val){ - this.onmessage(val); - }; - Worker.prototype.onmessage = function(val){ - return val; - }; - } - - flexsearch_worker = new FlexSearch({ + flexsearch_worker = new FlexSearch({ - encode: "icase", - tokenize: "strict", - async: false, - worker: 4 + encode: "icase", + tokenize: "reverse", + async: false, + worker: 4 + }); }); - }); - it("Should have been added to the index", function(done){ + it("Should have been added to the index", function(done){ - flexsearch_worker.add(0, "foo"); - flexsearch_worker.add(2, "bar"); - flexsearch_worker.add(1, "foobar"); + flexsearch_worker.add(0, "foo"); + flexsearch_worker.add(2, "bar"); + flexsearch_worker.add(1, "foobar"); - expect(flexsearch_worker.length).to.equal(3); - expect(flexsearch_worker.index).to.have.keys(["@0", "@1", "@2"]); + setTimeout(function(){ - flexsearch_worker.search("foo", function(result){ + expect(flexsearch_worker.length).to.equal(3); + expect(flexsearch_worker.index).to.have.keys(["@0", "@1", "@2"]); - expect(result).to.have.length(0); - }); + flexsearch_worker.search("foo", function(result){ - setTimeout(done, 25); - }); + expect(result).to.have.length(2); + expect(result).to.have.members([0, 1]); - it("Should not have been added to the index", function(done){ + done(); + }); - flexsearch_worker.add("foo"); - flexsearch_worker.add(3); - flexsearch_worker.add(null, "foobar"); - flexsearch_worker.add(void 0, "foobar"); - flexsearch_worker.add(4, null); - flexsearch_worker.add(5, false); - flexsearch_worker.add(6, []); - flexsearch_worker.add(7, {}); - flexsearch_worker.add(8, function(){}); + }, 25); + }); - setTimeout(function(){ + it("Should not have been added to the index", function(done){ + + flexsearch_worker.add("foo"); + flexsearch_worker.add(3); + flexsearch_worker.add(null, "foobar"); + flexsearch_worker.add(void 0, "foobar"); + flexsearch_worker.add(4, null); + flexsearch_worker.add(5, false); + flexsearch_worker.add(6, []); + flexsearch_worker.add(7, {}); + flexsearch_worker.add(8, function(){ + }); - expect(flexsearch_worker.length).to.equal(3); - expect(flexsearch_worker.index).to.have.keys(["@0", "@1", "@2"]); + setTimeout(function(){ - done(); + expect(flexsearch_worker.length).to.equal(3); + expect(flexsearch_worker.index).to.have.keys(["@0", "@1", "@2"]); - }, 25); + done(); + + }, 25); + }); }); - }); - describe("Search (Worker)", function(){ + describe("Search (Worker)", function(){ - it("Should have been matched from index", function(done){ + it("Should have been matched from index", function(done){ - flexsearch_worker.search("foo", function(result){ + flexsearch_worker.search("foo", function(result){ - expect(result).to.have.lengthOf(2); - }); + expect(result).to.have.lengthOf(2); - flexsearch_worker.search("bar", function(result){ + flexsearch_worker.search("bar", function(result){ - expect(result).to.have.lengthOf(2); - }); + expect(result).to.have.lengthOf(2); - flexsearch_worker.search("foobar", function(result){ + flexsearch_worker.search("foobar", function(result){ - expect(result).to.have.lengthOf(1); + expect(result).to.have.lengthOf(1); + + done(); + }); + }); + }); }); - setTimeout(done, 25); - }); + it("Should have been limited", function(done){ - it("Should have been limited", function(done){ + flexsearch_worker.search("foo", 1, function(result){ - flexsearch_worker.search("foo", 1, function(result){ + expect(result).to.have.lengthOf(1); - expect(result).to.include(0); - expect(result).to.not.include(1); + done(); + }); }); - setTimeout(done, 25); - }); + it("Should not have been matched from index", function(done){ - it("Should not have been matched from index", function(done){ + flexsearch_worker.search("barfoo", function(result){ - flexsearch_worker.search("barfoo", function(result){ + expect(result).to.have.lengthOf(0); - expect(result).to.have.lengthOf(0); - }); + flexsearch_worker.search("", function(result){ - flexsearch_worker.search("", function(result){ + expect(result).to.have.lengthOf(0); - expect(result).to.have.lengthOf(0); - }); + flexsearch_worker.search(" ", function(result){ - flexsearch_worker.search(" ", function(result){ + expect(result).to.have.lengthOf(0); - expect(result).to.have.lengthOf(0); - }); + flexsearch_worker.search(" o ", function(result){ - flexsearch_worker.search(" o ", function(result){ + expect(result).to.have.lengthOf(1); - expect(result).to.have.lengthOf(0); - }); + flexsearch_worker.search(" fob ", function(result){ + + expect(result).to.have.lengthOf(0); - setTimeout(done, 25); + done(); + }); + }); + }); + }); + }); + }); }); - }); - // TODO: - /* - describe("Update (Worker)", function(){ + describe("Update (Worker)", function(){ - it("Should have been updated to the index", function(done){ + it("Should have been updated to the index", function(done){ - flexsearch_worker.update(0, "bar"); - flexsearch_worker.update(2, "foobar"); - flexsearch_worker.update(1, "foo"); + flexsearch_worker.update(0, "bar"); + flexsearch_worker.update(2, "foobar"); + flexsearch_worker.update(1, "foo", function(){ - setTimeout(function(){ + expect(flexsearch_worker.length).to.equal(3); - expect(flexsearch_worker.length).to.equal(3); + flexsearch_worker.search("foo", function(results){ - flexsearch_worker.search("foo", function(results){ + expect(results).to.have.members([2, 1]); - expect(results).to.have.members([2, 1]); - }); + flexsearch_worker.search("bar", function(results){ - flexsearch_worker.search("bar", function(results){ + expect(results).to.have.members([0, 2]); - expect(results).to.have.members([0, 2]); - }); + flexsearch_worker.search("foobar", function(results){ - flexsearch_worker.search("foobar", function(results){ + expect(results).to.have.members([2]); - expect(results).to.have.members([2]); + done(); + }); + }); + }); }); - - setTimeout(done, 25); - }, 25); + }); }); - }); - */ - describe("Remove (Worker)", function(){ - - it("Should have been removed from the index", function(done){ + describe("Remove (Worker)", function(){ - expect(flexsearch_worker.length).to.equal(3); + it("Should have been removed from the index", function(done){ - flexsearch_worker.remove(0); - flexsearch_worker.remove(2); - flexsearch_worker.remove(1); + expect(flexsearch_worker.length).to.equal(3); - setTimeout(function(){ + flexsearch_worker.remove(0); + flexsearch_worker.remove(2); + flexsearch_worker.remove(1); expect(flexsearch_worker.length).to.equal(0); @@ -802,31 +769,31 @@ if(env !== "light"){ expect(results).to.not.include(1); expect(results).to.not.include(2); - }); - flexsearch_worker.search("bar", function(results){ + flexsearch_worker.search("bar", function(results){ - expect(results).to.not.include(0); - expect(results).to.not.include(2); - }); + expect(results).to.not.include(0); + expect(results).to.not.include(2); - flexsearch_worker.search("foobar", function(results){ + flexsearch_worker.search("foobar", function(results){ - expect(results).to.not.include(2); - }); + expect(results).to.not.include(2); - setTimeout(done, 25); - }, 25); - }); + done(); + }); + }); + }); + }); - if(env !== "light" && env !== "min"){ + if(env !== "light" && env !== "min"){ - it("Should have been debug mode activated", function(){ + it("Should have been debug mode activated", function(){ - flexsearch_worker.info(); - }); - } - }); + flexsearch_worker.info(); + }); + } + }); + } describe("Worker Not Supported", function(){ @@ -840,7 +807,7 @@ if(env !== "light"){ flexsearch_worker = new FlexSearch({ encode: false, - async: true, + async: false, worker: 4 });