flexsearch
Advanced tools
Comparing version 0.1.27 to 0.1.28
@@ -6,3 +6,3 @@ /**! | ||
* @preserve https://github.com/nextapps-de/flexsearch | ||
* @version: 0.1.27 | ||
* @version: 0.1.28 | ||
* @license: Apache 2.0 Licence | ||
@@ -32,5 +32,2 @@ */ | ||
// boolean model of multiple words | ||
boolean: false, | ||
// use flexible cache (scales automatically) | ||
@@ -45,2 +42,5 @@ cache: false, | ||
// minimum scoring (0 - 9) | ||
threshold: 0, | ||
// use on of built-in functions | ||
@@ -80,5 +80,2 @@ // or pass custom encoding algorithm | ||
/** @const {RegExp} */ | ||
//var regex_syllables = new RegExp("[^aeiouy]*[aeiouy]+", "g"); | ||
/** @const {RegExp} */ | ||
var regex_split = regex("[ -\/]"); | ||
@@ -167,2 +164,4 @@ | ||
} | ||
return this; | ||
}; | ||
@@ -179,2 +178,4 @@ | ||
global_encoder[name] = encoder; | ||
return this; | ||
}; | ||
@@ -184,4 +185,4 @@ | ||
* @param {!string} name | ||
* @param {!string} value | ||
* @returns {string} | ||
* @param {?string} value | ||
* @returns {?string} | ||
* @export | ||
@@ -214,2 +215,4 @@ */ | ||
options['worker'] = false; | ||
options['async'] = true; | ||
this._worker = null; | ||
@@ -273,3 +276,2 @@ } | ||
/** @export */ | ||
this.mode = ( | ||
@@ -282,11 +284,2 @@ | ||
/** @export */ | ||
this.boolean = ( | ||
options['boolean'] === 'or' || | ||
this.boolean || | ||
defaults.boolean | ||
); | ||
/** @export */ | ||
this.cache = ( | ||
@@ -299,3 +292,2 @@ | ||
/** @export */ | ||
this.async = ( | ||
@@ -308,3 +300,2 @@ | ||
/** @export */ | ||
this.worker = ( | ||
@@ -317,2 +308,9 @@ | ||
this.threshold = ( | ||
options['threshold'] || | ||
this.threshold || | ||
defaults.threshold | ||
); | ||
/** @export */ | ||
@@ -323,7 +321,6 @@ this.encoder = ( | ||
this.encoder || | ||
(defaults.encode && global_encoder[defaults.encode]) || | ||
//(defaults.encode && global_encoder[defaults.encode]) || | ||
options['encode'] | ||
); | ||
/** @export */ | ||
this.debug = ( | ||
@@ -384,7 +381,9 @@ | ||
false; | ||
return this; | ||
}; | ||
/** | ||
* @param {!string} value | ||
* @returns {string} | ||
* @param {?string} value | ||
* @returns {?string} | ||
* @export | ||
@@ -395,15 +394,15 @@ */ | ||
if(this.encoder){ | ||
if(value && global_matcher.length){ | ||
value = this.encoder(value); | ||
value = replace(value, global_matcher); | ||
} | ||
if(global_matcher.length){ | ||
if(value && this._matcher.length){ | ||
value = replace(value, global_matcher); | ||
value = replace(value, this._matcher); | ||
} | ||
if(this._matcher.length){ | ||
if(value && this.encoder){ | ||
value = replace(value, this._matcher); | ||
value = this.encoder(value); | ||
} | ||
@@ -429,7 +428,9 @@ | ||
} | ||
return this; | ||
}; | ||
/** | ||
* @param {!number|string} id | ||
* @param {!string} content | ||
* @param {?number|string} id | ||
* @param {?string} content | ||
* @this {FlexSearch} | ||
@@ -464,3 +465,3 @@ * @export | ||
return; | ||
return this; | ||
} | ||
@@ -484,13 +485,10 @@ | ||
return; | ||
return this; | ||
} | ||
if(content && this.encode){ | ||
content = this.encode(content); | ||
content = this.encode(content); | ||
} | ||
if(!content.length){ | ||
if(!content){ | ||
return; | ||
return this; | ||
} | ||
@@ -501,7 +499,7 @@ | ||
this.encoder === global_encoder['ngram'] ? | ||
content.constructor === Array ? | ||
content | ||
/** @type {!Array<string>} */ (content) | ||
: | ||
content.split(regex_split) | ||
/** @type {string} */ (content).split(regex_split) | ||
); | ||
@@ -535,3 +533,4 @@ | ||
id, | ||
content | ||
content, | ||
this.threshold | ||
); | ||
@@ -556,3 +555,4 @@ } | ||
id, | ||
content | ||
content, | ||
this.threshold | ||
); | ||
@@ -579,3 +579,4 @@ } | ||
id, | ||
content | ||
content, | ||
this.threshold | ||
); | ||
@@ -596,3 +597,4 @@ } | ||
id, | ||
content | ||
content, | ||
this.threshold | ||
); | ||
@@ -611,2 +613,4 @@ | ||
} | ||
return this; | ||
}; | ||
@@ -637,3 +641,3 @@ | ||
return; | ||
return this; | ||
} | ||
@@ -657,3 +661,3 @@ | ||
return; | ||
return this; | ||
} | ||
@@ -669,2 +673,4 @@ | ||
} | ||
return this; | ||
}; | ||
@@ -693,3 +699,3 @@ | ||
return; | ||
return this; | ||
} | ||
@@ -712,3 +718,3 @@ | ||
return; | ||
return this; | ||
} | ||
@@ -724,3 +730,3 @@ | ||
var tmp = this._map[z]; | ||
tmp = tmp && tmp[key]; | ||
tmp = tmp && tmp[key]; | ||
@@ -751,2 +757,4 @@ if(tmp && tmp.length){ | ||
} | ||
return this; | ||
}; | ||
@@ -764,2 +772,4 @@ | ||
var threshold; | ||
if(query && (typeof query === 'object')){ | ||
@@ -771,5 +781,8 @@ | ||
limit = query['limit']; | ||
threshold = query['threshold']; | ||
query = query['query']; | ||
} | ||
threshold || (threshold = 0); | ||
if(typeof limit === 'function'){ | ||
@@ -797,2 +810,3 @@ | ||
'limit': limit, | ||
'threshold': threshold, | ||
'content': query | ||
@@ -855,3 +869,3 @@ }); | ||
else if(this._last_empty_query && (query.indexOf(this._last_empty_query) !== -1)){ | ||
else if(this._last_empty_query && (query.indexOf(this._last_empty_query) === 0)){ | ||
@@ -863,7 +877,4 @@ return []; | ||
if(_query && this.encode){ | ||
_query = this.encode(/** @type {string} */ (_query)); | ||
_query = this.encode(/** @type {string} */ (_query)); | ||
} | ||
if(!_query.length){ | ||
@@ -876,10 +887,10 @@ | ||
if(this.encoder === global_encoder['ngram']){ | ||
var words = ( | ||
var words = /** @type {!Array<string>} */ (_query); | ||
} | ||
else{ | ||
_query.constructor === Array ? | ||
var words = /** @type {string} */ (_query).split(regex_split); | ||
} | ||
/** @type {!Array<string>} */ (_query) | ||
: | ||
/** @type {string} */ (_query).split(regex_split) | ||
); | ||
@@ -920,3 +931,3 @@ var length = words.length; | ||
for(var z = 9; z >= 0; z--){ | ||
for(var z = 9; z >= threshold; z--){ | ||
@@ -944,3 +955,3 @@ if((map = this._map[z][value])){ | ||
[].concat.apply([], map_check) | ||
check.concat.apply([], map_check) | ||
: | ||
@@ -966,20 +977,5 @@ map_check[0] | ||
var count = 0; | ||
var tmp = check[count++]; | ||
if(length > 0){ | ||
if(tmp){ | ||
while(tmp.length && (count < length)){ | ||
var item = check[count++]; | ||
tmp = intersect(tmp, item, count === length ? /** @type {number} */ (limit) : 0); | ||
} | ||
if(limit && (tmp.length > limit)){ | ||
tmp.splice(limit, tmp.length - limit); | ||
} | ||
result = tmp; | ||
result = intersect(check, limit); | ||
} | ||
@@ -1064,3 +1060,4 @@ } | ||
'cache': this._stack_keys.length, | ||
'matchers': global_matcher.length | ||
'matcher': global_matcher.length, | ||
'worker': this.worker | ||
}; | ||
@@ -1081,3 +1078,3 @@ }; | ||
this.init(); | ||
return this.init(); | ||
}; | ||
@@ -1100,5 +1097,8 @@ | ||
this._map = null; | ||
this._ids = null; | ||
this._scores = | ||
this._map = | ||
this._ids = | ||
this._cache = null; | ||
return this; | ||
}; | ||
@@ -1329,3 +1329,2 @@ | ||
var length = value.length; | ||
var last_whitespace = 0; | ||
@@ -1358,6 +1357,4 @@ for(var i = 0; i < length; i++){ | ||
} | ||
else{ | ||
last_whitespace = i; | ||
} | ||
// dynamic n-gram sequences | ||
@@ -1368,5 +1365,12 @@ if((char === ' ') || ((count_vowels >= 2) && (count_literal >= 2)) || (i === length - 1)){ | ||
if(tmp.length > 2 || (last_whitespace === (i - tmp.length))){ | ||
var tmp_length = tmp.length; | ||
parts[++count_parts] = tmp; | ||
if((tmp_length > 2) || (char === ' ') || (i === length - 1)){ | ||
var char_code = tmp.charCodeAt(0); | ||
if((tmp_length > 1) || (char_code >= 48) || (char_code <= 57)){ | ||
parts[++count_parts] = tmp; | ||
} | ||
} | ||
@@ -1497,5 +1501,6 @@ else if(parts[count_parts]){ | ||
* @param {string} content | ||
* @param {number} threshold | ||
*/ | ||
function addIndex(map, dupes, tmp, id, content){ | ||
function addIndex(map, dupes, tmp, id, content, threshold){ | ||
@@ -1506,6 +1511,11 @@ if(!dupes[tmp]){ | ||
var arr = map[calcScore(tmp, content)]; | ||
var score = calcScore(tmp, content); | ||
arr = arr[tmp] || (arr[tmp] = []); | ||
arr[arr.length] = id; | ||
if(score > threshold){ | ||
var arr = map[score]; | ||
arr = arr[tmp] || (arr[tmp] = []); | ||
arr[arr.length] = id; | ||
} | ||
} | ||
@@ -1647,54 +1657,85 @@ } | ||
/** | ||
* @param {!Array<number|string>} a | ||
* @param {!Array<number|string>} b | ||
* @param {number|boolean=} limit | ||
* @param {!Array<Array<number|string>>} arr | ||
* @param {number=} limit | ||
* @returns {Array} | ||
*/ | ||
function intersect(a, b, limit){ | ||
function intersect(arr, limit) { | ||
var length_a = a.length, | ||
length_b = b.length; | ||
var result = []; | ||
var length_z = arr.length; | ||
if(length_a && length_b){ | ||
if(length_z > 1){ | ||
var count = 0, | ||
tmp; | ||
var map = {}; | ||
var a = arr[0]; | ||
// swap order, shortest first | ||
// if(length_b < length_a){ | ||
// if(!a){ | ||
// | ||
// tmp = b; | ||
// b = a; | ||
// a = tmp; | ||
// | ||
// tmp = length_b; | ||
// length_b = length_a; | ||
// length_a = tmp; | ||
// return []; | ||
// } | ||
for(var y = 0; y < length_a; y++){ | ||
for(var i = 0, length = a.length; i < length; ++i) { | ||
var current_a = a[y]; | ||
map[a[i]] = true; | ||
} | ||
for(var x = 0; x < length_b; x++){ | ||
var tmp, count = 0; | ||
if(b[x] === current_a){ | ||
for(var z = 1; z < length_z; ++z){ | ||
result[count++] = current_a; | ||
var b = arr[z]; | ||
if(limit && (count === limit)){ | ||
// if(!b){ | ||
// | ||
// return []; | ||
// } | ||
return result; | ||
var new_map = {}; | ||
var found = false; | ||
for(var i = 0, length = b.length; i < length; ++i){ | ||
if((map[tmp = b[i]])){ | ||
if(z === (length_z - 1)){ | ||
result[count++] = tmp; | ||
if(limit && (count === limit)){ | ||
return result; | ||
} | ||
} | ||
found = true; | ||
new_map[tmp] = true; | ||
map[tmp] = false; | ||
break; | ||
} | ||
} | ||
if(!found){ | ||
return []; | ||
} | ||
map = new_map; | ||
} | ||
return result; | ||
} | ||
else{ | ||
result = arr[0]; | ||
if(limit && result && (result.length > limit)){ | ||
// Note: do not touch original array | ||
result = result.slice(0, limit); | ||
} | ||
} | ||
return result; | ||
@@ -1968,3 +2009,3 @@ } | ||
'js/worker/' + name + '.js' | ||
'../' + name + '.js' | ||
); | ||
@@ -1971,0 +2012,0 @@ |
/* | ||
https://github.com/nextapps-de/flexsearch | ||
@version: 0.1.27 | ||
@version: 0.1.28 | ||
@license: Apache 2.0 Licence | ||
*/ | ||
'use strict';(function(p,y,e){var c;(c=e.define)&&c.amd?c([],function(){return y}):(c=e.modules)?c[p.toLowerCase()]=y:"undefined"!==typeof module?module.exports=y:e[p]=y})("FlexSearch",function F(p){function e(a){a||(a=m);this.id=a.id||G++;this.init(a);Object.defineProperty(this,"index",{get:function(){return this.a}});Object.defineProperty(this,"length",{get:function(){return Object.keys(this.a).length}})}function c(a){return new RegExp(a,"g")}function t(a,b,d){if("undefined"===typeof d){for(d=0;d< | ||
b.length;d+=2)a=a.replace(b[d],b[d+1]);return a}return a.replace(b,d)}function u(a,b,d,g,c){b[d]||(b[d]="1",b=c.indexOf(d),a=a[3/c.length*(c.length-b)+6/(b-c.lastIndexOf(" ",b))+.5|0],a=a[d]||(a[d]=[]),a[a.length]=g)}function A(a){for(var b="",d="",g="",c=0;c<a.length;c++){var f=a[c];f!==d&&(0<c&&" "!==f&&"h"===f?(g="a"===g||"e"===g||"i"===g||"o"===g||"u"===g||"y"===g,"a"!==d&&"e"!==d&&"i"!==d&&"o"!==d&&"u"!==d&&"y"!==d||!g||(b+=f)):b+=f);g=c===a.length-1?"":a[c+1];d=f}return b}function v(a,b){a= | ||
a.length-b.length;return 0>a?1:0<a?-1:0}function H(a,b){a=a.length-b.length;return 0>a?-1:0<a?1:0}function I(a,b,d){var g=a.length,c=b.length,f=[];if(g&&c)for(var h=0,k=0;k<g;k++)for(var e=a[k],n=0;n<c;n++)if(b[n]===e){f[h++]=e;if(d&&h===d)return f;break}return f}function B(a){a.v||(a.v=C(function(){a.v=null;var b=a.async;b&&(a.async=!1);if(a.c.length){for(var d=D(),g;(g=a.c.shift())||0===g;){var c=a.g[g];switch(c[0]){case z.add:a.add(c[1],c[2]);break;case z.update:a.update(c[1],c[2]);break;case z.remove:a.remove(c[1])}a.g[g]= | ||
null;delete a.g[g];if(100<D()-d)break}a.c.length&&B(a)}b&&(a.async=b)},1,"search-async-"+a.id))}function D(){return"undefined"!==typeof performance?performance.now():(new Date).getTime()}function J(a,b,d,c){a=p("flexsearch","id"+a,function(){var a,b;self.a=function(d){if(d=d.data)b.debug&&console.log("Worker Job Started: "+d.id),d.search?self.postMessage({result:b.search(d.content,d.limit),id:a,content:d.content,limit:d.limit}):d.add?b.add(d.id,d.content):d.update?b.update(d.id,d.content):d.remove? | ||
b.remove(d.id):d.reset?b.reset():d.info?(d=b.info(),d.worker=a,b.debug&&console.log(d)):d.register&&(a=d.id,d.options.cache=!1,d.options.async=!0,d.options.worker=!1,b=(new Function(d.register.substring(d.register.indexOf("{")+1,d.register.lastIndexOf("}"))))(d.options))}},function(a){(a=a.data)&&a.result?c(a.id,a.content,a.result,a.limit):d.debug&&console.log(a)},b);var g=F.toString();d.id=b;a.postMessage(b,{register:g,options:d,id:b});return a}var m={type:"integer",mode:"forward",boolean:!1,cache:!1, | ||
async:!1,worker:!1,encode:!1,debug:!0},q=[],G=0,z={add:0,update:1,remove:2},E=c("[ -/]");e.new=function(a){return new this(a)};e.create=function(a){return e.new(a)};e.addMatcher=function(a){for(var b in a)a.hasOwnProperty(b)&&(q[q.length]=c(b),q[q.length]=a[b])};e.register=function(a,b){w[a]=b};e.encode=function(a,b){return w[a](b)};e.prototype.init=function(a){this.l=[];if(a){if(a.worker)if("undefined"===typeof Worker)a.worker=!1,this.i=null;else{var b=this,d=parseInt(a.worker,10)||4;b.o=-1;b.m= | ||
0;b.h=[];b.u=null;b.i=Array(d);for(var c=0;c<d;c++)b.i[c]=J(b.id,c,a||m,function(a,d,c,g){b.m!==b.worker&&(b.h=b.h.concat(c),b.m++,g&&b.h.length>=g&&(b.m=b.worker),b.u&&b.m===b.worker&&(b.h.length?b.f="":b.f||(b.f=d),b.cache&&b.j.set(d,b.h),b.u(b.h),b.h=[]))})}this.mode=a.mode||this.mode||m.mode;this.boolean="or"===a["boolean"]||this.boolean||m.boolean;this.cache=a.cache||this.cache||m.cache;this.async=a.async||this.async||m.async;this.worker=a.worker||this.worker||m.worker;this.encoder=a.encode&& | ||
w[a.encode]||this.encoder||m.encode&&w[m.encode]||a.encode;this.debug=a.debug||this.debug||m.debug;a.matcher&&this.addMatcher(a.matcher)}this.b=[{},{},{},{},{},{},{},{},{},{}];this.a={};this.g={};this.c=[];this.v=null;this.f="";this.s=!0;this.j=this.cache?new K(3E4,50,!0):!1};e.prototype.encode=function(a){this.encoder&&(a=this.encoder(a));q.length&&(a=t(a,q));this.l.length&&(a=t(a,this.l));return a};e.prototype.addMatcher=function(a){for(var b in a)a.hasOwnProperty(b)&&(this.l[this.l.length]=c(b), | ||
this.l[this.l.length]=a[b])};e.prototype.add=function(a,b){if("string"===typeof b&&b&&(a||0===a))if(this.a[a])this.update(a,b);else if(this.worker)++this.o>=this.i.length&&(this.o=0),this.i[this.o].postMessage(this.o,{add:!0,id:a,content:b}),this.a[a]=""+this.o;else if(this.async)this.g[a]||(this.c[this.c.length]=a),this.g[a]=[z.add,a,b],B(this);else if(b&&this.encode&&(b=this.encode(b)),b){for(var d={},c=this.encoder===w.ngram?b:b.split(E),e=0;e<c.length;e++){var f=c[e];if(f){var h=f.length;switch(this.mode){case "inverse":case "both":for(var k= | ||
"",l=h-1;1<=l;l--)k=f[l]+k,u(this.b,d,k,a,b);case "forward":k="";for(l=0;l<h;l++)k+=f[l],u(this.b,d,k,a,b);break;case "full":for(l=0;l<h;l++)for(var n=h;n>l;n--)k=f.substring(l,n),u(this.b,d,k,a,b);break;default:u(this.b,d,f,a,b)}}}this.a[a]="1";this.s=!1}};e.prototype.update=function(a,b){if("string"===typeof b&&(a||0===a)&&this.a[a])if(this.worker){var d=parseInt(this.a[a],10);this.i[d].postMessage(d,{update:!0,id:a,content:b})}else this.async?(this.g[a]||(this.c[this.c.length]=a),this.g[a]=[z.update, | ||
a,b],B(this)):(this.remove(a),b&&this.add(a,b))};e.prototype.remove=function(a){if(this.a[a])if(this.worker){var b=parseInt(this.a[a],10);this.i[b].postMessage(b,{remove:!0,id:a});delete this.a[a]}else if(this.async)this.g[a]||(this.c[this.c.length]=a),this.g[a]=[z.remove,a],B(this);else{for(b=0;10>b;b++)for(var d=Object.keys(this.b[b]),c=0;c<d.length;c++){var e=d[c],f=this.b[b];if((f=f&&f[e])&&f.length)for(var h=0;h<f.length;h++)if(f[h]===a){f.splice(h,1);break}f.length||delete this.b[b][e]}delete this.a[a]; | ||
this.s=!1}};e.prototype.search=function(a,b,d){a&&"object"===typeof a&&(d=a.callback||b,b=a.limit,a=a.query);"function"===typeof b?(d=b,b=1E3):b||(b=1E3);if(this.worker){this.u=d;this.m=0;this.h=[];for(var c=0;c<this.worker;c++)this.i[c].postMessage(c,{search:!0,limit:b,content:a});return null}if(d){var e=this;C(function(){d(e.search(a,b));e=null},1,"search-"+this.id);return null}if(!a||"string"!==typeof a)return[];c=a;if(!this.s)this.cache&&(this.f="",this.j.reset()),this.s=!0;else if(this.cache){var f= | ||
this.j.get(a);if(f)return f}else if(this.f&&-1!==a.indexOf(this.f))return[];c&&this.encode&&(c=this.encode(c));if(!c.length)return[];var h=this.encoder===w.ngram?c:c.split(E);c=h.length;1<c&&h.sort(v);var k=[],l=!0;f=[];for(var n={},p=0;p<c;p++){var m=h[p];if(m&&!n[m]){for(var r,t=!1,q=[],x=0,u=9;0<=u;u--)(r=this.b[u][m])&&r.length&&(q[x++]=r,t=!0);if(t)f[f.length]=1<x?[].concat.apply([],q):q[0];else{l=!1;break}n[m]="1"}}if(l&&(c=f.length,1<c&&f.sort(H),x=0,r=f[x++])){for(;r.length&&x<c;)k=f[x++], | ||
r=I(r,k,x===c?b:0);b&&r.length>b&&r.splice(b,r.length-b);k=r}k.length?this.f="":this.f||(this.f=a);this.cache&&this.j.set(a,k);return k};e.prototype.info=function(){if(this.worker)for(var a=0;a<this.worker;a++)this.i[a].postMessage(a,{info:!0,id:this.id});else{for(var b,d,c=0,e=0,f=0,h=0;10>h;h++)for(b=Object.keys(this.b[h]),a=0;a<b.length;a++)d=this.b[h][b[a]].length,c+=d+2*b[a].length+4,e+=d,f+=2*b[a].length;b=Object.keys(this.a);d=b.length;for(a=0;a<d;a++)c+=2*b[a].length+2;return{id:this.id,memory:c, | ||
items:d,sequences:e,chars:f,status:this.s,cache:this.c.length,matchers:q.length}}};e.prototype.reset=function(){this.destroy();this.init()};e.prototype.destroy=function(){this.cache&&this.j.reset();this.j=this.a=this.b=null};var w={icase:function(a){return a.toLowerCase()},simple:function(){var a=[c("[\u00e0\u00e1\u00e2\u00e3\u00e4\u00e5]"),"a",c("[\u00e8\u00e9\u00ea\u00eb]"),"e",c("[\u00ec\u00ed\u00ee\u00ef]"),"i",c("[\u00f2\u00f3\u00f4\u00f5\u00f6\u0151]"),"o",c("[\u00f9\u00fa\u00fb\u00fc\u0171]"), | ||
"u",c("[\u00fd\u0177\u00ff]"),"y",c("\u00f1"),"n",c("\u00e7"),"c",c("\u00df"),"s",c("[-/]")," ",c("[^a-z0-9 ]"),""];return function(b){return t(b.toLowerCase(),a)}}(),advanced:function(){var a=[c("ae"),"a",c("ai"),"ei",c("ay"),"ei",c("ey"),"ei",c("oe"),"o",c("ue"),"u",c("ie"),"i",c("sz"),"s",c("zs"),"s",c("sh"),"s",c("ck"),"k",c("cc"),"k",c("dt"),"t",c("ph"),"f",c("ou"),"o",c("uo"),"u"];return function(b,c){if(!b)return b;b=w.simple(b);2<b.length&&(b=t(b,a));c||1<b.length&&(b=A(b));return b}}(),extra:function(){var a= | ||
[c("p"),"b",c("[sz]"),"c",c("[gq]"),"k",c("[jy]"),"i",c("n"),"m",c("d"),"t",c("[vw]"),"f",c("[aeiouy]"),""];return function(b){if(!b)return b;b=w.advanced(b,!0);if(1<b.length){b=b.split(" ");for(var c=0;c<b.length;c++){var e=b[c];1<e.length&&(b[c]=e[0]+t(e.substring(1),a))}b=b.join("");b=A(b)}return b}}(),ngram:function(a){var b=[];if(!a)return b;a=w.advanced(a);if(!a)return b;for(var c=0,e=0,m=-1,f="",h=a.length,k=0,l=0;l<h;l++){var n=a[l];"a"===n||"e"===n||"i"===n||"o"===n||"u"===n||"y"===n?c++: | ||
e++;" "!==n?f+=n:k=l;if(" "===n||2<=c&&2<=e||l===h-1)f&&(2<f.length||k===l-f.length?b[++m]=f:b[m]&&(b[m]+=f),f=""),e=c=0}return b}},C=function(){var a={};return function(b,c,e){var d=a[e];d&&clearTimeout(d);return a[e]=setTimeout(b,c)}}(),K=function(){function a(){this.cache={}}a.prototype.reset=function(){this.cache={}};a.prototype.set=function(a,c){this.cache[a]=c};a.prototype.get=function(a){return this.cache[a]};return a}();return e}(function(){var p={},y=!("undefined"===typeof Blob||"undefined"=== | ||
typeof URL||!URL.createObjectURL);return function(e,c,t,u,A){var v=e;e=y?URL.createObjectURL(new Blob(["("+t.toString()+")()"],{type:"text/javascript"})):"js/worker/"+v+".js";v+="-"+c;p[v]||(p[v]=[]);p[v][A]=new Worker(e);p[v][A].onmessage=u;return{postMessage:function(c,e){p[v][c].postMessage(e)}}}}()),this); | ||
'use strict';(function(l,z,e){var d;(d=e.define)&&d.amd?d([],function(){return z}):(d=e.modules)?d[l.toLowerCase()]=z:"undefined"!==typeof module?module.exports=z:e[l]=z})("FlexSearch",function D(l){function e(a){a||(a=n);this.id=a.id||E++;this.init(a);Object.defineProperty(this,"index",{get:function(){return this.a}});Object.defineProperty(this,"length",{get:function(){return Object.keys(this.a).length}})}function d(a){return new RegExp(a,"g")}function u(a,b,c){if("undefined"===typeof c){for(c=0;c< | ||
b.length;c+=2)a=a.replace(b[c],b[c+1]);return a}return a.replace(b,c)}function r(a,b,c,h,f,m){b[c]||(b[c]="1",b=f.indexOf(c),f=3/f.length*(f.length-b)+6/(b-f.lastIndexOf(" ",b))+.5|0,f>m&&(a=a[f],a=a[c]||(a[c]=[]),a[a.length]=h))}function x(a){for(var b="",c="",h="",f=0;f<a.length;f++){var m=a[f];m!==c&&(0<f&&" "!==m&&"h"===m?(h="a"===h||"e"===h||"i"===h||"o"===h||"u"===h||"y"===h,"a"!==c&&"e"!==c&&"i"!==c&&"o"!==c&&"u"!==c&&"y"!==c||!h||(b+=m)):b+=m);h=f===a.length-1?"":a[f+1];c=m}return b}function p(a, | ||
b){a=a.length-b.length;return 0>a?1:0<a?-1:0}function F(a,b){a=a.length-b.length;return 0>a?-1:0<a?1:0}function G(a,b){var c=[],h=a.length;if(1<h){for(var f={},m=a[0],g=0,q=m.length;g<q;++g)f[m[g]]=!0;for(var d=0,e=1;e<h;++e){var l=a[e],p={},n=!1;g=0;for(q=l.length;g<q;++g)if(f[m=l[g]]){if(e===h-1&&(c[d++]=m,b&&d===b))return c;n=!0;p[m]=!0;f[m]=!1;break}if(!n)return[];f=p}}else c=a[0],b&&c&&c.length>b&&(c=c.slice(0,b));return c}function y(a){a.w||(a.w=A(function(){a.w=null;var b=a.async;b&&(a.async= | ||
!1);if(a.f.length){for(var c=B(),h;(h=a.f.shift())||0===h;){var f=a.h[h];switch(f[0]){case w.add:a.add(f[1],f[2]);break;case w.update:a.update(f[1],f[2]);break;case w.remove:a.remove(f[1])}a.h[h]=null;delete a.h[h];if(100<B()-c)break}a.f.length&&y(a)}b&&(a.async=b)},1,"search-async-"+a.id))}function B(){return"undefined"!==typeof performance?performance.now():(new Date).getTime()}function H(a,b,c,h){a=l("flexsearch","id"+a,function(){var a,b;self.a=function(c){if(c=c.data)b.debug&&console.log("Worker Job Started: "+ | ||
c.id),c.search?self.postMessage({result:b.search(c.content,c.limit),id:a,content:c.content,limit:c.limit}):c.add?b.add(c.id,c.content):c.update?b.update(c.id,c.content):c.remove?b.remove(c.id):c.reset?b.reset():c.info?(c=b.info(),c.worker=a,b.debug&&console.log(c)):c.register&&(a=c.id,c.options.cache=!1,c.options.async=!0,c.options.worker=!1,b=(new Function(c.register.substring(c.register.indexOf("{")+1,c.register.lastIndexOf("}"))))(c.options))}},function(a){(a=a.data)&&a.result?h(a.id,a.content, | ||
a.result,a.limit):c.debug&&console.log(a)},b);var f=D.toString();c.id=b;a.postMessage(b,{register:f,options:c,id:b});return a}var n={type:"integer",mode:"forward",cache:!1,async:!1,b:!1,threshold:0,encode:!1,debug:!0},t=[],E=0,w={add:0,update:1,remove:2},C=d("[ -/]");e.new=function(a){return new this(a)};e.create=function(a){return e.new(a)};e.addMatcher=function(a){for(var b in a)a.hasOwnProperty(b)&&(t[t.length]=d(b),t[t.length]=a[b]);return this};e.register=function(a,b){v[a]=b;return this};e.encode= | ||
function(a,b){return v[a](b)};e.prototype.init=function(a){this.m=[];if(a){if(a.worker)if("undefined"===typeof Worker)a.worker=!1,a.async=!0,this.j=null;else{var b=this,c=parseInt(a.worker,10)||4;b.s=-1;b.o=0;b.i=[];b.v=null;b.j=Array(c);for(var h=0;h<c;h++)b.j[h]=H(b.id,h,a||n,function(a,c,h,d){b.o!==b.b&&(b.i=b.i.concat(h),b.o++,d&&b.i.length>=d&&(b.o=b.b),b.v&&b.o===b.b&&(b.i.length?b.g="":b.g||(b.g=c),b.cache&&b.l.set(c,b.i),b.v(b.i),b.i=[]))})}this.mode=a.mode||this.mode||n.mode;this.cache=a.cache|| | ||
this.cache||n.cache;this.async=a.async||this.async||n.async;this.b=a.worker||this.b||n.b;this.threshold=a.threshold||this.threshold||n.threshold;this.encoder=a.encode&&v[a.encode]||this.encoder||a.encode;this.debug=a.debug||this.debug||n.debug;a.matcher&&this.addMatcher(a.matcher)}this.c=[{},{},{},{},{},{},{},{},{},{}];this.a={};this.h={};this.f=[];this.w=null;this.g="";this.u=!0;this.l=this.cache?new I(3E4,50,!0):!1;return this};e.prototype.encode=function(a){a&&t.length&&(a=u(a,t));a&&this.m.length&& | ||
(a=u(a,this.m));a&&this.encoder&&(a=this.encoder(a));return a};e.prototype.addMatcher=function(a){for(var b in a)a.hasOwnProperty(b)&&(this.m[this.m.length]=d(b),this.m[this.m.length]=a[b]);return this};e.prototype.add=function(a,b){if("string"===typeof b&&b&&(a||0===a))if(this.a[a])this.update(a,b);else{if(this.b)return++this.s>=this.j.length&&(this.s=0),this.j[this.s].postMessage(this.s,{add:!0,id:a,content:b}),this.a[a]=""+this.s,this;if(this.async)return this.h[a]||(this.f[this.f.length]=a),this.h[a]= | ||
[w.add,a,b],y(this),this;b=this.encode(b);if(!b.length)return this;for(var c={},h=b.constructor===Array?b:b.split(C),f=0;f<h.length;f++){var d=h[f];if(d){var g=d.length;switch(this.mode){case "inverse":case "both":for(var e="",k=g-1;1<=k;k--)e=d[k]+e,r(this.c,c,e,a,b,this.threshold);case "forward":e="";for(k=0;k<g;k++)e+=d[k],r(this.c,c,e,a,b,this.threshold);break;case "full":for(k=0;k<g;k++)for(var l=g;l>k;l--)e=d.substring(k,l),r(this.c,c,e,a,b,this.threshold);break;default:r(this.c,c,d,a,b,this.threshold)}}}this.a[a]= | ||
"1";this.u=!1}return this};e.prototype.update=function(a,b){if("string"===typeof b&&(a||0===a)&&this.a[a]){if(this.b){var c=parseInt(this.a[a],10);this.j[c].postMessage(c,{update:!0,id:a,content:b});return this}if(this.async)return this.h[a]||(this.f[this.f.length]=a),this.h[a]=[w.update,a,b],y(this),this;this.remove(a);b&&this.add(a,b)}return this};e.prototype.remove=function(a){if(this.a[a]){if(this.b){var b=parseInt(this.a[a],10);this.j[b].postMessage(b,{remove:!0,id:a});delete this.a[a];return this}if(this.async)return this.h[a]|| | ||
(this.f[this.f.length]=a),this.h[a]=[w.remove,a],y(this),this;for(b=0;10>b;b++)for(var c=Object.keys(this.c[b]),d=0;d<c.length;d++){var f=c[d],e=this.c[b];if((e=e&&e[f])&&e.length)for(var g=0;g<e.length;g++)if(e[g]===a){e.splice(g,1);break}e.length||delete this.c[b][f]}delete this.a[a];this.u=!1}return this};e.prototype.search=function(a,b,c){if(a&&"object"===typeof a){c=a.callback||b;b=a.limit;var d=a.threshold;a=a.query}d||(d=0);"function"===typeof b?(c=b,b=1E3):b||(b=1E3);if(this.b){this.v=c;this.o= | ||
0;this.i=[];for(var f=0;f<this.b;f++)this.j[f].postMessage(f,{search:!0,limit:b,threshold:d,content:a});return null}if(c){var e=this;A(function(){c(e.search(a,b));e=null},1,"search-"+this.id);return null}if(!a||"string"!==typeof a)return[];var g=a;if(!this.u)this.cache&&(this.g="",this.l.reset()),this.u=!0;else if(this.cache){var q=this.l.get(a);if(q)return q}else if(this.g&&0===a.indexOf(this.g))return[];g=this.encode(g);if(!g.length)return[];g=g.constructor===Array?g:g.split(C);q=g.length;1<q&& | ||
g.sort(p);for(var k=[],l=!0,n=[],u={},t=0;t<q;t++){var r=g[t];if(r&&!u[r]){for(var w=!1,v=[],x=0,y=9;y>=d;y--)(f=this.c[y][r])&&f.length&&(v[x++]=f,w=!0);if(w)n[n.length]=1<x?n.concat.apply([],v):v[0];else{l=!1;break}u[r]="1"}}l&&(q=n.length,1<q&&n.sort(F),0<q&&(k=G(n,b)));k.length?this.g="":this.g||(this.g=a);this.cache&&this.l.set(a,k);return k};e.prototype.info=function(){if(this.b)for(var a=0;a<this.b;a++)this.j[a].postMessage(a,{info:!0,id:this.id});else{for(var b,c,d=0,f=0,e=0,g=0;10>g;g++)for(b= | ||
Object.keys(this.c[g]),a=0;a<b.length;a++)c=this.c[g][b[a]].length,d+=c+2*b[a].length+4,f+=c,e+=2*b[a].length;b=Object.keys(this.a);c=b.length;for(a=0;a<c;a++)d+=2*b[a].length+2;return{id:this.id,memory:d,items:c,sequences:f,chars:e,status:this.u,cache:this.f.length,matcher:t.length,worker:this.b}}};e.prototype.reset=function(){this.destroy();return this.init()};e.prototype.destroy=function(){this.cache&&this.l.reset();this.c=this.a=this.l=null;return this};var v={icase:function(a){return a.toLowerCase()}, | ||
simple:function(){var a=[d("[\u00e0\u00e1\u00e2\u00e3\u00e4\u00e5]"),"a",d("[\u00e8\u00e9\u00ea\u00eb]"),"e",d("[\u00ec\u00ed\u00ee\u00ef]"),"i",d("[\u00f2\u00f3\u00f4\u00f5\u00f6\u0151]"),"o",d("[\u00f9\u00fa\u00fb\u00fc\u0171]"),"u",d("[\u00fd\u0177\u00ff]"),"y",d("\u00f1"),"n",d("\u00e7"),"c",d("\u00df"),"s",d("[-/]")," ",d("[^a-z0-9 ]"),""];return function(b){return u(b.toLowerCase(),a)}}(),advanced:function(){var a=[d("ae"),"a",d("ai"),"ei",d("ay"),"ei",d("ey"),"ei",d("oe"),"o",d("ue"),"u",d("ie"), | ||
"i",d("sz"),"s",d("zs"),"s",d("sh"),"s",d("ck"),"k",d("cc"),"k",d("dt"),"t",d("ph"),"f",d("ou"),"o",d("uo"),"u"];return function(b,c){if(!b)return b;b=v.simple(b);2<b.length&&(b=u(b,a));c||1<b.length&&(b=x(b));return b}}(),extra:function(){var a=[d("p"),"b",d("[sz]"),"c",d("[gq]"),"k",d("[jy]"),"i",d("n"),"m",d("d"),"t",d("[vw]"),"f",d("[aeiouy]"),""];return function(b){if(!b)return b;b=v.advanced(b,!0);if(1<b.length){b=b.split(" ");for(var c=0;c<b.length;c++){var d=b[c];1<d.length&&(b[c]=d[0]+u(d.substring(1), | ||
a))}b=b.join("");b=x(b)}return b}}(),ngram:function(a){var b=[];if(!a)return b;a=v.advanced(a);if(!a)return b;for(var c=0,d=0,e=-1,m="",g=a.length,l=0;l<g;l++){var k=a[l];"a"===k||"e"===k||"i"===k||"o"===k||"u"===k||"y"===k?c++:d++;" "!==k&&(m+=k);if(" "===k||2<=c&&2<=d||l===g-1){if(m){c=m.length;if(2<c||" "===k||l===g-1){if(k=m.charCodeAt(0),1<c||48<=k||57>=k)b[++e]=m}else b[e]&&(b[e]+=m);m=""}d=c=0}}return b}},A=function(){var a={};return function(b,c,d){var e=a[d];e&&clearTimeout(e);return a[d]= | ||
setTimeout(b,c)}}(),I=function(){function a(){this.cache={}}a.prototype.reset=function(){this.cache={}};a.prototype.set=function(a,c){this.cache[a]=c};a.prototype.get=function(a){return this.cache[a]};return a}();return e}(function(){var l={},z=!("undefined"===typeof Blob||"undefined"===typeof URL||!URL.createObjectURL);return function(e,d,u,r,x){var p=e;e=z?URL.createObjectURL(new Blob(["("+u.toString()+")()"],{type:"text/javascript"})):"../"+p+".js";p+="-"+d;l[p]||(l[p]=[]);l[p][x]=new Worker(e); | ||
l[p][x].onmessage=r;return{postMessage:function(d,e){l[p][d].postMessage(e)}}}}()),this); |
{ | ||
"name": "flexsearch", | ||
"version": "0.1.27", | ||
"version": "0.1.28", | ||
"description": "Superfast, lightweight and memory efficient full text search library.", | ||
@@ -5,0 +5,0 @@ "keywords": [], |
150
README.md
@@ -10,2 +10,3 @@ <p align="center"> | ||
<a target="_blank" href="https://github.com/nextapps-de/flexsearch/issues"><img src="https://img.shields.io/github/issues/nextapps-de/xone.svg"></a> | ||
<img src="https://badges.greenkeeper.io/nextapps-de/flexsearch.svg"> | ||
<a target="_blank" href="https://github.com/nextapps-de/flexsearch/blob/master/LICENSE.md"><img src="https://img.shields.io/npm/l/xone.svg"></a> | ||
@@ -17,3 +18,3 @@ </p> | ||
When it comes to raw search speed __FlexSearch outperforms every single searching library out there__ and also provides flexible search capabilities like multi-word matching, phonetic transformations or partial matching. It also has the __most memory-efficient index__. Keep in mind that updating items from the index has a significant cost. When your index needs to be updated continuously then <a href="/bulksearch" target="_blank">BulkSearch</a> may be a better choice. FlexSearch also provides you a non-blocking asynchronous processing model as well as web workers to perform any updates on the index as well as queries through dedicated threads. | ||
When it comes to raw search speed __FlexSearch outperforms every single searching library out there__ and also provides flexible search capabilities like multi-word matching, phonetic transformations or partial matching. It also has the __most memory-efficient index__. Keep in mind that updating items from the index has a significant cost. When your index needs to be updated continuously then <a href="bulksearch/" target="_blank">BulkSearch</a> may be a better choice. FlexSearch also provides you a non-blocking asynchronous processing model as well as web workers to perform any updates on the index as well as queries through dedicated threads. | ||
@@ -39,5 +40,4 @@ Benchmark: | ||
<li>Multiple Words</li> | ||
<li>Flexible Word Order</li> | ||
<li><a href="#phonetic">Phonetic Search</a></li> | ||
<li>Sorted by Scoring</li> | ||
<li>Relevance-based Scoring</li> | ||
<li>Limit Results</li> | ||
@@ -53,3 +53,3 @@ <li>Caching</li> | ||
Workers get its own dedicated memory. Especially for larger indexes, web worker improves speed and available memory a lot. FlexSearch index was tested with a 250 Mb text file including __10 Million words__. The indexing was done silently in background by multiple parallel running workers in about 7 minutes and __reserve ~ 8.2 Mb__ memory. The search result __took ~ 0.25 ms__! | ||
Workers get its own dedicated memory. Especially for larger indexes, web worker improves speed and available memory a lot. FlexSearch index was tested with a 250 Mb text file including 10 Million words. The indexing was done silently in background by multiple parallel running workers in about 7 minutes. The final index reserves ~ 8.2 Mb memory/space. The search result took ~ 0.25 ms. | ||
@@ -63,5 +63,5 @@ __Note:__ It is slightly faster to use no web worker when the index isn't too big (< 100,000 words). | ||
<tr> | ||
<th align="left">Description</th> | ||
<th align="left">BulkSearch</th> | ||
<th align="left">FlexSearch</th> | ||
<td align="left">Description</th> | ||
<td align="left">BulkSearch</th> | ||
<td align="left">FlexSearch</th> | ||
</tr> | ||
@@ -76,15 +76,21 @@ <tr> | ||
<td>Memory</td> | ||
<td>Large (~ 90 bytes per word)</td> | ||
<td>Tiny (~ 2 bytes per word)</td> | ||
<td>Large: ~ 5 Mb per 100,000 words</td> | ||
<td>Tiny: ~ 100 Kb per 100,000 words</td> | ||
</tr> | ||
<tr></tr> | ||
<tr> | ||
<td>Usage</td> | ||
<td><ul><li>Limited content</li><li>Index updates continously</li></ul></td> | ||
<td><ul><li>Fastest possible search</li><li>Rare updates on index</li><li>Low memory capabilities</li></ul></td> | ||
<td>Usecase</td> | ||
<td><ul><li>Limited content</li><li>Index needs to be updated continously (add, update, remove)</li><li>Boost query time through pagination</li></ul></td> | ||
<td><ul><li>Fastest possible search</li><li>Rare updates on index</li><li>Max out memory capabilities</li></ul></td> | ||
</tr> | ||
<tr></tr> | ||
<tr> | ||
<td>Limit Results</td> | ||
<td>Pagination</td> | ||
<td>Yes</td> | ||
<td>No</td> | ||
</tr> | ||
<tr></tr> | ||
<tr> | ||
<td>Ranked Searching</td> | ||
<td>No</td> | ||
<td>Yes</td> | ||
@@ -94,5 +100,5 @@ </tr> | ||
<tr> | ||
<td>Pagination</td> | ||
<td>WebWorker</td> | ||
<td>No</td> | ||
<td>Yes</td> | ||
<td>No</td> | ||
</tr> | ||
@@ -381,4 +387,19 @@ </table> | ||
``` | ||
<a name="chaining"></a> | ||
#### Chaining | ||
<a name="options" id="options"></a> | ||
Simply chain methods like: | ||
```js | ||
var index = FlexSearch.create() | ||
.addMatcher({'â': 'a'}) | ||
.add(0, 'foo') | ||
.add(1, 'bar'); | ||
``` | ||
```js | ||
index.remove(0).update(1, 'foo').add(2, 'foobar'); | ||
``` | ||
<a name="options"></a> | ||
## Options | ||
@@ -389,5 +410,5 @@ | ||
<tr> | ||
<th align="left">Option</th> | ||
<th align="left">Values</th> | ||
<th align="left">Description</th> | ||
<td align="left">Option</td> | ||
<td align="left">Values</td> | ||
<td align="left">Description</td> | ||
</tr> | ||
@@ -427,3 +448,2 @@ <tr> | ||
</tr> | ||
--> | ||
<tr></tr> | ||
@@ -438,2 +458,3 @@ <tr> | ||
</tr> | ||
--> | ||
<tr></tr> | ||
@@ -457,2 +478,11 @@ <tr> | ||
</tr> | ||
<tr></tr> | ||
<tr> | ||
<td align="top">worker</td> | ||
<td> | ||
false<br> | ||
{number} | ||
</td> | ||
<td>Enable and also count of running worker threads.</td> | ||
</tr> | ||
</table> | ||
@@ -466,7 +496,6 @@ | ||
<tr> | ||
<th align="left">Option</th> | ||
<th align="left">Description</th> | ||
<th align="left">Example</th> | ||
<th align="left">False-Positives</th> | ||
<th align="left">Compression</th> | ||
<td align="left">Option</td> | ||
<td align="left">Description</td> | ||
<td align="left">False-Positives</td> | ||
<td align="left">Compression</td> | ||
</tr> | ||
@@ -476,6 +505,2 @@ <tr> | ||
<td>Turn off encoding</td> | ||
<td> | ||
Reference: "Björn-Phillipp Mayer"<br> | ||
Matches: "Phil" | ||
</td> | ||
<td>no</td> | ||
@@ -486,8 +511,4 @@ <td>no</td> | ||
<tr> | ||
<td><b>icase</b></td> | ||
<td><b>"icase"</b></td> | ||
<td>Case in-sensitive encoding</td> | ||
<td> | ||
Reference: "Björn-Phillipp Mayer"<br> | ||
Matches: "phil" | ||
</td> | ||
<td>no</td> | ||
@@ -498,8 +519,4 @@ <td>no</td> | ||
<tr> | ||
<td><b>simple</b></td> | ||
<td><b>"simple"</b></td> | ||
<td>Phonetic normalizations</td> | ||
<td> | ||
Reference: "Björn-Phillipp Mayer"<br> | ||
Matches: "bjoern fillip" | ||
</td> | ||
<td>no</td> | ||
@@ -510,8 +527,4 @@ <td>~ 7%</td> | ||
<tr> | ||
<td><b>advanced</b></td> | ||
<td><b>"advanced"</b></td> | ||
<td>Phonetic normalizations + Literal transformations</td> | ||
<td> | ||
Reference: "Björn-Phillipp Mayer"<br> | ||
Matches: "filip meier" | ||
</td> | ||
<td>no</td> | ||
@@ -522,11 +535,14 @@ <td>~ 35%</td> | ||
<tr> | ||
<td><b>extra</b></td> | ||
<td><b>"extra"</b></td> | ||
<td>Phonetic normalizations + Soundex transformations</td> | ||
<td> | ||
Reference: "Björn-Phillipp Mayer"<br> | ||
Matches: "byorn mair" | ||
</td> | ||
<td>yes</td> | ||
<td>~ 60%</td> | ||
</tr> | ||
<tr></tr> | ||
<tr> | ||
<td><b>"ngram"</b></td> | ||
<td>Phonetic normalizations + N-Gram sequencing</td> | ||
<td>yes</td> | ||
<td>~ 40%</td> | ||
</tr> | ||
</table> | ||
@@ -542,7 +558,8 @@ | ||
<tr> | ||
<th align="left">Query</th> | ||
<th align="left">iCase</th> | ||
<th align="left">Simple</th> | ||
<th align="left">Advanced</th> | ||
<th align="left">Extra</th> | ||
<td align="left">Query</td> | ||
<td align="left">iCase</td> | ||
<td align="left">Simple</td> | ||
<td align="left">Advanced</td> | ||
<td align="left">Extra</td> | ||
<td align="left">N-Gram</td> | ||
</tr> | ||
@@ -555,2 +572,3 @@ <tr> | ||
<td><b>yes</b></td> | ||
<td><b>yes</b></td> | ||
</tr> | ||
@@ -564,2 +582,3 @@ <tr></tr> | ||
<td><b>yes</b></td> | ||
<td>no</td> | ||
</tr> | ||
@@ -573,2 +592,3 @@ <tr></tr> | ||
<td><b>yes</b></td> | ||
<td><b>yes</b></td> | ||
</tr> | ||
@@ -582,2 +602,3 @@ <tr></tr> | ||
<td><b>yes</b></td> | ||
<td><b>yes</b></td> | ||
</tr> | ||
@@ -591,2 +612,3 @@ <tr></tr> | ||
<td><b>yes</b></td> | ||
<td><b>yes</b></td> | ||
</tr> | ||
@@ -600,2 +622,3 @@ <tr></tr> | ||
<td><b>yes</b></td> | ||
<td><b>yes</b></td> | ||
</tr> | ||
@@ -609,2 +632,3 @@ <tr></tr> | ||
<td><b>yes</b></td> | ||
<td>no</td> | ||
</tr> | ||
@@ -618,2 +642,3 @@ <tr></tr> | ||
<td><b>yes</b></td> | ||
<td><b>yes</b></td> | ||
</tr> | ||
@@ -627,2 +652,3 @@ <tr></tr> | ||
<td><b>yes</b></td> | ||
<td><b>yes</b></td> | ||
</tr> | ||
@@ -636,2 +662,3 @@ <tr></tr> | ||
<td><b>yes</b></td> | ||
<td><b>yes</b></td> | ||
</tr> | ||
@@ -644,2 +671,3 @@ <tr></tr> | ||
<td>no</td> | ||
<td>no</td> | ||
<td><b>yes</b></td> | ||
@@ -653,2 +681,3 @@ </tr> | ||
<td>yes</td> | ||
<td><b>no</b></td> | ||
</tr> | ||
@@ -665,4 +694,4 @@ </table> | ||
<tr> | ||
<th align="left">Encoding</th> | ||
<th align="left">Memory usage of every ~ 100,000 indexed words</th> | ||
<td align="left">Encoding</td> | ||
<td align="left">Memory usage of every ~ 100,000 indexed words</td> | ||
</tr> | ||
@@ -688,7 +717,12 @@ <tr> | ||
</tr> | ||
<tr></tr> | ||
<tr> | ||
<th align="left">Mode</th> | ||
<th align="left">Multiplied with:</th> | ||
<td>"ngram"</td> | ||
<td>110 kb</td> | ||
</tr> | ||
<tr> | ||
<td align="left">Mode</td> | ||
<td align="left">Multiplied with:</td> | ||
</tr> | ||
<tr> | ||
<td>"strict"</td> | ||
@@ -695,0 +729,0 @@ <td>x 1</td> |
439
test/test.js
if(typeof module !== 'undefined'){ | ||
// Node.js Stub | ||
URL = function(string){}; | ||
URL.createObjectURL = function(val){}; | ||
Blob = function(string){}; | ||
var env = process.argv[3] === 'test' ? '.min' : ''; | ||
@@ -11,2 +17,4 @@ var expect = require('chai').expect; | ||
var flexsearch_async; | ||
var flexsearch_worker; | ||
var flexsearch_cache; | ||
@@ -124,2 +132,9 @@ var flexsearch_icase; | ||
flexsearch_cache = new FlexSearch({ | ||
encode: 'icase', | ||
mode: 'inverse', | ||
cache: true | ||
}); | ||
expect(flexsearch_default).to.be.an.instanceOf(FlexSearch); | ||
@@ -192,2 +207,9 @@ expect(flexsearch_sync).to.be.an.instanceOf(FlexSearch); | ||
expect(flexsearch_sync.length).to.equal(3); | ||
flexsearch_extra.add(3, ""); | ||
flexsearch_extra.add(3, " "); | ||
flexsearch_extra.add(3, " "); | ||
flexsearch_extra.add(3, " - "); | ||
expect(flexsearch_extra.length).to.equal(0); | ||
}); | ||
@@ -200,8 +222,8 @@ }); | ||
expect(flexsearch_sync.search("foo")).to.have.keys([0, 1]); | ||
expect(flexsearch_sync.search("foo")).to.have.members([0, 1]); | ||
expect(flexsearch_sync.search("bar")).to.include(2); | ||
expect(flexsearch_sync.search("foobar")).to.include(1); | ||
expect(flexsearch_sync.search("foo foo")).to.have.keys([0, 1]); | ||
expect(flexsearch_sync.search("foo foo")).to.have.keys([0, 1]); | ||
expect(flexsearch_sync.search("foo foo")).to.have.members([0, 1]); | ||
expect(flexsearch_sync.search("foo foo")).to.have.members([0, 1]); | ||
}); | ||
@@ -212,2 +234,3 @@ | ||
expect(flexsearch_sync.search("foo", 1)).to.include(0); | ||
expect(flexsearch_sync.search({query: "foo", limit: 1})).to.include(0); | ||
expect(flexsearch_sync.search("foo", 1)).to.not.include(1); | ||
@@ -221,2 +244,3 @@ }); | ||
expect(flexsearch_sync.search(" ")).to.have.lengthOf(0); | ||
expect(flexsearch_sync.search(" - ")).to.have.lengthOf(0); | ||
expect(flexsearch_sync.search(" o ")).to.have.lengthOf(0); | ||
@@ -235,6 +259,17 @@ }); | ||
expect(flexsearch_sync.length).to.equal(3); | ||
expect(flexsearch_sync.search("foo")).to.include(2, 1); | ||
expect(flexsearch_sync.search("foo")).to.have.members([2, 1]); | ||
expect(flexsearch_sync.search("bar")).to.include(0); | ||
expect(flexsearch_sync.search("bar")).to.not.include(2); | ||
expect(flexsearch_sync.search("foobar")).to.include(2); | ||
// bypass update: | ||
flexsearch_sync.add(2, "bar"); | ||
flexsearch_sync.add(0, "foo"); | ||
flexsearch_sync.add(1, "foobar"); | ||
expect(flexsearch_sync.length).to.equal(3); | ||
expect(flexsearch_sync.search("foo")).to.have.members([0, 1]); | ||
expect(flexsearch_sync.search("bar")).to.include(2); | ||
expect(flexsearch_sync.search("foobar")).to.include(1); | ||
}); | ||
@@ -255,6 +290,5 @@ | ||
expect(flexsearch_sync.length).to.equal(3); | ||
expect(flexsearch_sync.search("foo")).to.include(2, 1); | ||
expect(flexsearch_sync.search("bar")).to.include(0); | ||
expect(flexsearch_sync.search("bar")).to.not.include(2); | ||
expect(flexsearch_sync.search("foobar")).to.include(2); | ||
expect(flexsearch_sync.search("foo")).to.have.members([0, 1]); | ||
expect(flexsearch_sync.search("bar")).to.include(2); | ||
expect(flexsearch_sync.search("foobar")).to.include(1); | ||
}); | ||
@@ -303,2 +337,15 @@ }); | ||
}); | ||
it('Should have been sorted properly by threshold', function(){ | ||
flexsearch_inverse.add(0, "foobarxxx foobarfoobarfoobarxxx foobarfoobarfoobaryyy foobarfoobarfoobarzzz"); | ||
expect(flexsearch_inverse.search("xxx").length).to.equal(1); | ||
expect(flexsearch_inverse.search("yyy").length).to.equal(1); | ||
expect(flexsearch_inverse.search("zzz").length).to.equal(0); | ||
expect(flexsearch_inverse.search({query: "xxx", threshold: 2}).length).to.equal(1); | ||
expect(flexsearch_inverse.search({query: "xxx", threshold: 5}).length).to.equal(0); | ||
expect(flexsearch_inverse.search({query: "yyy", threshold: 2}).length).to.equal(0); | ||
expect(flexsearch_inverse.search({query: "zzz", threshold: 0}).length).to.equal(0); | ||
}); | ||
}); | ||
@@ -359,3 +406,3 @@ | ||
expect(result).to.have.keys([0, 1]); | ||
expect(result).to.have.members([0, 1]); | ||
}); | ||
@@ -434,3 +481,3 @@ | ||
expect(flexsearch_async.length).to.equal(3); | ||
expect(flexsearch_async.search("foo")).to.not.include(2, 1); | ||
expect(flexsearch_async.search("foo")).to.not.have.members([2, 1]); | ||
expect(flexsearch_async.search("bar")).to.not.include(0); | ||
@@ -443,3 +490,3 @@ expect(flexsearch_async.search("bar")).to.include(2); | ||
expect(flexsearch_async.length).to.equal(3); | ||
expect(flexsearch_async.search("foo")).to.include(2, 1); | ||
expect(flexsearch_async.search("foo")).to.have.members([2, 1]); | ||
expect(flexsearch_async.search("bar")).to.include(0); | ||
@@ -469,3 +516,3 @@ expect(flexsearch_async.search("bar")).to.not.include(2); | ||
expect(flexsearch_async.length).to.equal(3); | ||
expect(flexsearch_async.search("foo")).to.include(2, 1); | ||
expect(flexsearch_async.search("foo")).to.have.members([2, 1]); | ||
expect(flexsearch_async.search("bar")).to.include(0); | ||
@@ -505,2 +552,237 @@ expect(flexsearch_async.search("bar")).to.not.include(2); | ||
// ------------------------------------------------------------------------ | ||
// Worker Tests | ||
// ------------------------------------------------------------------------ | ||
describe('Add (Worker)', function(){ | ||
it('Should support worker', function(done){ | ||
if(typeof Worker === 'undefined'){ | ||
Worker = function(string){}; | ||
Worker.prototype.postMessage = function(val){ | ||
this.onmessage(val); | ||
}; | ||
Worker.prototype.onmessage = function(val){ | ||
return val; | ||
}; | ||
} | ||
flexsearch_worker = new FlexSearch({ | ||
encode: false, | ||
async: true, | ||
worker: 4 | ||
}); | ||
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"); | ||
expect(flexsearch_worker.length).to.equal(3); | ||
expect(flexsearch_worker.index).to.have.keys([0, 1, 2]); | ||
setTimeout(function(){ | ||
expect(flexsearch_worker.length).to.equal(3); | ||
expect(flexsearch_worker.index).to.have.keys([0, 1, 2]); | ||
done(); | ||
}, 25); | ||
}); | ||
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(3, null); | ||
flexsearch_worker.add(3, false); | ||
flexsearch_worker.add(3, []); | ||
flexsearch_worker.add(3, {}); | ||
flexsearch_worker.add(3, function(){}); | ||
setTimeout(function(){ | ||
expect(flexsearch_worker.length).to.equal(3); | ||
expect(flexsearch_worker.index).to.have.keys([0, 1, 2]); | ||
done(); | ||
}, 25); | ||
}); | ||
}); | ||
describe('Search (Worker)', function(){ | ||
it('Should have been matched from index', function(done){ | ||
flexsearch_worker.search("foo", function(result){ | ||
expect(result).to.have.members([0, 1]); | ||
}); | ||
flexsearch_worker.search("bar", function(result){ | ||
expect(result).to.have.members([2, 1]); | ||
}); | ||
flexsearch_worker.search("foobar", function(result){ | ||
expect(result).to.include(1); | ||
}); | ||
setTimeout(function(){ | ||
done(); | ||
}, 25); | ||
}); | ||
it('Should have been limited', function(done){ | ||
flexsearch_worker.search("foo", 1, function(result){ | ||
expect(result).to.include(0); | ||
expect(result).to.not.include(1); | ||
}); | ||
setTimeout(function(){ | ||
done(); | ||
}, 25); | ||
}); | ||
it('Should not have been matched from index', function(done){ | ||
flexsearch_worker.search("barfoo", function(result){ | ||
expect(result).to.have.lengthOf(0); | ||
}); | ||
flexsearch_worker.search("", function(result){ | ||
expect(result).to.have.lengthOf(0); | ||
}); | ||
flexsearch_worker.search(" ", function(result){ | ||
expect(result).to.have.lengthOf(0); | ||
}); | ||
flexsearch_worker.search(" o ", function(result){ | ||
expect(result).to.have.lengthOf(0); | ||
}); | ||
setTimeout(function(){ | ||
done(); | ||
}, 25); | ||
}); | ||
}); | ||
describe('Update (Worker)', function(){ | ||
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"); | ||
expect(flexsearch_worker.length).to.equal(3); | ||
flexsearch_worker.search("foo", function(results){ | ||
expect(results).to.have.members([2, 1]); | ||
}); | ||
flexsearch_worker.search("bar", function(results){ | ||
expect(results).to.have.members([0, 2]); | ||
}); | ||
flexsearch_worker.search("foobar", function(results){ | ||
expect(results).to.include(2); | ||
}); | ||
setTimeout(function(){ | ||
done(); | ||
}, 25); | ||
}); | ||
}); | ||
describe('Remove (Worker)', function(){ | ||
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(0); | ||
flexsearch_worker.search("foo", function(results){ | ||
expect(results).to.not.include(1); | ||
expect(results).to.not.include(2); | ||
}); | ||
flexsearch_worker.search("bar", function(results){ | ||
expect(results).to.not.include(0); | ||
expect(results).to.not.include(2); | ||
}); | ||
flexsearch_worker.search("foobar", function(results){ | ||
expect(results).to.not.include(2); | ||
}); | ||
setTimeout(function(){ | ||
done(); | ||
}, 25); | ||
}); | ||
it('Should have been debug mode activated', function(){ | ||
flexsearch_worker.info(); | ||
}); | ||
}); | ||
describe('Worker Not Supported', function(){ | ||
it('Should not support worker', function(){ | ||
if(typeof Worker !== 'undefined'){ | ||
Worker = void 0; | ||
} | ||
flexsearch_worker = new FlexSearch({ | ||
encode: false, | ||
async: true, | ||
worker: 4 | ||
}); | ||
expect(flexsearch_worker.info().worker).to.equal(false); | ||
}); | ||
}); | ||
// ------------------------------------------------------------------------ | ||
// Phonetic Tests | ||
@@ -535,2 +817,9 @@ // ------------------------------------------------------------------------ | ||
}); | ||
it('Should have been encoded properly: Custom Encoder', function(){ | ||
FlexSearch.register('custom', test_encoder); | ||
expect(FlexSearch.encode('custom', "Björn-Phillipp Mayer")).to.equal(flexsearch_custom.encode("Björn-Phillipp Mayer")); | ||
}); | ||
}); | ||
@@ -610,10 +899,130 @@ | ||
flexsearch_forward.add(0, "123456"); | ||
flexsearch_forward.init({ | ||
expect(flexsearch_forward.search("123456")).to.include(0); | ||
encode: false | ||
}).init({ | ||
encode: 'not-found', | ||
matcher: { | ||
'7': 'e' | ||
} | ||
}).addMatcher({ | ||
'8': 'f' | ||
}); | ||
flexsearch_forward.add(0, "12345678"); | ||
expect(flexsearch_forward.search("12345678")).to.include(0); | ||
expect(flexsearch_forward.search("abcd")).to.include(0); | ||
expect(flexsearch_forward.encode("123456")).to.equal("abcddd"); | ||
expect(flexsearch_forward.encode("12345678")).to.equal("abcdddef"); | ||
}); | ||
}); | ||
// ------------------------------------------------------------------------ | ||
// Caching | ||
// ------------------------------------------------------------------------ | ||
describe('Caching', function(){ | ||
it('Should have been cached properly', function(){ | ||
flexsearch_cache.add(0, 'foo') | ||
.add(1, 'bar') | ||
.add(2, 'foobar'); | ||
// fetch: | ||
expect(flexsearch_cache.search("foo")).to.have.members([0, 2]); | ||
expect(flexsearch_cache.search("bar")).to.have.members([1, 2]); | ||
expect(flexsearch_cache.search("foobar")).to.include(2); | ||
// cache: | ||
expect(flexsearch_cache.search("foo")).to.have.members([0, 2]); | ||
expect(flexsearch_cache.search("bar")).to.have.members([1, 2]); | ||
expect(flexsearch_cache.search("foobar")).to.include(2); | ||
// update: | ||
flexsearch_cache.remove(2).update(1, 'foo').add(3, 'foobar'); | ||
// fetch: | ||
expect(flexsearch_cache.search("foo")).to.have.members([0, 1, 3]); | ||
expect(flexsearch_cache.search("bar")).to.include(3); | ||
expect(flexsearch_cache.search("foobar")).to.include(3); | ||
// cache: | ||
expect(flexsearch_cache.search("foo")).to.have.members([0, 1, 3]); | ||
expect(flexsearch_cache.search("bar")).to.include(3); | ||
expect(flexsearch_cache.search("foobar")).to.include(3); | ||
}); | ||
}); | ||
// ------------------------------------------------------------------------ | ||
// Debug Information | ||
// ------------------------------------------------------------------------ | ||
describe('Debug', function(){ | ||
it('Should have been debug mode activated', function(){ | ||
var info = flexsearch_cache.info(); | ||
expect(info).to.have.keys([ | ||
'id', | ||
'chars', | ||
'status', | ||
'cache', | ||
'items', | ||
'matcher', | ||
'memory', | ||
'sequences', | ||
'worker' | ||
]); | ||
}); | ||
}); | ||
// ------------------------------------------------------------------------ | ||
// Chaining | ||
// ------------------------------------------------------------------------ | ||
describe('Chaining', function(){ | ||
it('Should have been chained properly', function(){ | ||
var index = FlexSearch.create({mode: 'forward', encode: 'icase'}) | ||
.addMatcher({'â': 'a'}) | ||
.add(0, 'foo') | ||
.add(1, 'bar'); | ||
expect(index.search("foo")).to.include(0); | ||
expect(index.search("bar")).to.include(1); | ||
expect(index.encode("bâr")).to.equal("bar"); | ||
index.remove(0).update(1, 'foo').add(2, 'foobâr'); | ||
expect(index.search("foo")).to.have.members([1, 2]); | ||
expect(index.search("bar")).to.have.lengthOf(0); | ||
expect(index.search("foobar")).to.include(2); | ||
index.reset().add(0, 'foo').add(1, 'bar'); | ||
expect(index.search("foo")).to.include(0); | ||
expect(index.search("bar")).to.include(1); | ||
expect(index.search("foobar")).to.have.lengthOf(0); | ||
flexsearch_cache.destroy().init().add(0, 'foo').add(1, 'bar'); | ||
expect(flexsearch_cache.search("foo")).to.include(0); | ||
expect(flexsearch_cache.search("bar")).to.include(1); | ||
expect(flexsearch_cache.search("foobar")).to.have.lengthOf(0); | ||
}); | ||
}); | ||
/* Test Helpers */ | ||
@@ -620,0 +1029,0 @@ |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
121778
2126
719