Host FlexSearch
This commit is contained in:
32
paige/node_modules/flexsearch/src/_config/bundle/config.js
generated
vendored
Normal file
32
paige/node_modules/flexsearch/src/_config/bundle/config.js
generated
vendored
Normal file
@@ -0,0 +1,32 @@
|
||||
/** @define {boolean} */
|
||||
export const DEBUG = false;
|
||||
|
||||
/** @define {boolean} */
|
||||
export const POLYFILL = false;
|
||||
|
||||
/** @define {boolean} */
|
||||
export const SUPPORT_WORKER = true;
|
||||
|
||||
/** @define {boolean|string} */
|
||||
export const SUPPORT_ENCODER = true;
|
||||
|
||||
/** @define {boolean} */
|
||||
export const SUPPORT_CACHE = true;
|
||||
|
||||
/** @define {boolean} */
|
||||
export const SUPPORT_ASYNC = true;
|
||||
|
||||
/** @define {boolean} */
|
||||
export const SUPPORT_STORE = true;
|
||||
|
||||
/** @define {boolean} */
|
||||
export const SUPPORT_TAGS = true;
|
||||
|
||||
/** @define {boolean} */
|
||||
export const SUPPORT_SUGGESTION = true;
|
||||
|
||||
/** @define {boolean} */
|
||||
export const SUPPORT_SERIALIZE = true;
|
||||
|
||||
/** @define {boolean} */
|
||||
export const SUPPORT_DOCUMENT = true;
|
32
paige/node_modules/flexsearch/src/_config/compact/config.js
generated
vendored
Normal file
32
paige/node_modules/flexsearch/src/_config/compact/config.js
generated
vendored
Normal file
@@ -0,0 +1,32 @@
|
||||
/** @define {boolean} */
|
||||
export const DEBUG = false;
|
||||
|
||||
/** @define {boolean} */
|
||||
export const POLYFILL = false;
|
||||
|
||||
/** @define {boolean} */
|
||||
export const SUPPORT_WORKER = false;
|
||||
|
||||
/** @define {boolean|string} */
|
||||
export const SUPPORT_ENCODER = true;
|
||||
|
||||
/** @define {boolean} */
|
||||
export const SUPPORT_CACHE = false;
|
||||
|
||||
/** @define {boolean} */
|
||||
export const SUPPORT_ASYNC = true;
|
||||
|
||||
/** @define {boolean} */
|
||||
export const SUPPORT_STORE = true;
|
||||
|
||||
/** @define {boolean} */
|
||||
export const SUPPORT_TAGS = false;
|
||||
|
||||
/** @define {boolean} */
|
||||
export const SUPPORT_SUGGESTION = true;
|
||||
|
||||
/** @define {boolean} */
|
||||
export const SUPPORT_SERIALIZE = false;
|
||||
|
||||
/** @define {boolean} */
|
||||
export const SUPPORT_DOCUMENT = true;
|
32
paige/node_modules/flexsearch/src/_config/debug/config.js
generated
vendored
Normal file
32
paige/node_modules/flexsearch/src/_config/debug/config.js
generated
vendored
Normal file
@@ -0,0 +1,32 @@
|
||||
/** @define {boolean} */
|
||||
export const DEBUG = true;
|
||||
|
||||
/** @define {boolean} */
|
||||
export const POLYFILL = false;
|
||||
|
||||
/** @define {boolean} */
|
||||
export const SUPPORT_WORKER = true;
|
||||
|
||||
/** @define {boolean|string} */
|
||||
export const SUPPORT_ENCODER = true;
|
||||
|
||||
/** @define {boolean} */
|
||||
export const SUPPORT_CACHE = true;
|
||||
|
||||
/** @define {boolean} */
|
||||
export const SUPPORT_ASYNC = true;
|
||||
|
||||
/** @define {boolean} */
|
||||
export const SUPPORT_STORE = true;
|
||||
|
||||
/** @define {boolean} */
|
||||
export const SUPPORT_TAGS = true;
|
||||
|
||||
/** @define {boolean} */
|
||||
export const SUPPORT_SUGGESTION = true;
|
||||
|
||||
/** @define {boolean} */
|
||||
export const SUPPORT_SERIALIZE = true;
|
||||
|
||||
/** @define {boolean} */
|
||||
export const SUPPORT_DOCUMENT = true;
|
32
paige/node_modules/flexsearch/src/_config/light/config.js
generated
vendored
Normal file
32
paige/node_modules/flexsearch/src/_config/light/config.js
generated
vendored
Normal file
@@ -0,0 +1,32 @@
|
||||
/** @define {boolean} */
|
||||
export const DEBUG = false;
|
||||
|
||||
/** @define {boolean} */
|
||||
export const POLYFILL = false;
|
||||
|
||||
/** @define {boolean} */
|
||||
export const SUPPORT_WORKER = false;
|
||||
|
||||
/** @define {boolean|string} */
|
||||
export const SUPPORT_ENCODER = false;
|
||||
|
||||
/** @define {boolean} */
|
||||
export const SUPPORT_CACHE = false;
|
||||
|
||||
/** @define {boolean} */
|
||||
export const SUPPORT_ASYNC = false;
|
||||
|
||||
/** @define {boolean} */
|
||||
export const SUPPORT_STORE = false;
|
||||
|
||||
/** @define {boolean} */
|
||||
export const SUPPORT_TAGS = false;
|
||||
|
||||
/** @define {boolean} */
|
||||
export const SUPPORT_SUGGESTION = false;
|
||||
|
||||
/** @define {boolean} */
|
||||
export const SUPPORT_SERIALIZE = false;
|
||||
|
||||
/** @define {boolean} */
|
||||
export const SUPPORT_DOCUMENT = false;
|
51
paige/node_modules/flexsearch/src/async.js
generated
vendored
Normal file
51
paige/node_modules/flexsearch/src/async.js
generated
vendored
Normal file
@@ -0,0 +1,51 @@
|
||||
import { IndexInterface, DocumentInterface } from "./type.js";
|
||||
//import { promise as Promise } from "./polyfill.js";
|
||||
import { is_function, is_object, is_string } from "./common.js";
|
||||
|
||||
export default function(prototype){
|
||||
|
||||
register(prototype, "add");
|
||||
register(prototype, "append");
|
||||
register(prototype, "search");
|
||||
register(prototype, "update");
|
||||
register(prototype, "remove");
|
||||
}
|
||||
|
||||
function register(prototype, key){
|
||||
|
||||
prototype[key + "Async"] = function(){
|
||||
|
||||
/** @type {IndexInterface|DocumentInterface} */
|
||||
const self = this;
|
||||
const args = /*[].slice.call*/(arguments);
|
||||
const arg = args[args.length - 1];
|
||||
let callback;
|
||||
|
||||
if(is_function(arg)){
|
||||
|
||||
callback = arg;
|
||||
delete args[args.length - 1];
|
||||
}
|
||||
|
||||
const promise = new Promise(function(resolve){
|
||||
|
||||
setTimeout(function(){
|
||||
|
||||
self.async = true;
|
||||
const res = self[key].apply(self, args);
|
||||
self.async = false;
|
||||
resolve(res);
|
||||
});
|
||||
});
|
||||
|
||||
if(callback){
|
||||
|
||||
promise.then(callback);
|
||||
return this;
|
||||
}
|
||||
else{
|
||||
|
||||
return promise;
|
||||
}
|
||||
};
|
||||
}
|
169
paige/node_modules/flexsearch/src/cache.js
generated
vendored
Normal file
169
paige/node_modules/flexsearch/src/cache.js
generated
vendored
Normal file
@@ -0,0 +1,169 @@
|
||||
import { IndexInterface, DocumentInterface } from "./type.js";
|
||||
import { create_object, is_object } from "./common.js";
|
||||
|
||||
/**
|
||||
* @param {boolean|number=} limit
|
||||
* @constructor
|
||||
*/
|
||||
|
||||
function CacheClass(limit){
|
||||
|
||||
/** @private */
|
||||
this.limit = (limit !== true) && limit;
|
||||
|
||||
/** @private */
|
||||
this.cache = create_object();
|
||||
|
||||
/** @private */
|
||||
this.queue = [];
|
||||
|
||||
//this.clear();
|
||||
}
|
||||
|
||||
export default CacheClass;
|
||||
|
||||
/**
|
||||
* @param {string|Object} query
|
||||
* @param {number|Object=} limit
|
||||
* @param {Object=} options
|
||||
* @this {IndexInterface}
|
||||
* @returns {Array<number|string>}
|
||||
*/
|
||||
|
||||
export function searchCache(query, limit, options){
|
||||
|
||||
if(is_object(query)){
|
||||
|
||||
query = query["query"];
|
||||
}
|
||||
|
||||
let cache = this.cache.get(query);
|
||||
|
||||
if(!cache){
|
||||
|
||||
cache = this.search(query, limit, options);
|
||||
this.cache.set(query, cache);
|
||||
}
|
||||
|
||||
return cache;
|
||||
}
|
||||
|
||||
// CacheClass.prototype.clear = function(){
|
||||
//
|
||||
// /** @private */
|
||||
// this.cache = create_object();
|
||||
//
|
||||
// /** @private */
|
||||
// this.queue = [];
|
||||
// };
|
||||
|
||||
CacheClass.prototype.set = function(key, value){
|
||||
|
||||
if(!this.cache[key]){
|
||||
|
||||
// it is just a shame that native function array.shift() performs so bad
|
||||
|
||||
// const length = this.queue.length;
|
||||
//
|
||||
// this.queue[length] = key;
|
||||
//
|
||||
// if(length === this.limit){
|
||||
//
|
||||
// delete this.cache[this.queue.shift()];
|
||||
// }
|
||||
|
||||
// the same bad performance
|
||||
|
||||
// this.queue.unshift(key);
|
||||
//
|
||||
// if(this.queue.length === this.limit){
|
||||
//
|
||||
// this.queue.pop();
|
||||
// }
|
||||
|
||||
// fast implementation variant
|
||||
|
||||
// let length = this.queue.length;
|
||||
//
|
||||
// if(length === this.limit){
|
||||
//
|
||||
// length--;
|
||||
//
|
||||
// delete this.cache[this.queue[0]];
|
||||
//
|
||||
// for(let x = 0; x < length; x++){
|
||||
//
|
||||
// this.queue[x] = this.queue[x + 1];
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// this.queue[length] = key;
|
||||
|
||||
// current fastest implementation variant
|
||||
// theoretically that should not perform better compared to the example above
|
||||
|
||||
let length = this.queue.length;
|
||||
|
||||
if(length === this.limit){
|
||||
|
||||
delete this.cache[this.queue[length - 1]];
|
||||
}
|
||||
else{
|
||||
|
||||
length++;
|
||||
}
|
||||
|
||||
for(let x = length - 1; x > 0; x--){
|
||||
|
||||
this.queue[x] = this.queue[x - 1];
|
||||
}
|
||||
|
||||
this.queue[0] = key;
|
||||
}
|
||||
|
||||
this.cache[key] = value;
|
||||
};
|
||||
|
||||
CacheClass.prototype.get = function(key){
|
||||
|
||||
const cache = this.cache[key];
|
||||
|
||||
if(this.limit && cache){
|
||||
|
||||
// probably the indexOf() method performs faster when matched content is on front (left-to-right)
|
||||
// using lastIndexOf() does not help, it performs almost slower
|
||||
|
||||
const pos = this.queue.indexOf(key);
|
||||
|
||||
// if(pos < this.queue.length - 1){
|
||||
//
|
||||
// const tmp = this.queue[pos];
|
||||
// this.queue[pos] = this.queue[pos + 1];
|
||||
// this.queue[pos + 1] = tmp;
|
||||
// }
|
||||
|
||||
if(pos){
|
||||
|
||||
const tmp = this.queue[pos - 1];
|
||||
this.queue[pos - 1] = this.queue[pos];
|
||||
this.queue[pos] = tmp;
|
||||
}
|
||||
}
|
||||
|
||||
return cache;
|
||||
};
|
||||
|
||||
CacheClass.prototype.del = function(id){
|
||||
|
||||
for(let i = 0, item, key; i < this.queue.length; i++){
|
||||
|
||||
key = this.queue[i];
|
||||
item = this.cache[key];
|
||||
|
||||
if(item.includes(id)){
|
||||
|
||||
this.queue.splice(i--, 1);
|
||||
delete this.cache[key];
|
||||
}
|
||||
}
|
||||
};
|
78
paige/node_modules/flexsearch/src/common.js
generated
vendored
Normal file
78
paige/node_modules/flexsearch/src/common.js
generated
vendored
Normal file
@@ -0,0 +1,78 @@
|
||||
export function parse_option(value, default_value){
|
||||
|
||||
return typeof value !== "undefined" ? value : default_value;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {!number} count
|
||||
* @returns {Array<Object>}
|
||||
*/
|
||||
|
||||
export function create_object_array(count){
|
||||
|
||||
const array = new Array(count);
|
||||
|
||||
for(let i = 0; i < count; i++){
|
||||
|
||||
array[i] = create_object();
|
||||
}
|
||||
|
||||
return array;
|
||||
}
|
||||
|
||||
export function create_arrays(count){
|
||||
|
||||
const array = new Array(count);
|
||||
|
||||
for(let i = 0; i < count; i++){
|
||||
|
||||
array[i] = [];
|
||||
}
|
||||
|
||||
return array;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {!Object} obj
|
||||
* @returns {Array<string>}
|
||||
*/
|
||||
|
||||
export function get_keys(obj){
|
||||
|
||||
return Object.keys(obj);
|
||||
}
|
||||
|
||||
export function create_object(){
|
||||
|
||||
return Object.create(null);
|
||||
}
|
||||
|
||||
export function concat(arrays){
|
||||
|
||||
return [].concat.apply([], arrays);
|
||||
}
|
||||
|
||||
export function sort_by_length_down(a, b){
|
||||
|
||||
return b.length - a.length;
|
||||
}
|
||||
|
||||
export function is_array(val){
|
||||
|
||||
return val.constructor === Array;
|
||||
}
|
||||
|
||||
export function is_string(val){
|
||||
|
||||
return typeof val === "string";
|
||||
}
|
||||
|
||||
export function is_object(val){
|
||||
|
||||
return typeof val === "object";
|
||||
}
|
||||
|
||||
export function is_function(val){
|
||||
|
||||
return typeof val === "function";
|
||||
}
|
35
paige/node_modules/flexsearch/src/config.js
generated
vendored
Normal file
35
paige/node_modules/flexsearch/src/config.js
generated
vendored
Normal file
@@ -0,0 +1,35 @@
|
||||
/** @define {string} */
|
||||
export const RELEASE = "custom";
|
||||
|
||||
/** @define {boolean} */
|
||||
export const DEBUG = false;
|
||||
|
||||
/** @define {boolean} */
|
||||
export const POLYFILL = true;
|
||||
|
||||
/** @define {boolean} */
|
||||
export const SUPPORT_WORKER = true;
|
||||
|
||||
/** @define {boolean|string} */
|
||||
export const SUPPORT_ENCODER = true;
|
||||
|
||||
/** @define {boolean} */
|
||||
export const SUPPORT_CACHE = true;
|
||||
|
||||
/** @define {boolean} */
|
||||
export const SUPPORT_ASYNC = true;
|
||||
|
||||
/** @define {boolean} */
|
||||
export const SUPPORT_STORE = true;
|
||||
|
||||
/** @define {boolean} */
|
||||
export const SUPPORT_TAGS = true;
|
||||
|
||||
/** @define {boolean} */
|
||||
export const SUPPORT_SUGGESTION = true;
|
||||
|
||||
/** @define {boolean} */
|
||||
export const SUPPORT_SERIALIZE = true;
|
||||
|
||||
/** @define {boolean} */
|
||||
export const SUPPORT_DOCUMENT = true;
|
790
paige/node_modules/flexsearch/src/document.js
generated
vendored
Normal file
790
paige/node_modules/flexsearch/src/document.js
generated
vendored
Normal file
@@ -0,0 +1,790 @@
|
||||
/**!
|
||||
* FlexSearch.js
|
||||
* Author and Copyright: Thomas Wilkerling
|
||||
* Licence: Apache-2.0
|
||||
* Hosted by Nextapps GmbH
|
||||
* https://github.com/nextapps-de/flexsearch
|
||||
*/
|
||||
|
||||
// COMPILER BLOCK -->
|
||||
import {
|
||||
|
||||
SUPPORT_ASYNC,
|
||||
SUPPORT_CACHE,
|
||||
SUPPORT_SERIALIZE,
|
||||
SUPPORT_STORE,
|
||||
SUPPORT_TAGS,
|
||||
SUPPORT_WORKER
|
||||
|
||||
} from "./config.js";
|
||||
// <-- COMPILER BLOCK
|
||||
|
||||
import Index from "./index.js";
|
||||
import { DocumentInterface } from "./type.js";
|
||||
import Cache, { searchCache } from "./cache.js";
|
||||
import { create_object, is_array, is_string, is_object, parse_option, get_keys } from "./common.js";
|
||||
import apply_async from "./async.js";
|
||||
import { intersect, intersect_union } from "./intersect.js";
|
||||
import { exportDocument, importDocument } from "./serialize.js";
|
||||
import WorkerIndex from "./worker/index.js";
|
||||
|
||||
/**
|
||||
* @constructor
|
||||
* @implements {DocumentInterface}
|
||||
* @param {Object=} options
|
||||
* @return {Document}
|
||||
*/
|
||||
|
||||
function Document(options){
|
||||
|
||||
if(!(this instanceof Document)) {
|
||||
|
||||
return new Document(options);
|
||||
}
|
||||
|
||||
const document = options["document"] || options["doc"] || options;
|
||||
let opt;
|
||||
|
||||
this.tree = [];
|
||||
this.field = [];
|
||||
this.marker = [];
|
||||
this.register = create_object();
|
||||
this.key = ((opt = document["key"] || document["id"]) && parse_tree(opt, this.marker)) || "id";
|
||||
this.fastupdate = parse_option(options["fastupdate"], true);
|
||||
|
||||
if(SUPPORT_STORE){
|
||||
|
||||
this.storetree = (opt = document["store"]) && (opt !== true) && [];
|
||||
this.store = opt && create_object();
|
||||
}
|
||||
|
||||
if(SUPPORT_TAGS){
|
||||
|
||||
// TODO case-insensitive tags
|
||||
|
||||
this.tag = ((opt = document["tag"]) && parse_tree(opt, this.marker));
|
||||
this.tagindex = opt && create_object();
|
||||
}
|
||||
|
||||
if(SUPPORT_CACHE){
|
||||
|
||||
this.cache = (opt = options["cache"]) && new Cache(opt);
|
||||
|
||||
// do not apply cache again for the indexes
|
||||
|
||||
options["cache"] = false;
|
||||
}
|
||||
|
||||
if(SUPPORT_WORKER){
|
||||
|
||||
this.worker = options["worker"];
|
||||
}
|
||||
|
||||
if(SUPPORT_ASYNC){
|
||||
|
||||
// this switch is used by recall of promise callbacks
|
||||
|
||||
this.async = false;
|
||||
}
|
||||
|
||||
/** @export */
|
||||
this.index = parse_descriptor.call(this, options, document);
|
||||
}
|
||||
|
||||
export default Document;
|
||||
|
||||
/**
|
||||
* @this Document
|
||||
*/
|
||||
|
||||
function parse_descriptor(options, document){
|
||||
|
||||
const index = create_object();
|
||||
let field = document["index"] || document["field"] || document;
|
||||
|
||||
if(is_string(field)){
|
||||
|
||||
field = [field];
|
||||
}
|
||||
|
||||
for(let i = 0, key, opt; i < field.length; i++){
|
||||
|
||||
key = field[i];
|
||||
|
||||
if(!is_string(key)){
|
||||
|
||||
opt = key;
|
||||
key = key["field"];
|
||||
}
|
||||
|
||||
opt = is_object(opt) ? Object.assign({}, options, opt) : options;
|
||||
|
||||
if(SUPPORT_WORKER && this.worker){
|
||||
|
||||
index[key] = new WorkerIndex(opt);
|
||||
|
||||
if(!index[key].worker){
|
||||
|
||||
this.worker = false;
|
||||
}
|
||||
}
|
||||
|
||||
if(!this.worker){
|
||||
|
||||
index[key] = new Index(opt, this.register);
|
||||
}
|
||||
|
||||
this.tree[i] = parse_tree(key, this.marker);
|
||||
this.field[i] = key;
|
||||
}
|
||||
|
||||
if(SUPPORT_STORE && this.storetree){
|
||||
|
||||
let store = document["store"];
|
||||
|
||||
if(is_string(store)){
|
||||
|
||||
store = [store];
|
||||
}
|
||||
|
||||
for(let i = 0; i < store.length; i++){
|
||||
|
||||
this.storetree[i] = parse_tree(store[i], this.marker);
|
||||
}
|
||||
}
|
||||
|
||||
return index;
|
||||
}
|
||||
|
||||
function parse_tree(key, marker){
|
||||
|
||||
const tree = key.split(":");
|
||||
let count = 0;
|
||||
|
||||
for(let i = 0; i < tree.length; i++){
|
||||
|
||||
key = tree[i];
|
||||
|
||||
if(key.indexOf("[]") >= 0){
|
||||
|
||||
key = key.substring(0, key.length - 2);
|
||||
|
||||
if(key){
|
||||
|
||||
marker[count] = true;
|
||||
}
|
||||
}
|
||||
|
||||
if(key){
|
||||
|
||||
tree[count++] = key;
|
||||
}
|
||||
}
|
||||
|
||||
if(count < tree.length){
|
||||
|
||||
tree.length = count;
|
||||
}
|
||||
|
||||
return count > 1 ? tree : tree[0];
|
||||
}
|
||||
|
||||
// TODO support generic function created from string when tree depth > 1
|
||||
|
||||
function parse_simple(obj, tree){
|
||||
|
||||
if(is_string(tree)){
|
||||
|
||||
obj = obj[tree];
|
||||
}
|
||||
else{
|
||||
|
||||
for(let i = 0; obj && (i < tree.length); i++){
|
||||
|
||||
obj = obj[tree[i]];
|
||||
}
|
||||
}
|
||||
|
||||
return obj;
|
||||
}
|
||||
|
||||
// TODO support generic function created from string when tree depth > 1
|
||||
|
||||
function store_value(obj, store, tree, pos, key){
|
||||
|
||||
obj = obj[key];
|
||||
|
||||
// reached target field
|
||||
|
||||
if(pos === (tree.length - 1)){
|
||||
|
||||
// store target value
|
||||
|
||||
store[key] = obj;
|
||||
}
|
||||
else if(obj){
|
||||
|
||||
if(is_array(obj)){
|
||||
|
||||
store = store[key] = new Array(obj.length);
|
||||
|
||||
for(let i = 0; i < obj.length; i++){
|
||||
|
||||
// do not increase pos (an array is not a field)
|
||||
store_value(obj, store, tree, pos, i);
|
||||
}
|
||||
}
|
||||
else{
|
||||
|
||||
store = store[key] || (store[key] = create_object());
|
||||
key = tree[++pos];
|
||||
|
||||
store_value(obj, store, tree, pos, key);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function add_index(obj, tree, marker, pos, index, id, key, _append){
|
||||
|
||||
obj = obj[key];
|
||||
|
||||
if(obj){
|
||||
|
||||
// reached target field
|
||||
|
||||
if(pos === (tree.length - 1)){
|
||||
|
||||
// handle target value
|
||||
|
||||
if(is_array(obj)){
|
||||
|
||||
// append array contents so each entry gets a new scoring context
|
||||
|
||||
if(marker[pos]){
|
||||
|
||||
for(let i = 0; i < obj.length; i++){
|
||||
|
||||
index.add(id, obj[i], /* append: */ true, /* skip update: */ true);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
// or join array contents and use one scoring context
|
||||
|
||||
obj = obj.join(" ");
|
||||
}
|
||||
|
||||
index.add(id, obj, _append, /* skip_update: */ true);
|
||||
}
|
||||
else{
|
||||
|
||||
if(is_array(obj)){
|
||||
|
||||
for(let i = 0; i < obj.length; i++){
|
||||
|
||||
// do not increase index, an array is not a field
|
||||
|
||||
add_index(obj, tree, marker, pos, index, id, i, _append);
|
||||
}
|
||||
}
|
||||
else{
|
||||
|
||||
key = tree[++pos];
|
||||
|
||||
add_index(obj, tree, marker, pos, index, id, key, _append);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param id
|
||||
* @param content
|
||||
* @param {boolean=} _append
|
||||
* @returns {Document|Promise}
|
||||
*/
|
||||
|
||||
Document.prototype.add = function(id, content, _append){
|
||||
|
||||
if(is_object(id)){
|
||||
|
||||
content = id;
|
||||
id = parse_simple(content, this.key);
|
||||
}
|
||||
|
||||
if(content && (id || (id === 0))){
|
||||
|
||||
if(!_append && this.register[id]){
|
||||
|
||||
return this.update(id, content);
|
||||
}
|
||||
|
||||
for(let i = 0, tree, field; i < this.field.length; i++){
|
||||
|
||||
field = this.field[i];
|
||||
tree = this.tree[i];
|
||||
|
||||
if(is_string(tree)){
|
||||
|
||||
tree = [tree];
|
||||
}
|
||||
|
||||
add_index(content, tree, this.marker, 0, this.index[field], id, tree[0], _append);
|
||||
}
|
||||
|
||||
if(SUPPORT_TAGS && this.tag){
|
||||
|
||||
let tag = parse_simple(content, this.tag);
|
||||
let dupes = create_object();
|
||||
|
||||
if(is_string(tag)){
|
||||
|
||||
tag = [tag];
|
||||
}
|
||||
|
||||
for(let i = 0, key, arr; i < tag.length; i++){
|
||||
|
||||
key = tag[i];
|
||||
|
||||
if(!dupes[key]){
|
||||
|
||||
dupes[key] = 1;
|
||||
arr = this.tagindex[key] || (this.tagindex[key] = []);
|
||||
|
||||
if(!_append || !arr.includes(id)){
|
||||
|
||||
arr[arr.length] = id;
|
||||
|
||||
// add a reference to the register for fast updates
|
||||
|
||||
if(this.fastupdate){
|
||||
|
||||
const tmp = this.register[id] || (this.register[id] = []);
|
||||
tmp[tmp.length] = arr;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: how to handle store when appending contents?
|
||||
|
||||
if(SUPPORT_STORE && this.store && (!_append || !this.store[id])){
|
||||
|
||||
let store;
|
||||
|
||||
if(this.storetree){
|
||||
|
||||
store = create_object();
|
||||
|
||||
for(let i = 0, tree; i < this.storetree.length; i++){
|
||||
|
||||
tree = this.storetree[i];
|
||||
|
||||
if(is_string(tree)){
|
||||
|
||||
store[tree] = content[tree];
|
||||
}
|
||||
else{
|
||||
|
||||
store_value(content, store, tree, 0, tree[0]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
this.store[id] = store || content;
|
||||
}
|
||||
}
|
||||
|
||||
return this;
|
||||
};
|
||||
|
||||
Document.prototype.append = function(id, content){
|
||||
|
||||
return this.add(id, content, true);
|
||||
};
|
||||
|
||||
Document.prototype.update = function(id, content){
|
||||
|
||||
return this.remove(id).add(id, content);
|
||||
};
|
||||
|
||||
Document.prototype.remove = function(id){
|
||||
|
||||
if(is_object(id)){
|
||||
|
||||
id = parse_simple(id, this.key);
|
||||
}
|
||||
|
||||
if(this.register[id]){
|
||||
|
||||
for(let i = 0; i < this.field.length; i++){
|
||||
|
||||
// workers does not share the register
|
||||
|
||||
this.index[this.field[i]].remove(id, !this.worker);
|
||||
|
||||
if(this.fastupdate){
|
||||
|
||||
// when fastupdate was enabled all ids are removed
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if(SUPPORT_TAGS && this.tag){
|
||||
|
||||
// when fastupdate was enabled all ids are already removed
|
||||
|
||||
if(!this.fastupdate){
|
||||
|
||||
for(let key in this.tagindex){
|
||||
|
||||
const tag = this.tagindex[key];
|
||||
const pos = tag.indexOf(id);
|
||||
|
||||
if(pos !== -1){
|
||||
|
||||
if(tag.length > 1){
|
||||
|
||||
tag.splice(pos, 1);
|
||||
}
|
||||
else{
|
||||
|
||||
delete this.tagindex[key];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(SUPPORT_STORE && this.store){
|
||||
|
||||
delete this.store[id];
|
||||
}
|
||||
|
||||
delete this.register[id];
|
||||
}
|
||||
|
||||
return this;
|
||||
};
|
||||
|
||||
/**
|
||||
* @param {!string|Object} query
|
||||
* @param {number|Object=} limit
|
||||
* @param {Object=} options
|
||||
* @param {Array<Array>=} _resolve For internal use only.
|
||||
* @returns {Promise|Array}
|
||||
*/
|
||||
|
||||
Document.prototype.search = function(query, limit, options, _resolve){
|
||||
|
||||
if(!options){
|
||||
|
||||
if(!limit && is_object(query)){
|
||||
|
||||
options = /** @type {Object} */ (query);
|
||||
query = "";
|
||||
}
|
||||
else if(is_object(limit)){
|
||||
|
||||
options = /** @type {Object} */ (limit);
|
||||
limit = 0;
|
||||
}
|
||||
}
|
||||
|
||||
let result = [], result_field = [];
|
||||
let pluck, enrich;
|
||||
let field, tag, bool, offset, count = 0;
|
||||
|
||||
if(options){
|
||||
|
||||
if(is_array(options)){
|
||||
|
||||
field = options;
|
||||
options = null;
|
||||
}
|
||||
else{
|
||||
|
||||
query = options["query"] || query;
|
||||
pluck = options["pluck"];
|
||||
field = pluck || options["index"] || options["field"] /*|| (is_string(options) && [options])*/;
|
||||
tag = SUPPORT_TAGS && options["tag"];
|
||||
enrich = SUPPORT_STORE && this.store && options["enrich"];
|
||||
bool = options["bool"] === "and";
|
||||
limit = options["limit"] || limit || 100;
|
||||
offset = options["offset"] || 0;
|
||||
|
||||
if(tag){
|
||||
|
||||
if(is_string(tag)){
|
||||
|
||||
tag = [tag];
|
||||
}
|
||||
|
||||
// when tags is used and no query was set,
|
||||
// then just return the tag indexes
|
||||
|
||||
if(!query){
|
||||
|
||||
for(let i = 0, res; i < tag.length; i++){
|
||||
|
||||
res = get_tag.call(this, tag[i], limit, offset, enrich);
|
||||
|
||||
if(res){
|
||||
|
||||
result[result.length] = res;
|
||||
count++;
|
||||
}
|
||||
}
|
||||
|
||||
return count ? result : [];
|
||||
}
|
||||
}
|
||||
|
||||
if(is_string(field)){
|
||||
|
||||
field = [field];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
field || (field = this.field);
|
||||
bool = bool && ((field.length > 1) || (tag && (tag.length > 1)));
|
||||
|
||||
const promises = !_resolve && (this.worker || this.async) && [];
|
||||
|
||||
// TODO solve this in one loop below
|
||||
|
||||
for(let i = 0, res, key, len; i < field.length; i++){
|
||||
|
||||
let field_options;
|
||||
|
||||
key = field[i];
|
||||
|
||||
if(!is_string(key)){
|
||||
|
||||
field_options = key;
|
||||
key = field_options["field"];
|
||||
query = field_options["query"] || query;
|
||||
limit = field_options["limit"] || limit;
|
||||
enrich = field_options["enrich"] || enrich;
|
||||
}
|
||||
|
||||
if(promises){
|
||||
|
||||
promises[i] = this.index[key].searchAsync(query, limit, field_options || options);
|
||||
|
||||
// just collect and continue
|
||||
|
||||
continue;
|
||||
}
|
||||
else if(_resolve){
|
||||
|
||||
res = _resolve[i];
|
||||
}
|
||||
else{
|
||||
|
||||
// inherit options also when search? it is just for laziness, Object.assign() has a cost
|
||||
|
||||
res = this.index[key].search(query, limit, field_options || options);
|
||||
}
|
||||
|
||||
len = res && res.length;
|
||||
|
||||
if(tag && len){
|
||||
|
||||
const arr = [];
|
||||
let count = 0;
|
||||
|
||||
if(bool){
|
||||
|
||||
// prepare for intersection
|
||||
|
||||
arr[0] = [res];
|
||||
}
|
||||
|
||||
for(let y = 0, key, res; y < tag.length; y++){
|
||||
|
||||
key = tag[y];
|
||||
res = this.tagindex[key];
|
||||
len = res && res.length;
|
||||
|
||||
if(len){
|
||||
|
||||
count++;
|
||||
arr[arr.length] = bool ? [res] : res;
|
||||
}
|
||||
}
|
||||
|
||||
if(count){
|
||||
|
||||
if(bool){
|
||||
|
||||
res = intersect(arr, limit || 100, offset || 0);
|
||||
}
|
||||
else{
|
||||
|
||||
res = intersect_union(res, arr);
|
||||
}
|
||||
|
||||
len = res.length;
|
||||
}
|
||||
}
|
||||
|
||||
if(len){
|
||||
|
||||
result_field[count] = key;
|
||||
result[count++] = res;
|
||||
}
|
||||
else if(bool){
|
||||
|
||||
return [];
|
||||
}
|
||||
}
|
||||
|
||||
if(promises){
|
||||
|
||||
const self = this;
|
||||
|
||||
// anyone knows a better workaround of optionally having async promises?
|
||||
// the promise.all() needs to be wrapped into additional promise,
|
||||
// otherwise the recursive callback wouldn't run before return
|
||||
|
||||
return new Promise(function(resolve){
|
||||
|
||||
Promise.all(promises).then(function(result){
|
||||
|
||||
resolve(self.search(query, limit, options, result));
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
if(!count){
|
||||
|
||||
// fast path "not found"
|
||||
|
||||
return [];
|
||||
}
|
||||
|
||||
if(pluck && (!enrich || !this.store)){
|
||||
|
||||
// fast path optimization
|
||||
|
||||
return result[0];
|
||||
}
|
||||
|
||||
for(let i = 0, res; i < result_field.length; i++){
|
||||
|
||||
res = result[i];
|
||||
|
||||
if(res.length){
|
||||
|
||||
if(enrich){
|
||||
|
||||
res = apply_enrich.call(this, res);
|
||||
}
|
||||
}
|
||||
|
||||
if(pluck){
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
result[i] = {
|
||||
|
||||
"field": result_field[i],
|
||||
"result": res
|
||||
};
|
||||
}
|
||||
|
||||
return result;
|
||||
};
|
||||
|
||||
/**
|
||||
* @this Document
|
||||
*/
|
||||
|
||||
function get_tag(key, limit, offset, enrich){
|
||||
|
||||
let res = this.tagindex[key];
|
||||
let len = res && (res.length - offset);
|
||||
|
||||
if(len && (len > 0)){
|
||||
|
||||
if((len > limit) || offset){
|
||||
|
||||
res = res.slice(offset, offset + limit);
|
||||
}
|
||||
|
||||
if(enrich){
|
||||
|
||||
res = apply_enrich.call(this, res);
|
||||
}
|
||||
|
||||
return {
|
||||
|
||||
"tag": key,
|
||||
"result": res
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @this Document
|
||||
*/
|
||||
|
||||
function apply_enrich(res){
|
||||
|
||||
const arr = new Array(res.length);
|
||||
|
||||
for(let x = 0, id; x < res.length; x++){
|
||||
|
||||
id = res[x];
|
||||
|
||||
arr[x] = {
|
||||
|
||||
"id": id,
|
||||
"doc": this.store[id]
|
||||
};
|
||||
}
|
||||
|
||||
return arr;
|
||||
}
|
||||
|
||||
Document.prototype.contain = function(id){
|
||||
|
||||
return !!this.register[id];
|
||||
};
|
||||
|
||||
if(SUPPORT_STORE){
|
||||
|
||||
Document.prototype.get = function(id){
|
||||
|
||||
return this.store[id];
|
||||
};
|
||||
|
||||
Document.prototype.set = function(id, data){
|
||||
|
||||
this.store[id] = data;
|
||||
return this;
|
||||
};
|
||||
}
|
||||
|
||||
if(SUPPORT_CACHE){
|
||||
|
||||
Document.prototype.searchCache = searchCache;
|
||||
}
|
||||
|
||||
if(SUPPORT_SERIALIZE){
|
||||
|
||||
Document.prototype.export = exportDocument;
|
||||
Document.prototype.import = importDocument;
|
||||
}
|
||||
|
||||
if(SUPPORT_ASYNC){
|
||||
|
||||
apply_async(Document.prototype);
|
||||
}
|
49
paige/node_modules/flexsearch/src/engine.js
generated
vendored
Normal file
49
paige/node_modules/flexsearch/src/engine.js
generated
vendored
Normal file
@@ -0,0 +1,49 @@
|
||||
// COMPILER BLOCK -->
|
||||
import { DEBUG, SUPPORT_ASYNC, SUPPORT_CACHE } from "./config";
|
||||
// <-- COMPILER BLOCK
|
||||
import { searchCache } from "./cache";
|
||||
|
||||
/**
|
||||
* @constructor
|
||||
* @abstract
|
||||
*/
|
||||
|
||||
function Engine(index){
|
||||
|
||||
if(DEBUG){
|
||||
|
||||
//if(this.constructor === Engine){
|
||||
if(this instanceof Engine){
|
||||
|
||||
throw new Error("Can't instantiate abstract class!");
|
||||
}
|
||||
}
|
||||
|
||||
if(SUPPORT_CACHE){
|
||||
|
||||
index.prototype.searchCache = searchCache;
|
||||
}
|
||||
|
||||
if(SUPPORT_ASYNC){
|
||||
|
||||
index.prototype.addAsync = addAsync;
|
||||
index.prototype.appendAsync = appendAsync;
|
||||
index.prototype.searchAsync = searchAsync;
|
||||
index.prototype.updateAsync = updateAsync;
|
||||
index.prototype.removeAsync = removeAsync;
|
||||
}
|
||||
}
|
||||
|
||||
if(SUPPORT_CACHE){
|
||||
|
||||
Engine.prototype.searchCache = searchCache;
|
||||
}
|
||||
|
||||
if(SUPPORT_ASYNC){
|
||||
|
||||
Engine.prototype.addAsync = addAsync;
|
||||
Engine.prototype.appendAsync = appendAsync;
|
||||
Engine.prototype.searchAsync = searchAsync;
|
||||
Engine.prototype.updateAsync = updateAsync;
|
||||
Engine.prototype.removeAsync = removeAsync;
|
||||
}
|
22
paige/node_modules/flexsearch/src/global.js
generated
vendored
Normal file
22
paige/node_modules/flexsearch/src/global.js
generated
vendored
Normal file
@@ -0,0 +1,22 @@
|
||||
export const global_lang = {};
|
||||
export const global_charset = {};
|
||||
|
||||
/**
|
||||
* @param {!string} name
|
||||
* @param {Object} charset
|
||||
*/
|
||||
|
||||
export function registerCharset(name, charset){
|
||||
|
||||
global_charset[name] = charset;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {!string} name
|
||||
* @param {Object} lang
|
||||
*/
|
||||
|
||||
export function registerLanguage(name, lang){
|
||||
|
||||
global_lang[name] = lang;
|
||||
}
|
823
paige/node_modules/flexsearch/src/index.js
generated
vendored
Normal file
823
paige/node_modules/flexsearch/src/index.js
generated
vendored
Normal file
@@ -0,0 +1,823 @@
|
||||
/**!
|
||||
* FlexSearch.js
|
||||
* Author and Copyright: Thomas Wilkerling
|
||||
* Licence: Apache-2.0
|
||||
* Hosted by Nextapps GmbH
|
||||
* https://github.com/nextapps-de/flexsearch
|
||||
*/
|
||||
|
||||
// COMPILER BLOCK -->
|
||||
import {
|
||||
|
||||
SUPPORT_ENCODER,
|
||||
SUPPORT_CACHE,
|
||||
SUPPORT_ASYNC,
|
||||
SUPPORT_SUGGESTION,
|
||||
SUPPORT_SERIALIZE
|
||||
|
||||
} from "./config.js";
|
||||
// <-- COMPILER BLOCK
|
||||
|
||||
import { IndexInterface } from "./type.js";
|
||||
import { encode as default_encoder } from "./lang/latin/default.js";
|
||||
import { create_object, create_object_array, concat, sort_by_length_down, is_array, is_string, is_object, parse_option } from "./common.js";
|
||||
import { pipeline, init_stemmer_or_matcher, init_filter } from "./lang.js";
|
||||
import { global_lang, global_charset } from "./global.js";
|
||||
import apply_async from "./async.js";
|
||||
import { intersect } from "./intersect.js";
|
||||
import Cache, { searchCache } from "./cache.js";
|
||||
import apply_preset from "./preset.js";
|
||||
import { exportIndex, importIndex } from "./serialize.js";
|
||||
|
||||
/**
|
||||
* @constructor
|
||||
* @implements IndexInterface
|
||||
* @param {Object=} options
|
||||
* @param {Object=} _register
|
||||
* @return {Index}
|
||||
*/
|
||||
|
||||
function Index(options, _register){
|
||||
|
||||
if(!(this instanceof Index)) {
|
||||
|
||||
return new Index(options);
|
||||
}
|
||||
|
||||
let charset, lang, tmp;
|
||||
|
||||
if(options){
|
||||
|
||||
if(SUPPORT_ENCODER){
|
||||
|
||||
options = apply_preset(options);
|
||||
}
|
||||
|
||||
charset = options["charset"];
|
||||
lang = options["lang"];
|
||||
|
||||
if(is_string(charset)){
|
||||
|
||||
if(charset.indexOf(":") === -1){
|
||||
|
||||
charset += ":default";
|
||||
}
|
||||
|
||||
charset = global_charset[charset];
|
||||
}
|
||||
|
||||
if(is_string(lang)){
|
||||
|
||||
lang = global_lang[lang];
|
||||
}
|
||||
}
|
||||
else{
|
||||
|
||||
options = {};
|
||||
}
|
||||
|
||||
let resolution, optimize, context = options["context"] || {};
|
||||
|
||||
this.encode = options["encode"] || (charset && charset.encode) || default_encoder;
|
||||
this.register = _register || create_object();
|
||||
this.resolution = resolution = options["resolution"] || 9;
|
||||
this.tokenize = tmp = (charset && charset.tokenize) || options["tokenize"] || "strict";
|
||||
this.depth = (tmp === "strict") && context["depth"];
|
||||
this.bidirectional = parse_option(context["bidirectional"], true);
|
||||
this.optimize = optimize = parse_option(options["optimize"], true);
|
||||
this.fastupdate = parse_option(options["fastupdate"], true);
|
||||
this.minlength = options["minlength"] || 1;
|
||||
this.boost = options["boost"];
|
||||
|
||||
// when not using the memory strategy the score array should not pre-allocated to its full length
|
||||
|
||||
this.map = optimize ? create_object_array(resolution) : create_object();
|
||||
this.resolution_ctx = resolution = context["resolution"] || 1;
|
||||
this.ctx = optimize ? create_object_array(resolution) : create_object();
|
||||
this.rtl = (charset && charset.rtl) || options["rtl"];
|
||||
this.matcher = (tmp = options["matcher"] || (lang && lang.matcher)) && init_stemmer_or_matcher(tmp, false);
|
||||
this.stemmer = (tmp = options["stemmer"] || (lang && lang.stemmer)) && init_stemmer_or_matcher(tmp, true);
|
||||
this.filter = (tmp = options["filter"] || (lang && lang.filter)) && init_filter(tmp);
|
||||
|
||||
if(SUPPORT_CACHE){
|
||||
|
||||
this.cache = (tmp = options["cache"]) && new Cache(tmp);
|
||||
}
|
||||
}
|
||||
|
||||
export default Index;
|
||||
|
||||
//Index.prototype.pipeline = pipeline;
|
||||
|
||||
/**
|
||||
* @param {!number|string} id
|
||||
* @param {!string} content
|
||||
*/
|
||||
|
||||
Index.prototype.append = function(id, content){
|
||||
|
||||
return this.add(id, content, true);
|
||||
};
|
||||
|
||||
// TODO:
|
||||
// string + number as text
|
||||
// boolean, null, undefined as ?
|
||||
|
||||
/**
|
||||
* @param {!number|string} id
|
||||
* @param {!string} content
|
||||
* @param {boolean=} _append
|
||||
* @param {boolean=} _skip_update
|
||||
*/
|
||||
|
||||
Index.prototype.add = function(id, content, _append, _skip_update){
|
||||
|
||||
if(content && (id || (id === 0))){
|
||||
|
||||
if(!_skip_update && !_append && this.register[id]){
|
||||
|
||||
return this.update(id, content);
|
||||
}
|
||||
|
||||
content = this.encode("" + content);
|
||||
const length = content.length;
|
||||
|
||||
if(length){
|
||||
|
||||
// check context dupes to skip all contextual redundancy along a document
|
||||
|
||||
const dupes_ctx = create_object();
|
||||
const dupes = create_object();
|
||||
const depth = this.depth;
|
||||
const resolution = this.resolution;
|
||||
|
||||
for(let i = 0; i < length; i++){
|
||||
|
||||
let term = content[this.rtl ? length - 1 - i : i];
|
||||
let term_length = term.length;
|
||||
|
||||
// skip dupes will break the context chain
|
||||
|
||||
if(term && (term_length >= this.minlength) && (depth || !dupes[term])){
|
||||
|
||||
let score = get_score(resolution, length, i);
|
||||
let token = "";
|
||||
|
||||
switch(this.tokenize){
|
||||
|
||||
case "full":
|
||||
|
||||
if(term_length > 2){
|
||||
|
||||
for(let x = 0; x < term_length; x++){
|
||||
|
||||
for(let y = term_length; y > x; y--){
|
||||
|
||||
if((y - x) >= this.minlength){
|
||||
|
||||
const partial_score = get_score(resolution, length, i, term_length, x);
|
||||
token = term.substring(x, y);
|
||||
this.push_index(dupes, token, partial_score, id, _append);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
// fallthrough to next case when term length < 3
|
||||
|
||||
case "reverse":
|
||||
|
||||
// skip last round (this token exist already in "forward")
|
||||
|
||||
if(term_length > 1){
|
||||
|
||||
for(let x = term_length - 1; x > 0; x--){
|
||||
|
||||
token = term[x] + token;
|
||||
|
||||
if(token.length >= this.minlength){
|
||||
|
||||
const partial_score = get_score(resolution, length, i, term_length, x);
|
||||
this.push_index(dupes, token, partial_score, id, _append);
|
||||
}
|
||||
}
|
||||
|
||||
token = "";
|
||||
}
|
||||
|
||||
// fallthrough to next case to apply forward also
|
||||
|
||||
case "forward":
|
||||
|
||||
if(term_length > 1){
|
||||
|
||||
for(let x = 0; x < term_length; x++){
|
||||
|
||||
token += term[x];
|
||||
|
||||
if(token.length >= this.minlength){
|
||||
|
||||
this.push_index(dupes, token, score, id, _append);
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
// fallthrough to next case when token has a length of 1
|
||||
|
||||
default:
|
||||
// case "strict":
|
||||
|
||||
if(this.boost){
|
||||
|
||||
score = Math.min((score / this.boost(content, term, i)) | 0, resolution - 1);
|
||||
}
|
||||
|
||||
this.push_index(dupes, term, score, id, _append);
|
||||
|
||||
// context is just supported by tokenizer "strict"
|
||||
|
||||
if(depth){
|
||||
|
||||
if((length > 1) && (i < (length - 1))){
|
||||
|
||||
// check inner dupes to skip repeating words in the current context
|
||||
|
||||
const dupes_inner = create_object();
|
||||
const resolution = this.resolution_ctx;
|
||||
const keyword = term;
|
||||
const size = Math.min(depth + 1, length - i);
|
||||
|
||||
dupes_inner[keyword] = 1;
|
||||
|
||||
for(let x = 1; x < size; x++){
|
||||
|
||||
term = content[this.rtl ? length - 1 - i - x : i + x];
|
||||
|
||||
if(term && (term.length >= this.minlength) && !dupes_inner[term]){
|
||||
|
||||
dupes_inner[term] = 1;
|
||||
|
||||
const context_score = get_score(resolution + ((length / 2) > resolution ? 0 : 1), length, i, size - 1, x - 1);
|
||||
const swap = this.bidirectional && (term > keyword);
|
||||
this.push_index(dupes_ctx, swap ? keyword : term, context_score, id, _append, swap ? term : keyword);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
this.fastupdate || (this.register[id] = 1);
|
||||
}
|
||||
}
|
||||
|
||||
return this;
|
||||
};
|
||||
|
||||
/**
|
||||
* @param {number} resolution
|
||||
* @param {number} length
|
||||
* @param {number} i
|
||||
* @param {number=} term_length
|
||||
* @param {number=} x
|
||||
* @returns {number}
|
||||
*/
|
||||
|
||||
function get_score(resolution, length, i, term_length, x){
|
||||
|
||||
// console.log("resolution", resolution);
|
||||
// console.log("length", length);
|
||||
// console.log("term_length", term_length);
|
||||
// console.log("i", i);
|
||||
// console.log("x", x);
|
||||
// console.log((resolution - 1) / (length + (term_length || 0)) * (i + (x || 0)) + 1);
|
||||
|
||||
// the first resolution slot is reserved for the best match,
|
||||
// when a query matches the first word(s).
|
||||
|
||||
// also to stretch score to the whole range of resolution, the
|
||||
// calculation is shift by one and cut the floating point.
|
||||
// this needs the resolution "1" to be handled additionally.
|
||||
|
||||
// do not stretch the resolution more than the term length will
|
||||
// improve performance and memory, also it improves scoring in
|
||||
// most cases between a short document and a long document
|
||||
|
||||
return i && (resolution > 1) ? (
|
||||
|
||||
(length + (term_length || 0)) <= resolution ?
|
||||
|
||||
i + (x || 0)
|
||||
:
|
||||
((resolution - 1) / (length + (term_length || 0)) * (i + (x || 0)) + 1) | 0
|
||||
):
|
||||
0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @private
|
||||
* @param dupes
|
||||
* @param value
|
||||
* @param score
|
||||
* @param id
|
||||
* @param {boolean=} append
|
||||
* @param {string=} keyword
|
||||
*/
|
||||
|
||||
Index.prototype.push_index = function(dupes, value, score, id, append, keyword){
|
||||
|
||||
let arr = keyword ? this.ctx : this.map;
|
||||
|
||||
if(!dupes[value] || (keyword && !dupes[value][keyword])){
|
||||
|
||||
if(this.optimize){
|
||||
|
||||
arr = arr[score];
|
||||
}
|
||||
|
||||
if(keyword){
|
||||
|
||||
dupes = dupes[value] || (dupes[value] = create_object());
|
||||
dupes[keyword] = 1;
|
||||
|
||||
arr = arr[keyword] || (arr[keyword] = create_object());
|
||||
}
|
||||
else{
|
||||
|
||||
dupes[value] = 1;
|
||||
}
|
||||
|
||||
arr = arr[value] || (arr[value] = []);
|
||||
|
||||
if(!this.optimize){
|
||||
|
||||
arr = arr[score] || (arr[score] = []);
|
||||
}
|
||||
|
||||
if(!append || !arr.includes(id)){
|
||||
|
||||
arr[arr.length] = id;
|
||||
|
||||
// add a reference to the register for fast updates
|
||||
|
||||
if(this.fastupdate){
|
||||
|
||||
const tmp = this.register[id] || (this.register[id] = []);
|
||||
tmp[tmp.length] = arr;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {string|Object} query
|
||||
* @param {number|Object=} limit
|
||||
* @param {Object=} options
|
||||
* @returns {Array<number|string>}
|
||||
*/
|
||||
|
||||
Index.prototype.search = function(query, limit, options){
|
||||
|
||||
if(!options){
|
||||
|
||||
if(!limit && is_object(query)){
|
||||
|
||||
options = /** @type {Object} */ (query);
|
||||
query = options["query"];
|
||||
}
|
||||
else if(is_object(limit)){
|
||||
|
||||
options = /** @type {Object} */ (limit);
|
||||
}
|
||||
}
|
||||
|
||||
let result = [];
|
||||
let length;
|
||||
let context, suggest, offset = 0;
|
||||
|
||||
if(options){
|
||||
|
||||
query = options["query"] || query;
|
||||
limit = options["limit"];
|
||||
offset = options["offset"] || 0;
|
||||
context = options["context"];
|
||||
suggest = SUPPORT_SUGGESTION && options["suggest"];
|
||||
}
|
||||
|
||||
if(query){
|
||||
|
||||
query = /** @type {Array} */ (this.encode("" + query));
|
||||
length = query.length;
|
||||
|
||||
// TODO: solve this in one single loop below
|
||||
|
||||
if(length > 1){
|
||||
|
||||
const dupes = create_object();
|
||||
const query_new = [];
|
||||
|
||||
for(let i = 0, count = 0, term; i < length; i++){
|
||||
|
||||
term = query[i];
|
||||
|
||||
if(term && (term.length >= this.minlength) && !dupes[term]){
|
||||
|
||||
// this fast path can just apply when not in memory-optimized mode
|
||||
|
||||
if(!this.optimize && !suggest && !this.map[term]){
|
||||
|
||||
// fast path "not found"
|
||||
|
||||
return result;
|
||||
}
|
||||
else{
|
||||
|
||||
query_new[count++] = term;
|
||||
dupes[term] = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
query = query_new;
|
||||
length = query.length;
|
||||
}
|
||||
}
|
||||
|
||||
if(!length){
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
limit || (limit = 100);
|
||||
|
||||
let depth = this.depth && (length > 1) && (context !== false);
|
||||
let index = 0, keyword;
|
||||
|
||||
if(depth){
|
||||
|
||||
keyword = query[0];
|
||||
index = 1;
|
||||
}
|
||||
else{
|
||||
|
||||
if(length > 1){
|
||||
|
||||
query.sort(sort_by_length_down);
|
||||
}
|
||||
}
|
||||
|
||||
for(let arr, term; index < length; index++){
|
||||
|
||||
term = query[index];
|
||||
|
||||
// console.log(keyword);
|
||||
// console.log(term);
|
||||
// console.log("");
|
||||
|
||||
if(depth){
|
||||
|
||||
arr = this.add_result(result, suggest, limit, offset, length === 2, term, keyword);
|
||||
|
||||
// console.log(arr);
|
||||
// console.log(result);
|
||||
|
||||
// when suggestion enabled just forward keyword if term was found
|
||||
// as long as the result is empty forward the pointer also
|
||||
|
||||
if(!suggest || (arr !== false) || !result.length){
|
||||
|
||||
keyword = term;
|
||||
}
|
||||
}
|
||||
else{
|
||||
|
||||
arr = this.add_result(result, suggest, limit, offset, length === 1, term);
|
||||
}
|
||||
|
||||
if(arr){
|
||||
|
||||
return /** @type {Array<number|string>} */ (arr);
|
||||
}
|
||||
|
||||
// apply suggestions on last loop or fallback
|
||||
|
||||
if(suggest && (index === length - 1)){
|
||||
|
||||
let length = result.length;
|
||||
|
||||
if(!length){
|
||||
|
||||
if(depth){
|
||||
|
||||
// fallback to non-contextual search when no result was found
|
||||
|
||||
depth = 0;
|
||||
index = -1;
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
else if(length === 1){
|
||||
|
||||
// fast path optimization
|
||||
|
||||
return single_result(result[0], limit, offset);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return intersect(result, limit, offset, suggest);
|
||||
};
|
||||
|
||||
/**
|
||||
* Returns an array when the result is done (to stop the process immediately),
|
||||
* returns false when suggestions is enabled and no result was found,
|
||||
* or returns nothing when a set was pushed successfully to the results
|
||||
*
|
||||
* @private
|
||||
* @param {Array} result
|
||||
* @param {Array} suggest
|
||||
* @param {number} limit
|
||||
* @param {number} offset
|
||||
* @param {boolean} single_term
|
||||
* @param {string} term
|
||||
* @param {string=} keyword
|
||||
* @return {Array<Array<string|number>>|boolean|undefined}
|
||||
*/
|
||||
|
||||
Index.prototype.add_result = function(result, suggest, limit, offset, single_term, term, keyword){
|
||||
|
||||
let word_arr = [];
|
||||
let arr = keyword ? this.ctx : this.map;
|
||||
|
||||
if(!this.optimize){
|
||||
|
||||
arr = get_array(arr, term, keyword, this.bidirectional);
|
||||
}
|
||||
|
||||
if(arr){
|
||||
|
||||
let count = 0;
|
||||
const arr_len = Math.min(arr.length, keyword ? this.resolution_ctx : this.resolution);
|
||||
|
||||
// relevance:
|
||||
for(let x = 0, size = 0, tmp, len; x < arr_len; x++){
|
||||
|
||||
tmp = arr[x];
|
||||
|
||||
if(tmp){
|
||||
|
||||
if(this.optimize){
|
||||
|
||||
tmp = get_array(tmp, term, keyword, this.bidirectional);
|
||||
}
|
||||
|
||||
if(offset){
|
||||
|
||||
if(tmp && single_term){
|
||||
|
||||
len = tmp.length;
|
||||
|
||||
if(len <= offset){
|
||||
|
||||
offset -= len;
|
||||
tmp = null;
|
||||
}
|
||||
else{
|
||||
|
||||
tmp = tmp.slice(offset);
|
||||
offset = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(tmp){
|
||||
|
||||
// keep score (sparse array):
|
||||
//word_arr[x] = tmp;
|
||||
|
||||
// simplified score order:
|
||||
word_arr[count++] = tmp;
|
||||
|
||||
if(single_term){
|
||||
|
||||
size += tmp.length;
|
||||
|
||||
if(size >= limit){
|
||||
|
||||
// fast path optimization
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(count){
|
||||
|
||||
if(single_term){
|
||||
|
||||
// fast path optimization
|
||||
// offset was already applied at this point
|
||||
|
||||
return single_result(word_arr, limit, 0);
|
||||
}
|
||||
|
||||
result[result.length] = word_arr;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// return an empty array will stop the loop,
|
||||
// to prevent stop when using suggestions return a false value
|
||||
|
||||
return !suggest && word_arr;
|
||||
};
|
||||
|
||||
function single_result(result, limit, offset){
|
||||
|
||||
if(result.length === 1){
|
||||
|
||||
result = result[0];
|
||||
}
|
||||
else{
|
||||
|
||||
result = concat(result);
|
||||
}
|
||||
|
||||
return offset || (result.length > limit) ?
|
||||
|
||||
result.slice(offset, offset + limit)
|
||||
:
|
||||
result;
|
||||
}
|
||||
|
||||
function get_array(arr, term, keyword, bidirectional){
|
||||
|
||||
if(keyword){
|
||||
|
||||
// the frequency of the starting letter is slightly less
|
||||
// on the last half of the alphabet (m-z) in almost every latin language,
|
||||
// so we sort downwards (https://en.wikipedia.org/wiki/Letter_frequency)
|
||||
|
||||
const swap = bidirectional && (term > keyword);
|
||||
|
||||
arr = arr[swap ? term : keyword];
|
||||
arr = arr && arr[swap ? keyword : term];
|
||||
}
|
||||
else{
|
||||
|
||||
arr = arr[term];
|
||||
}
|
||||
|
||||
return arr;
|
||||
}
|
||||
|
||||
Index.prototype.contain = function(id){
|
||||
|
||||
return !!this.register[id];
|
||||
};
|
||||
|
||||
Index.prototype.update = function(id, content){
|
||||
|
||||
return this.remove(id).add(id, content);
|
||||
};
|
||||
|
||||
/**
|
||||
* @param {boolean=} _skip_deletion
|
||||
*/
|
||||
|
||||
Index.prototype.remove = function(id, _skip_deletion){
|
||||
|
||||
const refs = this.register[id];
|
||||
|
||||
if(refs){
|
||||
|
||||
if(this.fastupdate){
|
||||
|
||||
// fast updates performs really fast but did not fully cleanup the key entries
|
||||
|
||||
for(let i = 0, tmp; i < refs.length; i++){
|
||||
|
||||
tmp = refs[i];
|
||||
tmp.splice(tmp.indexOf(id), 1);
|
||||
}
|
||||
}
|
||||
else{
|
||||
|
||||
remove_index(this.map, id, this.resolution, this.optimize);
|
||||
|
||||
if(this.depth){
|
||||
|
||||
remove_index(this.ctx, id, this.resolution_ctx, this.optimize);
|
||||
}
|
||||
}
|
||||
|
||||
_skip_deletion || delete this.register[id];
|
||||
|
||||
if(SUPPORT_CACHE && this.cache){
|
||||
|
||||
this.cache.del(id);
|
||||
}
|
||||
}
|
||||
|
||||
return this;
|
||||
};
|
||||
|
||||
/**
|
||||
* @param map
|
||||
* @param id
|
||||
* @param res
|
||||
* @param optimize
|
||||
* @param {number=} resolution
|
||||
* @return {number}
|
||||
*/
|
||||
|
||||
function remove_index(map, id, res, optimize, resolution){
|
||||
|
||||
let count = 0;
|
||||
|
||||
if(is_array(map)){
|
||||
|
||||
// the first array is the score array in both strategies
|
||||
|
||||
if(!resolution){
|
||||
|
||||
resolution = Math.min(map.length, res);
|
||||
|
||||
for(let x = 0, arr; x < resolution; x++){
|
||||
|
||||
arr = map[x];
|
||||
|
||||
if(arr){
|
||||
|
||||
count = remove_index(arr, id, res, optimize, resolution);
|
||||
|
||||
if(!optimize && !count){
|
||||
|
||||
// when not memory optimized the score index should removed
|
||||
|
||||
delete map[x];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else{
|
||||
|
||||
const pos = map.indexOf(id);
|
||||
|
||||
if(pos !== -1){
|
||||
|
||||
// fast path, when length is 1 or lower then the whole field gets deleted
|
||||
|
||||
if(map.length > 1){
|
||||
|
||||
map.splice(pos, 1);
|
||||
count++;
|
||||
}
|
||||
}
|
||||
else{
|
||||
|
||||
count++;
|
||||
}
|
||||
}
|
||||
}
|
||||
else{
|
||||
|
||||
for(let key in map){
|
||||
|
||||
count = remove_index(map[key], id, res, optimize, resolution);
|
||||
|
||||
if(!count){
|
||||
|
||||
delete map[key];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
if(SUPPORT_CACHE){
|
||||
|
||||
Index.prototype.searchCache = searchCache;
|
||||
}
|
||||
|
||||
if(SUPPORT_SERIALIZE){
|
||||
|
||||
Index.prototype.export = exportIndex;
|
||||
Index.prototype.import = importIndex;
|
||||
}
|
||||
|
||||
if(SUPPORT_ASYNC){
|
||||
|
||||
apply_async(Index.prototype);
|
||||
}
|
397
paige/node_modules/flexsearch/src/intersect.js
generated
vendored
Normal file
397
paige/node_modules/flexsearch/src/intersect.js
generated
vendored
Normal file
@@ -0,0 +1,397 @@
|
||||
import { create_object, concat } from "./common.js";
|
||||
|
||||
/**
|
||||
* Implementation based on Array.includes() provides better performance,
|
||||
* but it needs at least one word in the query which is less frequent.
|
||||
* Also on large indexes it does not scale well performance-wise.
|
||||
* This strategy also lacks of suggestion capabilities (matching & sorting).
|
||||
*
|
||||
* @param arrays
|
||||
* @param limit
|
||||
* @param offset
|
||||
* @param {boolean|Array=} suggest
|
||||
* @returns {Array}
|
||||
*/
|
||||
|
||||
// export function intersect(arrays, limit, offset, suggest) {
|
||||
//
|
||||
// const length = arrays.length;
|
||||
// let result = [];
|
||||
// let check;
|
||||
//
|
||||
// // determine shortest array and collect results
|
||||
// // from the sparse relevance arrays
|
||||
//
|
||||
// let smallest_size;
|
||||
// let smallest_arr;
|
||||
// let smallest_index;
|
||||
//
|
||||
// for(let x = 0; x < length; x++){
|
||||
//
|
||||
// const arr = arrays[x];
|
||||
// const len = arr.length;
|
||||
//
|
||||
// let size = 0;
|
||||
//
|
||||
// for(let y = 0, tmp; y < len; y++){
|
||||
//
|
||||
// tmp = arr[y];
|
||||
//
|
||||
// if(tmp){
|
||||
//
|
||||
// size += tmp.length;
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// if(!smallest_size || (size < smallest_size)){
|
||||
//
|
||||
// smallest_size = size;
|
||||
// smallest_arr = arr;
|
||||
// smallest_index = x;
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// smallest_arr = smallest_arr.length === 1 ?
|
||||
//
|
||||
// smallest_arr[0]
|
||||
// :
|
||||
// concat(smallest_arr);
|
||||
//
|
||||
// if(suggest){
|
||||
//
|
||||
// suggest = [smallest_arr];
|
||||
// check = create_object();
|
||||
// }
|
||||
//
|
||||
// let size = 0;
|
||||
// let steps = 0;
|
||||
//
|
||||
// // process terms in reversed order often results in better performance.
|
||||
// // the outer loop must be the words array, using the
|
||||
// // smallest array here disables the "fast fail" optimization.
|
||||
//
|
||||
// for(let x = length - 1; x >= 0; x--){
|
||||
//
|
||||
// if(x !== smallest_index){
|
||||
//
|
||||
// steps++;
|
||||
//
|
||||
// const word_arr = arrays[x];
|
||||
// const word_arr_len = word_arr.length;
|
||||
// const new_arr = [];
|
||||
//
|
||||
// let count = 0;
|
||||
//
|
||||
// for(let z = 0, id; z < smallest_arr.length; z++){
|
||||
//
|
||||
// id = smallest_arr[z];
|
||||
//
|
||||
// let found;
|
||||
//
|
||||
// // process relevance in forward order (direction is
|
||||
// // important for adding IDs during the last round)
|
||||
//
|
||||
// for(let y = 0; y < word_arr_len; y++){
|
||||
//
|
||||
// const arr = word_arr[y];
|
||||
//
|
||||
// if(arr.length){
|
||||
//
|
||||
// found = arr.includes(id);
|
||||
//
|
||||
// if(found){
|
||||
//
|
||||
// // check if in last round
|
||||
//
|
||||
// if(steps === length - 1){
|
||||
//
|
||||
// if(offset){
|
||||
//
|
||||
// offset--;
|
||||
// }
|
||||
// else{
|
||||
//
|
||||
// result[size++] = id;
|
||||
//
|
||||
// if(size === limit){
|
||||
//
|
||||
// // fast path "end reached"
|
||||
//
|
||||
// return result;
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// if(suggest){
|
||||
//
|
||||
// check[id] = 1;
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// break;
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// if(found){
|
||||
//
|
||||
// new_arr[count++] = id;
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// if(suggest){
|
||||
//
|
||||
// suggest[steps] = new_arr;
|
||||
// }
|
||||
// else if(!count){
|
||||
//
|
||||
// return [];
|
||||
// }
|
||||
//
|
||||
// smallest_arr = new_arr;
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// if(suggest){
|
||||
//
|
||||
// // needs to iterate in reverse direction
|
||||
//
|
||||
// for(let x = suggest.length - 1, arr, len; x >= 0; x--){
|
||||
//
|
||||
// arr = suggest[x];
|
||||
// len = arr && arr.length;
|
||||
//
|
||||
// if(len){
|
||||
//
|
||||
// for(let y = 0, id; y < len; y++){
|
||||
//
|
||||
// id = arr[y];
|
||||
//
|
||||
// if(!check[id]){
|
||||
//
|
||||
// check[id] = 1;
|
||||
//
|
||||
// if(offset){
|
||||
//
|
||||
// offset--;
|
||||
// }
|
||||
// else{
|
||||
//
|
||||
// result[size++] = id;
|
||||
//
|
||||
// if(size === limit){
|
||||
//
|
||||
// // fast path "end reached"
|
||||
//
|
||||
// return result;
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// return result;
|
||||
// }
|
||||
|
||||
/**
|
||||
* Implementation based on Object[key] provides better suggestions
|
||||
* capabilities and has less performance scaling issues on large indexes.
|
||||
*
|
||||
* @param arrays
|
||||
* @param limit
|
||||
* @param offset
|
||||
* @param {boolean|Array=} suggest
|
||||
* @returns {Array}
|
||||
*/
|
||||
|
||||
export function intersect(arrays, limit, offset, suggest) {
|
||||
|
||||
const length = arrays.length;
|
||||
let result = [];
|
||||
let check;
|
||||
let check_suggest;
|
||||
let size = 0;
|
||||
|
||||
if(suggest){
|
||||
|
||||
suggest = [];
|
||||
}
|
||||
|
||||
// process terms in reversed order often has advantage for the fast path "end reached".
|
||||
// also a reversed order prioritize the order of words from a query.
|
||||
|
||||
for(let x = length - 1; x >= 0; x--){
|
||||
|
||||
const word_arr = arrays[x];
|
||||
const word_arr_len = word_arr.length;
|
||||
const check_new = create_object();
|
||||
|
||||
let found = !check;
|
||||
|
||||
// process relevance in forward order (direction is
|
||||
// important for adding IDs during the last round)
|
||||
|
||||
for(let y = 0; y < word_arr_len; y++){
|
||||
|
||||
const arr = word_arr[y];
|
||||
const arr_len = arr.length;
|
||||
|
||||
if(arr_len){
|
||||
|
||||
// loop through IDs
|
||||
|
||||
for(let z = 0, check_idx, id; z < arr_len; z++){
|
||||
|
||||
id = arr[z];
|
||||
|
||||
if(check){
|
||||
|
||||
if(check[id]){
|
||||
|
||||
// check if in last round
|
||||
|
||||
if(!x){
|
||||
|
||||
if(offset){
|
||||
|
||||
offset--;
|
||||
}
|
||||
else{
|
||||
|
||||
result[size++] = id;
|
||||
|
||||
if(size === limit){
|
||||
|
||||
// fast path "end reached"
|
||||
|
||||
return result;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(x || suggest){
|
||||
|
||||
check_new[id] = 1;
|
||||
}
|
||||
|
||||
found = true;
|
||||
}
|
||||
|
||||
if(suggest){
|
||||
|
||||
check_idx = (check_suggest[id] || 0) + 1;
|
||||
check_suggest[id] = check_idx;
|
||||
|
||||
// do not adding IDs which are already included in the result (saves one loop)
|
||||
// the first intersection match has the check index 2, so shift by -2
|
||||
|
||||
if(check_idx < length){
|
||||
|
||||
const tmp = suggest[check_idx - 2] || (suggest[check_idx - 2] = []);
|
||||
tmp[tmp.length] = id;
|
||||
}
|
||||
}
|
||||
}
|
||||
else{
|
||||
|
||||
// pre-fill in first round
|
||||
|
||||
check_new[id] = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(suggest){
|
||||
|
||||
// re-use the first pre-filled check for suggestions
|
||||
|
||||
check || (check_suggest = check_new);
|
||||
}
|
||||
else if(!found){
|
||||
|
||||
return [];
|
||||
}
|
||||
|
||||
check = check_new;
|
||||
}
|
||||
|
||||
if(suggest){
|
||||
|
||||
// needs to iterate in reverse direction
|
||||
|
||||
for(let x = suggest.length - 1, arr, len; x >= 0; x--){
|
||||
|
||||
arr = suggest[x];
|
||||
len = arr.length;
|
||||
|
||||
for(let y = 0, id; y < len; y++){
|
||||
|
||||
id = arr[y];
|
||||
|
||||
if(!check[id]){
|
||||
|
||||
if(offset){
|
||||
|
||||
offset--;
|
||||
}
|
||||
else{
|
||||
|
||||
result[size++] = id;
|
||||
|
||||
if(size === limit){
|
||||
|
||||
// fast path "end reached"
|
||||
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
check[id] = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param mandatory
|
||||
* @param arrays
|
||||
* @returns {Array}
|
||||
*/
|
||||
|
||||
export function intersect_union(mandatory, arrays) {
|
||||
|
||||
const check = create_object();
|
||||
const union = create_object();
|
||||
const result = [];
|
||||
|
||||
for(let x = 0; x < mandatory.length; x++){
|
||||
|
||||
check[mandatory[x]] = 1;
|
||||
}
|
||||
|
||||
for(let x = 0, arr; x < arrays.length; x++){
|
||||
|
||||
arr = arrays[x];
|
||||
|
||||
for(let y = 0, id; y < arr.length; y++){
|
||||
|
||||
id = arr[y];
|
||||
|
||||
if(check[id]){
|
||||
|
||||
if(!union[id]){
|
||||
|
||||
union[id] = 1;
|
||||
result[result.length] = id;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
321
paige/node_modules/flexsearch/src/lang.js
generated
vendored
Normal file
321
paige/node_modules/flexsearch/src/lang.js
generated
vendored
Normal file
@@ -0,0 +1,321 @@
|
||||
import { IndexInterface } from "./type.js";
|
||||
import { create_object, get_keys } from "./common.js";
|
||||
|
||||
/**
|
||||
* @param {!string} str
|
||||
* @param {boolean|Array<string|RegExp>=} normalize
|
||||
* @param {boolean|string|RegExp=} split
|
||||
* @param {boolean=} _collapse
|
||||
* @returns {string|Array<string>}
|
||||
* @this IndexInterface
|
||||
*/
|
||||
|
||||
export function pipeline(str, normalize, split, _collapse){
|
||||
|
||||
if(str){
|
||||
|
||||
if(normalize){
|
||||
|
||||
str = replace(str, /** @type {Array<string|RegExp>} */ (normalize));
|
||||
}
|
||||
|
||||
if(this.matcher){
|
||||
|
||||
str = replace(str, this.matcher);
|
||||
}
|
||||
|
||||
if(this.stemmer && (str.length > 1)){
|
||||
|
||||
str = replace(str, this.stemmer);
|
||||
}
|
||||
|
||||
if(_collapse && (str.length > 1)){
|
||||
|
||||
str = collapse(str);
|
||||
}
|
||||
|
||||
if(split || (split === "")){
|
||||
|
||||
const words = str.split(/** @type {string|RegExp} */ (split));
|
||||
|
||||
return this.filter ? filter(words, this.filter) : words;
|
||||
}
|
||||
}
|
||||
|
||||
return str;
|
||||
}
|
||||
|
||||
// TODO improve normalize + remove non-delimited chars like in "I'm" + split on whitespace+
|
||||
|
||||
export const regex_whitespace = /[\p{Z}\p{S}\p{P}\p{C}]+/u;
|
||||
// https://github.com/nextapps-de/flexsearch/pull/414
|
||||
//export const regex_whitespace = /[\s\xA0\u2000-\u200B\u2028\u2029\u3000\ufeff!"#$%&'()*+,\-./:;<=>?@[\\\]^_`{|}~]/
|
||||
const regex_normalize = /[\u0300-\u036f]/g;
|
||||
|
||||
export function normalize(str){
|
||||
|
||||
if(str.normalize){
|
||||
|
||||
str = str.normalize("NFD").replace(regex_normalize, "");
|
||||
}
|
||||
|
||||
return str;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {!string} str
|
||||
* @param {boolean|Array<string|RegExp>=} normalize
|
||||
* @param {boolean|string|RegExp=} split
|
||||
* @param {boolean=} _collapse
|
||||
* @returns {string|Array<string>}
|
||||
*/
|
||||
|
||||
// FlexSearch.prototype.pipeline = function(str, normalize, split, _collapse){
|
||||
//
|
||||
// if(str){
|
||||
//
|
||||
// if(normalize && str){
|
||||
//
|
||||
// str = replace(str, /** @type {Array<string|RegExp>} */ (normalize));
|
||||
// }
|
||||
//
|
||||
// if(str && this.matcher){
|
||||
//
|
||||
// str = replace(str, this.matcher);
|
||||
// }
|
||||
//
|
||||
// if(this.stemmer && str.length > 1){
|
||||
//
|
||||
// str = replace(str, this.stemmer);
|
||||
// }
|
||||
//
|
||||
// if(_collapse && str.length > 1){
|
||||
//
|
||||
// str = collapse(str);
|
||||
// }
|
||||
//
|
||||
// if(str){
|
||||
//
|
||||
// if(split || (split === "")){
|
||||
//
|
||||
// const words = str.split(/** @type {string|RegExp} */ (split));
|
||||
//
|
||||
// return this.filter ? filter(words, this.filter) : words;
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// return str;
|
||||
// };
|
||||
|
||||
// export function pipeline(str, normalize, matcher, stemmer, split, _filter, _collapse){
|
||||
//
|
||||
// if(str){
|
||||
//
|
||||
// if(normalize && str){
|
||||
//
|
||||
// str = replace(str, normalize);
|
||||
// }
|
||||
//
|
||||
// if(matcher && str){
|
||||
//
|
||||
// str = replace(str, matcher);
|
||||
// }
|
||||
//
|
||||
// if(stemmer && str.length > 1){
|
||||
//
|
||||
// str = replace(str, stemmer);
|
||||
// }
|
||||
//
|
||||
// if(_collapse && str.length > 1){
|
||||
//
|
||||
// str = collapse(str);
|
||||
// }
|
||||
//
|
||||
// if(str){
|
||||
//
|
||||
// if(split !== false){
|
||||
//
|
||||
// str = str.split(split);
|
||||
//
|
||||
// if(_filter){
|
||||
//
|
||||
// str = filter(str, _filter);
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// return str;
|
||||
// }
|
||||
|
||||
|
||||
/**
|
||||
* @param {Array<string>} words
|
||||
* @returns {Object<string, string>}
|
||||
*/
|
||||
|
||||
export function init_filter(words){
|
||||
|
||||
const filter = create_object();
|
||||
|
||||
for(let i = 0, length = words.length; i < length; i++){
|
||||
|
||||
filter[words[i]] = 1;
|
||||
}
|
||||
|
||||
return filter;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {!Object<string, string>} obj
|
||||
* @param {boolean} is_stemmer
|
||||
* @returns {Array}
|
||||
*/
|
||||
|
||||
export function init_stemmer_or_matcher(obj, is_stemmer){
|
||||
|
||||
const keys = get_keys(obj);
|
||||
const length = keys.length;
|
||||
const final = [];
|
||||
|
||||
let removal = "", count = 0;
|
||||
|
||||
for(let i = 0, key, tmp; i < length; i++){
|
||||
|
||||
key = keys[i];
|
||||
tmp = obj[key];
|
||||
|
||||
if(tmp){
|
||||
|
||||
final[count++] = regex(is_stemmer ? "(?!\\b)" + key + "(\\b|_)" : key);
|
||||
final[count++] = tmp;
|
||||
}
|
||||
else{
|
||||
|
||||
removal += (removal ? "|" : "") + key;
|
||||
}
|
||||
}
|
||||
|
||||
if(removal){
|
||||
|
||||
final[count++] = regex(is_stemmer ? "(?!\\b)(" + removal + ")(\\b|_)" : "(" + removal + ")");
|
||||
final[count] = "";
|
||||
}
|
||||
|
||||
return final;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param {!string} str
|
||||
* @param {Array} regexp
|
||||
* @returns {string}
|
||||
*/
|
||||
|
||||
export function replace(str, regexp){
|
||||
|
||||
for(let i = 0, len = regexp.length; i < len; i += 2){
|
||||
|
||||
str = str.replace(regexp[i], regexp[i + 1]);
|
||||
|
||||
if(!str){
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return str;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {!string} str
|
||||
* @returns {RegExp}
|
||||
*/
|
||||
|
||||
export function regex(str){
|
||||
|
||||
return new RegExp(str, "g");
|
||||
}
|
||||
|
||||
/**
|
||||
* Regex: replace(/(?:(\w)(?:\1)*)/g, "$1")
|
||||
* @param {!string} string
|
||||
* @returns {string}
|
||||
*/
|
||||
|
||||
export function collapse(string){
|
||||
|
||||
let final = "", prev = "";
|
||||
|
||||
for(let i = 0, len = string.length, char; i < len; i++){
|
||||
|
||||
if((char = string[i]) !== prev){
|
||||
|
||||
final += (prev = char);
|
||||
}
|
||||
}
|
||||
|
||||
return final;
|
||||
}
|
||||
|
||||
// TODO using fast-swap
|
||||
export function filter(words, map){
|
||||
|
||||
const length = words.length;
|
||||
const filtered = [];
|
||||
|
||||
for(let i = 0, count = 0; i < length; i++){
|
||||
|
||||
const word = words[i];
|
||||
|
||||
if(word && !map[word]){
|
||||
|
||||
filtered[count++] = word;
|
||||
}
|
||||
}
|
||||
|
||||
return filtered;
|
||||
}
|
||||
|
||||
// const chars = {a:1, e:1, i:1, o:1, u:1, y:1};
|
||||
//
|
||||
// function collapse_repeating_chars(string){
|
||||
//
|
||||
// let collapsed_string = "",
|
||||
// char_prev = "",
|
||||
// char_next = "";
|
||||
//
|
||||
// for(let i = 0; i < string.length; i++){
|
||||
//
|
||||
// const char = string[i];
|
||||
//
|
||||
// if(char !== char_prev){
|
||||
//
|
||||
// if(i && (char === "h")){
|
||||
//
|
||||
// if((chars[char_prev] && chars[char_next]) || (char_prev === " ")){
|
||||
//
|
||||
// collapsed_string += char;
|
||||
// }
|
||||
// }
|
||||
// else{
|
||||
//
|
||||
// collapsed_string += char;
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// char_next = (
|
||||
//
|
||||
// (i === (string.length - 1)) ?
|
||||
//
|
||||
// ""
|
||||
// :
|
||||
// string[i + 1]
|
||||
// );
|
||||
//
|
||||
// char_prev = char;
|
||||
// }
|
||||
//
|
||||
// return collapsed_string;
|
||||
// }
|
29
paige/node_modules/flexsearch/src/lang/arabic/default.js
generated
vendored
Normal file
29
paige/node_modules/flexsearch/src/lang/arabic/default.js
generated
vendored
Normal file
@@ -0,0 +1,29 @@
|
||||
import { IndexInterface } from "../../type.js";
|
||||
import { pipeline } from "../../lang.js";
|
||||
|
||||
export const rtl = true;
|
||||
export const tokenize = "";
|
||||
export default {
|
||||
encode: encode,
|
||||
rtl: rtl
|
||||
}
|
||||
|
||||
const regex = /[\x00-\x7F]+/g;
|
||||
const split = /\s+/;
|
||||
|
||||
/**
|
||||
* @param {string|number} str
|
||||
* @this IndexInterface
|
||||
*/
|
||||
|
||||
export function encode(str){
|
||||
|
||||
return pipeline.call(
|
||||
|
||||
this,
|
||||
/* string: */ ("" + str).replace(regex, " "),
|
||||
/* normalize: */ false,
|
||||
/* split: */ split,
|
||||
/* collapse: */ false
|
||||
);
|
||||
}
|
172
paige/node_modules/flexsearch/src/lang/at.js
generated
vendored
Normal file
172
paige/node_modules/flexsearch/src/lang/at.js
generated
vendored
Normal file
@@ -0,0 +1,172 @@
|
||||
/**
|
||||
* http://www.ranks.nl/stopwords
|
||||
* @type {Array<string>}
|
||||
*/
|
||||
|
||||
export const filter = [
|
||||
|
||||
"aber",
|
||||
"als",
|
||||
"am",
|
||||
"an",
|
||||
"auch",
|
||||
"auf",
|
||||
"aus",
|
||||
"bei",
|
||||
"bin",
|
||||
"bis",
|
||||
"bist",
|
||||
"da",
|
||||
"dadurch",
|
||||
"daher",
|
||||
"darum",
|
||||
"das",
|
||||
"daß",
|
||||
"dass",
|
||||
"dein",
|
||||
"deine",
|
||||
"dem",
|
||||
"den",
|
||||
"der",
|
||||
"des",
|
||||
"dessen",
|
||||
"deshalb",
|
||||
"die",
|
||||
"dies",
|
||||
"dieser",
|
||||
"dieses",
|
||||
"doch",
|
||||
"dort",
|
||||
"du",
|
||||
"durch",
|
||||
"ein",
|
||||
"eine",
|
||||
"einem",
|
||||
"einen",
|
||||
"einer",
|
||||
"eines",
|
||||
"er",
|
||||
"es",
|
||||
"euer",
|
||||
"eure",
|
||||
"für",
|
||||
"hatte",
|
||||
"hatten",
|
||||
"hattest",
|
||||
"hattet",
|
||||
"hier",
|
||||
"hinter",
|
||||
"ich",
|
||||
"ihr",
|
||||
"ihre",
|
||||
"im",
|
||||
"in",
|
||||
"ist",
|
||||
"ja",
|
||||
"jede",
|
||||
"jedem",
|
||||
"jeden",
|
||||
"jeder",
|
||||
"jedes",
|
||||
"jener",
|
||||
"jenes",
|
||||
"jetzt",
|
||||
"kann",
|
||||
"kannst",
|
||||
"können",
|
||||
"könnt",
|
||||
"machen",
|
||||
"mein",
|
||||
"meine",
|
||||
"mit",
|
||||
"muß",
|
||||
"mußt",
|
||||
"musst",
|
||||
"müssen",
|
||||
"müßt",
|
||||
"nach",
|
||||
"nachdem",
|
||||
"nein",
|
||||
"nicht",
|
||||
"nun",
|
||||
"oder",
|
||||
"seid",
|
||||
"sein",
|
||||
"seine",
|
||||
"sich",
|
||||
"sie",
|
||||
"sind",
|
||||
"soll",
|
||||
"sollen",
|
||||
"sollst",
|
||||
"sollt",
|
||||
"sonst",
|
||||
"soweit",
|
||||
"sowie",
|
||||
"und",
|
||||
"unser",
|
||||
"unsere",
|
||||
"unter",
|
||||
"vom",
|
||||
"von",
|
||||
"vor",
|
||||
"wann",
|
||||
"warum",
|
||||
"was",
|
||||
"weiter",
|
||||
"weitere",
|
||||
"wenn",
|
||||
"wer",
|
||||
"werde",
|
||||
"werden",
|
||||
"werdet",
|
||||
"weshalb",
|
||||
"wie",
|
||||
"wieder",
|
||||
"wieso",
|
||||
"wir",
|
||||
"wird",
|
||||
"wirst",
|
||||
"wo",
|
||||
"woher",
|
||||
"wohin",
|
||||
"zu",
|
||||
"zum",
|
||||
"zur",
|
||||
"über"
|
||||
];
|
||||
|
||||
/**
|
||||
* @type {Object<string, string>}
|
||||
*/
|
||||
|
||||
export const stemmer = {
|
||||
|
||||
"niss": "",
|
||||
"isch": "",
|
||||
"lich": "",
|
||||
"heit": "",
|
||||
"keit": "",
|
||||
"end": "",
|
||||
"ung": "",
|
||||
"est": "",
|
||||
"ern": "",
|
||||
"em": "",
|
||||
"er": "",
|
||||
"en": "",
|
||||
"es": "",
|
||||
"st": "",
|
||||
"ig": "",
|
||||
"ik": "",
|
||||
"e": "",
|
||||
"s": ""
|
||||
};
|
||||
|
||||
export const matcher = {};
|
||||
|
||||
export default {
|
||||
|
||||
filter: filter,
|
||||
stemmer: stemmer,
|
||||
matcher: matcher
|
||||
}
|
29
paige/node_modules/flexsearch/src/lang/cjk/default.js
generated
vendored
Normal file
29
paige/node_modules/flexsearch/src/lang/cjk/default.js
generated
vendored
Normal file
@@ -0,0 +1,29 @@
|
||||
import { IndexInterface } from "../../type.js";
|
||||
import { pipeline } from "../../lang.js";
|
||||
|
||||
export const rtl = false;
|
||||
export const tokenize = "strict";
|
||||
export default {
|
||||
encode: encode,
|
||||
rtl: rtl,
|
||||
tokenize: tokenize
|
||||
}
|
||||
|
||||
const regex = /[\x00-\x7F]+/g;
|
||||
|
||||
/**
|
||||
* @param {string|number} str
|
||||
* @this IndexInterface
|
||||
*/
|
||||
|
||||
export function encode(str){
|
||||
|
||||
return pipeline.call(
|
||||
|
||||
this,
|
||||
/* string: */ ("" + str).replace(regex, ""),
|
||||
/* normalize: */ false,
|
||||
/* split: */ "",
|
||||
/* collapse: */ false
|
||||
);
|
||||
}
|
29
paige/node_modules/flexsearch/src/lang/cyrillic/default.js
generated
vendored
Normal file
29
paige/node_modules/flexsearch/src/lang/cyrillic/default.js
generated
vendored
Normal file
@@ -0,0 +1,29 @@
|
||||
import { IndexInterface } from "../../type.js";
|
||||
import { pipeline } from "../../lang.js";
|
||||
|
||||
export const rtl = false;
|
||||
export const tokenize = "";
|
||||
export default {
|
||||
encode: encode,
|
||||
rtl: rtl
|
||||
}
|
||||
|
||||
const regex = /[\x00-\x7F]+/g;
|
||||
const split = /\s+/;
|
||||
|
||||
/**
|
||||
* @param {string|number} str
|
||||
* @this IndexInterface
|
||||
*/
|
||||
|
||||
export function encode(str){
|
||||
|
||||
return pipeline.call(
|
||||
|
||||
this,
|
||||
/* string: */ ("" + str).replace(regex, " "),
|
||||
/* normalize: */ false,
|
||||
/* split: */ split,
|
||||
/* collapse: */ false
|
||||
);
|
||||
}
|
185
paige/node_modules/flexsearch/src/lang/de.js
generated
vendored
Normal file
185
paige/node_modules/flexsearch/src/lang/de.js
generated
vendored
Normal file
@@ -0,0 +1,185 @@
|
||||
/**
|
||||
* Filter are also known as "stopwords", they completely filter out words from being indexed.
|
||||
* Source: http://www.ranks.nl/stopwords
|
||||
* Object Definition: Just provide an array of words.
|
||||
* @type {Array<string>}
|
||||
*/
|
||||
|
||||
export const filter = [
|
||||
|
||||
"aber",
|
||||
"als",
|
||||
"am",
|
||||
"an",
|
||||
"auch",
|
||||
"auf",
|
||||
"aus",
|
||||
"bei",
|
||||
"bin",
|
||||
"bis",
|
||||
"bist",
|
||||
"da",
|
||||
"dadurch",
|
||||
"daher",
|
||||
"darum",
|
||||
"das",
|
||||
"daß",
|
||||
"dass",
|
||||
"dein",
|
||||
"deine",
|
||||
"dem",
|
||||
"den",
|
||||
"der",
|
||||
"des",
|
||||
"dessen",
|
||||
"deshalb",
|
||||
"die",
|
||||
"dies",
|
||||
"dieser",
|
||||
"dieses",
|
||||
"doch",
|
||||
"dort",
|
||||
"du",
|
||||
"durch",
|
||||
"ein",
|
||||
"eine",
|
||||
"einem",
|
||||
"einen",
|
||||
"einer",
|
||||
"eines",
|
||||
"er",
|
||||
"es",
|
||||
"euer",
|
||||
"eure",
|
||||
"für",
|
||||
"hatte",
|
||||
"hatten",
|
||||
"hattest",
|
||||
"hattet",
|
||||
"hier",
|
||||
"hinter",
|
||||
"ich",
|
||||
"ihr",
|
||||
"ihre",
|
||||
"im",
|
||||
"in",
|
||||
"ist",
|
||||
"ja",
|
||||
"jede",
|
||||
"jedem",
|
||||
"jeden",
|
||||
"jeder",
|
||||
"jedes",
|
||||
"jener",
|
||||
"jenes",
|
||||
"jetzt",
|
||||
"kann",
|
||||
"kannst",
|
||||
"können",
|
||||
"könnt",
|
||||
"machen",
|
||||
"mein",
|
||||
"meine",
|
||||
"mit",
|
||||
"muß",
|
||||
"mußt",
|
||||
"musst",
|
||||
"müssen",
|
||||
"müßt",
|
||||
"nach",
|
||||
"nachdem",
|
||||
"nein",
|
||||
"nicht",
|
||||
"nun",
|
||||
"oder",
|
||||
"seid",
|
||||
"sein",
|
||||
"seine",
|
||||
"sich",
|
||||
"sie",
|
||||
"sind",
|
||||
"soll",
|
||||
"sollen",
|
||||
"sollst",
|
||||
"sollt",
|
||||
"sonst",
|
||||
"soweit",
|
||||
"sowie",
|
||||
"und",
|
||||
"unser",
|
||||
"unsere",
|
||||
"unter",
|
||||
"vom",
|
||||
"von",
|
||||
"vor",
|
||||
"wann",
|
||||
"warum",
|
||||
"was",
|
||||
"weiter",
|
||||
"weitere",
|
||||
"wenn",
|
||||
"wer",
|
||||
"werde",
|
||||
"werden",
|
||||
"werdet",
|
||||
"weshalb",
|
||||
"wie",
|
||||
"wieder",
|
||||
"wieso",
|
||||
"wir",
|
||||
"wird",
|
||||
"wirst",
|
||||
"wo",
|
||||
"woher",
|
||||
"wohin",
|
||||
"zu",
|
||||
"zum",
|
||||
"zur",
|
||||
"über"
|
||||
];
|
||||
|
||||
/**
|
||||
* Stemmer removes word endings and is a kind of "partial normalization". A word ending just matched when the word length is bigger than the matched partial.
|
||||
* Example: The word "correct" and "correctness" could be the same word, so you can define {"ness": ""} to normalize the ending.
|
||||
* Object Definition: the key represents the word ending, the value contains the replacement (or empty string for removal).
|
||||
* @type {Object<string, string>}
|
||||
*/
|
||||
|
||||
export const stemmer = {
|
||||
|
||||
"niss": "",
|
||||
"isch": "",
|
||||
"lich": "",
|
||||
"heit": "",
|
||||
"keit": "",
|
||||
"ell": "",
|
||||
"bar": "",
|
||||
"end": "",
|
||||
"ung": "",
|
||||
"est": "",
|
||||
"ern": "",
|
||||
"em": "",
|
||||
"er": "",
|
||||
"en": "",
|
||||
"es": "",
|
||||
"st": "",
|
||||
"ig": "",
|
||||
"ik": "",
|
||||
"e": "",
|
||||
"s": ""
|
||||
};
|
||||
|
||||
/**
|
||||
* Matcher replaces all occurrences of a given string regardless of its position and is also a kind of "partial normalization".
|
||||
* Object Definition: the key represents the target term, the value contains the search string which should be replaced (could also be an array of multiple terms).
|
||||
* @type {Object<string, Array<string>|string>}
|
||||
*/
|
||||
|
||||
export const matcher = {};
|
||||
|
||||
export default {
|
||||
|
||||
filter: filter,
|
||||
stemmer: stemmer,
|
||||
matcher: matcher
|
||||
}
|
276
paige/node_modules/flexsearch/src/lang/en.js
generated
vendored
Normal file
276
paige/node_modules/flexsearch/src/lang/en.js
generated
vendored
Normal file
@@ -0,0 +1,276 @@
|
||||
/**
|
||||
* http://www.ranks.nl/stopwords
|
||||
* @type {Array<string>}
|
||||
*/
|
||||
|
||||
export const filter = [
|
||||
|
||||
"a",
|
||||
"about",
|
||||
"above",
|
||||
"after",
|
||||
"again",
|
||||
"against",
|
||||
"all",
|
||||
"also",
|
||||
"am",
|
||||
"an",
|
||||
"and",
|
||||
"any",
|
||||
"are",
|
||||
"aren't",
|
||||
"as",
|
||||
"at",
|
||||
//"back",
|
||||
"be",
|
||||
"because",
|
||||
"been",
|
||||
"before",
|
||||
"being",
|
||||
"below",
|
||||
//"between",
|
||||
"both",
|
||||
"but",
|
||||
"by",
|
||||
"can",
|
||||
"cannot",
|
||||
"can't",
|
||||
"come",
|
||||
"could",
|
||||
"couldn't",
|
||||
//"day",
|
||||
"did",
|
||||
"didn't",
|
||||
"do",
|
||||
"does",
|
||||
"doesn't",
|
||||
"doing",
|
||||
"dont",
|
||||
"down",
|
||||
"during",
|
||||
"each",
|
||||
"even",
|
||||
"few",
|
||||
"first",
|
||||
"for",
|
||||
"from",
|
||||
"further",
|
||||
"get",
|
||||
//"give",
|
||||
"go",
|
||||
//"good",
|
||||
"had",
|
||||
"hadn't",
|
||||
"has",
|
||||
"hasn't",
|
||||
"have",
|
||||
"haven't",
|
||||
"having",
|
||||
"he",
|
||||
"hed",
|
||||
//"hell",
|
||||
"her",
|
||||
"here",
|
||||
"here's",
|
||||
"hers",
|
||||
"herself",
|
||||
"hes",
|
||||
"him",
|
||||
"himself",
|
||||
"his",
|
||||
"how",
|
||||
"how's",
|
||||
"i",
|
||||
"id",
|
||||
"if",
|
||||
"ill",
|
||||
"im",
|
||||
"in",
|
||||
"into",
|
||||
"is",
|
||||
"isn't",
|
||||
"it",
|
||||
"it's",
|
||||
"itself",
|
||||
"i've",
|
||||
"just",
|
||||
"know",
|
||||
"let's",
|
||||
"like",
|
||||
//"look",
|
||||
"make",
|
||||
"me",
|
||||
"more",
|
||||
"most",
|
||||
"mustn't",
|
||||
"my",
|
||||
"myself",
|
||||
"new",
|
||||
"no",
|
||||
"nor",
|
||||
"not",
|
||||
"now",
|
||||
"of",
|
||||
"off",
|
||||
"on",
|
||||
"once",
|
||||
//"one",
|
||||
"only",
|
||||
"or",
|
||||
"other",
|
||||
"ought",
|
||||
"our",
|
||||
"our's",
|
||||
"ourselves",
|
||||
"out",
|
||||
"over",
|
||||
"own",
|
||||
//"people",
|
||||
"same",
|
||||
"say",
|
||||
"see",
|
||||
"shan't",
|
||||
"she",
|
||||
"she'd",
|
||||
"shell",
|
||||
"shes",
|
||||
"should",
|
||||
"shouldn't",
|
||||
"so",
|
||||
"some",
|
||||
"such",
|
||||
//"take",
|
||||
"than",
|
||||
"that",
|
||||
"that's",
|
||||
"the",
|
||||
"their",
|
||||
"theirs",
|
||||
"them",
|
||||
"themselves",
|
||||
"then",
|
||||
"there",
|
||||
"there's",
|
||||
"these",
|
||||
"they",
|
||||
"they'd",
|
||||
"they'll",
|
||||
"they're",
|
||||
"they've",
|
||||
//"think",
|
||||
"this",
|
||||
"those",
|
||||
"through",
|
||||
"time",
|
||||
"to",
|
||||
"too",
|
||||
//"two",
|
||||
//"under",
|
||||
"until",
|
||||
"up",
|
||||
"us",
|
||||
//"use",
|
||||
"very",
|
||||
"want",
|
||||
"was",
|
||||
"wasn't",
|
||||
"way",
|
||||
"we",
|
||||
"wed",
|
||||
"well",
|
||||
"were",
|
||||
"weren't",
|
||||
"we've",
|
||||
"what",
|
||||
"what's",
|
||||
"when",
|
||||
"when's",
|
||||
"where",
|
||||
"where's",
|
||||
"which",
|
||||
"while",
|
||||
"who",
|
||||
"whom",
|
||||
"who's",
|
||||
"why",
|
||||
"why's",
|
||||
"will",
|
||||
"with",
|
||||
"won't",
|
||||
//"work",
|
||||
"would",
|
||||
"wouldn't",
|
||||
//"year",
|
||||
"you",
|
||||
"you'd",
|
||||
"you'll",
|
||||
"your",
|
||||
"you're",
|
||||
"your's",
|
||||
"yourself",
|
||||
"yourselves",
|
||||
"you've"
|
||||
];
|
||||
|
||||
/**
|
||||
* @type {Object<string, string>}
|
||||
*/
|
||||
|
||||
export const stemmer = {
|
||||
|
||||
"ational": "ate",
|
||||
"iveness": "ive",
|
||||
"fulness": "ful",
|
||||
"ousness": "ous",
|
||||
"ization": "ize",
|
||||
"tional": "tion",
|
||||
"biliti": "ble",
|
||||
"icate": "ic",
|
||||
"ative": "",
|
||||
"alize": "al",
|
||||
"iciti": "ic",
|
||||
"entli": "ent",
|
||||
"ousli": "ous",
|
||||
"alism": "al",
|
||||
"ation": "ate",
|
||||
"aliti": "al",
|
||||
"iviti": "ive",
|
||||
"ement": "",
|
||||
"enci": "ence",
|
||||
"anci": "ance",
|
||||
"izer": "ize",
|
||||
"alli": "al",
|
||||
"ator": "ate",
|
||||
"logi": "log",
|
||||
"ical": "ic",
|
||||
"ance": "",
|
||||
"ence": "",
|
||||
"ness": "",
|
||||
"able": "",
|
||||
"ible": "",
|
||||
"ment": "",
|
||||
"eli": "e",
|
||||
"bli": "ble",
|
||||
"ful": "",
|
||||
"ant": "",
|
||||
"ent": "",
|
||||
"ism": "",
|
||||
"ate": "",
|
||||
"iti": "",
|
||||
"ous": "",
|
||||
"ive": "",
|
||||
"ize": "",
|
||||
"al": "",
|
||||
"ou": "",
|
||||
"er": "",
|
||||
"ic": ""
|
||||
};
|
||||
|
||||
export const matcher = {};
|
||||
|
||||
export default {
|
||||
|
||||
filter: filter,
|
||||
stemmer: stemmer,
|
||||
matcher: matcher
|
||||
}
|
92
paige/node_modules/flexsearch/src/lang/latin/advanced.js
generated
vendored
Normal file
92
paige/node_modules/flexsearch/src/lang/latin/advanced.js
generated
vendored
Normal file
@@ -0,0 +1,92 @@
|
||||
import { IndexInterface } from "../../type.js";
|
||||
import { regex, replace, collapse } from "../../lang.js";
|
||||
import { encode as encode_balance } from "./balance.js";
|
||||
|
||||
export const rtl = false;
|
||||
export const tokenize = "";
|
||||
export default {
|
||||
encode: encode,
|
||||
rtl: rtl,
|
||||
tokenize: tokenize
|
||||
}
|
||||
|
||||
// Phonetic Normalization
|
||||
|
||||
const regex_ae = regex("ae"),
|
||||
//regex_ai = regex("ai"),
|
||||
//regex_ay = regex("ay"),
|
||||
//regex_ey = regex("ey"),
|
||||
regex_oe = regex("oe"),
|
||||
//regex_ue = regex("ue"),
|
||||
//regex_ie = regex("ie"),
|
||||
//regex_sz = regex("sz"),
|
||||
//regex_zs = regex("zs"),
|
||||
//regex_ck = regex("ck"),
|
||||
//regex_cc = regex("cc"),
|
||||
regex_sh = regex("sh"),
|
||||
regex_th = regex("th"),
|
||||
//regex_dt = regex("dt"),
|
||||
regex_ph = regex("ph"),
|
||||
regex_pf = regex("pf");
|
||||
//regex_ou = regex("ou"),
|
||||
//regex_uo = regex("uo");
|
||||
|
||||
const pairs = [
|
||||
regex_ae, "a",
|
||||
// regex_ai, "ei",
|
||||
// regex_ay, "ei",
|
||||
// regex_ey, "ei",
|
||||
regex_oe, "o",
|
||||
// regex_ue, "u",
|
||||
// regex_ie, "i",
|
||||
// regex_sz, "s",
|
||||
// regex_zs, "s",
|
||||
regex_sh, "s",
|
||||
// regex_ck, "k",
|
||||
// regex_cc, "k",
|
||||
regex_th, "t",
|
||||
// regex_dt, "t",
|
||||
regex_ph, "f",
|
||||
regex_pf, "f",
|
||||
// regex_ou, "o",
|
||||
// regex_uo, "u"
|
||||
|
||||
// regex("(?![aeiouy])h(?![aeiouy])"), "",
|
||||
// regex("(?!^[aeiouy])h(?!^[aeiouy])"), ""
|
||||
regex("(?![aeo])h(?![aeo])"), "",
|
||||
regex("(?!^[aeo])h(?!^[aeo])"), ""
|
||||
];
|
||||
|
||||
/**
|
||||
* @param {string|number} str
|
||||
* @param {boolean=} _skip_postprocessing
|
||||
* @this IndexInterface
|
||||
*/
|
||||
|
||||
export function encode(str, _skip_postprocessing){
|
||||
|
||||
if(str){
|
||||
|
||||
str = encode_balance.call(this, str).join(" ");
|
||||
|
||||
if(str.length > 2){
|
||||
|
||||
str = replace(str, pairs);
|
||||
}
|
||||
|
||||
if(!_skip_postprocessing){
|
||||
|
||||
if(str.length > 1){
|
||||
|
||||
str = collapse(str);
|
||||
}
|
||||
|
||||
if(str){
|
||||
|
||||
str = str.split(" ");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return str || [];
|
||||
}
|
119
paige/node_modules/flexsearch/src/lang/latin/balance.js
generated
vendored
Normal file
119
paige/node_modules/flexsearch/src/lang/latin/balance.js
generated
vendored
Normal file
@@ -0,0 +1,119 @@
|
||||
import { IndexInterface } from "../../type.js";
|
||||
import { encode as encode_simple } from "./simple.js";
|
||||
|
||||
// custom soundex implementation
|
||||
|
||||
export const rtl = false;
|
||||
export const tokenize = "strict";
|
||||
export default {
|
||||
encode: encode,
|
||||
rtl: rtl,
|
||||
tokenize: tokenize
|
||||
}
|
||||
|
||||
//const regex_whitespace = /[\W_]+/g;
|
||||
const regex_strip = /[^a-z0-9]+/;
|
||||
|
||||
// const pairs = [
|
||||
// regex_whitespace, " ",
|
||||
// regex_strip, ""
|
||||
// ];
|
||||
|
||||
// modified
|
||||
|
||||
const soundex = {
|
||||
|
||||
"b": "p",
|
||||
//"p": "p",
|
||||
|
||||
//"f": "f",
|
||||
"v": "f",
|
||||
"w": "f",
|
||||
|
||||
//"s": "s",
|
||||
"z": "s",
|
||||
"x": "s",
|
||||
"ß": "s",
|
||||
|
||||
"d": "t",
|
||||
//"t": "t",
|
||||
|
||||
//"l": "l",
|
||||
|
||||
//"m": "m",
|
||||
"n": "m",
|
||||
|
||||
"c": "k",
|
||||
"g": "k",
|
||||
"j": "k",
|
||||
//"k": "k",
|
||||
"q": "k",
|
||||
|
||||
//"r": "r",
|
||||
//"h": "h",
|
||||
//"a": "a",
|
||||
|
||||
//"e": "e",
|
||||
"i": "e",
|
||||
"y": "e",
|
||||
|
||||
//"o": "o",
|
||||
"u": "o"
|
||||
};
|
||||
|
||||
/**
|
||||
* @param {string|number} str
|
||||
* @this IndexInterface
|
||||
*/
|
||||
|
||||
export function encode(str){
|
||||
|
||||
str = encode_simple.call(this, str).join(" ");
|
||||
|
||||
// str = this.pipeline(
|
||||
//
|
||||
// /* string: */ normalize("" + str).toLowerCase(),
|
||||
// /* normalize: */ false,
|
||||
// /* split: */ false,
|
||||
// /* collapse: */ false
|
||||
// );
|
||||
|
||||
const result = [];
|
||||
|
||||
if(str){
|
||||
|
||||
const words = str.split(regex_strip);
|
||||
const length = words.length;
|
||||
|
||||
for(let x = 0, tmp, count = 0; x < length; x++){
|
||||
|
||||
if((str = words[x]) /*&& (str.length > 2)*/ && (!this.filter || !this.filter[str])){
|
||||
|
||||
tmp = str[0];
|
||||
let code = soundex[tmp] || tmp; //str[0];
|
||||
let previous = code; //soundex[code] || code;
|
||||
|
||||
for(let i = 1; i < str.length; i++){
|
||||
|
||||
tmp = str[i];
|
||||
const current = soundex[tmp] || tmp;
|
||||
|
||||
if(current && (current !== previous)){
|
||||
|
||||
code += current;
|
||||
previous = current;
|
||||
|
||||
// if(code.length === 7){
|
||||
//
|
||||
// break;
|
||||
// }
|
||||
}
|
||||
}
|
||||
|
||||
result[count++] = code; //(code + "0000").substring(0, 4);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
27
paige/node_modules/flexsearch/src/lang/latin/default.js
generated
vendored
Normal file
27
paige/node_modules/flexsearch/src/lang/latin/default.js
generated
vendored
Normal file
@@ -0,0 +1,27 @@
|
||||
import { IndexInterface } from "../../type.js";
|
||||
import { pipeline, normalize, regex_whitespace } from "../../lang.js";
|
||||
|
||||
export const rtl = false;
|
||||
export const tokenize = "";
|
||||
export default {
|
||||
encode: encode,
|
||||
rtl: rtl,
|
||||
tokenize: tokenize
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {string|number} str
|
||||
* @this IndexInterface
|
||||
*/
|
||||
|
||||
export function encode(str){
|
||||
|
||||
return pipeline.call(
|
||||
|
||||
this,
|
||||
/* string: */ ("" + str).toLowerCase(),
|
||||
/* normalize: */ false,
|
||||
/* split: */ regex_whitespace,
|
||||
/* collapse: */ false
|
||||
);
|
||||
}
|
67
paige/node_modules/flexsearch/src/lang/latin/extra.js
generated
vendored
Normal file
67
paige/node_modules/flexsearch/src/lang/latin/extra.js
generated
vendored
Normal file
@@ -0,0 +1,67 @@
|
||||
import { IndexInterface } from "../../type.js";
|
||||
import { regex, replace, collapse } from "../../lang.js";
|
||||
import { encode as encode_advanced } from "./advanced.js";
|
||||
|
||||
export const rtl = false;
|
||||
export const tokenize = "";
|
||||
export default {
|
||||
encode: encode,
|
||||
rtl: rtl,
|
||||
tokenize: tokenize
|
||||
}
|
||||
|
||||
// Soundex Normalization
|
||||
|
||||
const prefix = "(?!\\b)";
|
||||
const //soundex_b = regex(prefix + "p"),
|
||||
// soundex_s = regex(prefix + "z"),
|
||||
// soundex_k = regex(prefix + "[cgq]"),
|
||||
// soundex_m = regex(prefix + "n"),
|
||||
// soundex_t = regex(prefix + "d"),
|
||||
// soundex_f = regex(prefix + "[vw]"),
|
||||
//regex_vowel = regex(prefix + "[aeiouy]");
|
||||
regex_vowel = regex(prefix + "[aeo]");
|
||||
|
||||
const pairs = [
|
||||
|
||||
// soundex_b, "b",
|
||||
// soundex_s, "s",
|
||||
// soundex_k, "k",
|
||||
// soundex_m, "m",
|
||||
// soundex_t, "t",
|
||||
// soundex_f, "f",
|
||||
// regex("(?![aeiouy])h(?![aeiouy])"), "",
|
||||
// regex("(?!^[aeiouy])h(?!^[aeiouy])"), "",
|
||||
regex_vowel, ""
|
||||
];
|
||||
|
||||
/**
|
||||
* @param {string|number} str
|
||||
* @this IndexInterface
|
||||
*/
|
||||
|
||||
export function encode(str){
|
||||
|
||||
if(str){
|
||||
|
||||
str = encode_advanced.call(this, str, /* skip post-processing: */ true);
|
||||
|
||||
if(str.length > 1){
|
||||
|
||||
//str = replace(str, pairs);
|
||||
str = str.replace(regex_vowel, "");
|
||||
}
|
||||
|
||||
if(str.length > 1){
|
||||
|
||||
str = collapse(str);
|
||||
}
|
||||
|
||||
if(str){
|
||||
|
||||
str = str.split(" ");
|
||||
}
|
||||
}
|
||||
|
||||
return str || [];
|
||||
}
|
60
paige/node_modules/flexsearch/src/lang/latin/simple.js
generated
vendored
Normal file
60
paige/node_modules/flexsearch/src/lang/latin/simple.js
generated
vendored
Normal file
@@ -0,0 +1,60 @@
|
||||
import { IndexInterface } from "../../type.js";
|
||||
import { pipeline, normalize, regex_whitespace, regex } from "../../lang.js";
|
||||
|
||||
export const rtl = false;
|
||||
export const tokenize = "";
|
||||
export default {
|
||||
encode: encode,
|
||||
rtl: rtl,
|
||||
tokenize: tokenize
|
||||
}
|
||||
|
||||
// Charset Normalization
|
||||
|
||||
const //regex_whitespace = /\W+/,
|
||||
//regex_strip = regex("[^a-z0-9 ]"),
|
||||
regex_a = regex("[àáâãäå]"),
|
||||
regex_e = regex("[èéêë]"),
|
||||
regex_i = regex("[ìíîï]"),
|
||||
regex_o = regex("[òóôõöő]"),
|
||||
regex_u = regex("[ùúûüű]"),
|
||||
regex_y = regex("[ýŷÿ]"),
|
||||
regex_n = regex("ñ"),
|
||||
regex_c = regex("[çc]"),
|
||||
regex_s = regex("ß"),
|
||||
regex_and = regex(" & ");
|
||||
|
||||
const pairs = [
|
||||
|
||||
regex_a, "a",
|
||||
regex_e, "e",
|
||||
regex_i, "i",
|
||||
regex_o, "o",
|
||||
regex_u, "u",
|
||||
regex_y, "y",
|
||||
regex_n, "n",
|
||||
regex_c, "k",
|
||||
regex_s, "s",
|
||||
regex_and, " and "
|
||||
//regex_whitespace, " "
|
||||
//regex_strip, ""
|
||||
];
|
||||
|
||||
/**
|
||||
* @param {string|number} str
|
||||
* @this IndexInterface
|
||||
*/
|
||||
|
||||
export function encode(str){
|
||||
|
||||
str = "" + str;
|
||||
|
||||
return pipeline.call(
|
||||
|
||||
this,
|
||||
/* string: */ normalize(str).toLowerCase(),
|
||||
/* normalize: */ !str.normalize && pairs,
|
||||
/* split: */ regex_whitespace,
|
||||
/* collapse: */ false
|
||||
);
|
||||
}
|
276
paige/node_modules/flexsearch/src/lang/us.js
generated
vendored
Normal file
276
paige/node_modules/flexsearch/src/lang/us.js
generated
vendored
Normal file
@@ -0,0 +1,276 @@
|
||||
/**
|
||||
* http://www.ranks.nl/stopwords
|
||||
* @type {Array<string>}
|
||||
*/
|
||||
|
||||
export const filter = [
|
||||
|
||||
"a",
|
||||
"about",
|
||||
"above",
|
||||
"after",
|
||||
"again",
|
||||
"against",
|
||||
"all",
|
||||
"also",
|
||||
"am",
|
||||
"an",
|
||||
"and",
|
||||
"any",
|
||||
"are",
|
||||
"aren't",
|
||||
"as",
|
||||
"at",
|
||||
//"back",
|
||||
"be",
|
||||
"because",
|
||||
"been",
|
||||
"before",
|
||||
"being",
|
||||
"below",
|
||||
//"between",
|
||||
"both",
|
||||
"but",
|
||||
"by",
|
||||
"can",
|
||||
"cannot",
|
||||
"can't",
|
||||
"come",
|
||||
"could",
|
||||
"couldn't",
|
||||
//"day",
|
||||
"did",
|
||||
"didn't",
|
||||
"do",
|
||||
"does",
|
||||
"doesn't",
|
||||
"doing",
|
||||
"dont",
|
||||
"down",
|
||||
"during",
|
||||
"each",
|
||||
"even",
|
||||
"few",
|
||||
"first",
|
||||
"for",
|
||||
"from",
|
||||
"further",
|
||||
"get",
|
||||
//"give",
|
||||
"go",
|
||||
//"good",
|
||||
"had",
|
||||
"hadn't",
|
||||
"has",
|
||||
"hasn't",
|
||||
"have",
|
||||
"haven't",
|
||||
"having",
|
||||
"he",
|
||||
"hed",
|
||||
//"hell",
|
||||
"her",
|
||||
"here",
|
||||
"here's",
|
||||
"hers",
|
||||
"herself",
|
||||
"hes",
|
||||
"him",
|
||||
"himself",
|
||||
"his",
|
||||
"how",
|
||||
"how's",
|
||||
"i",
|
||||
"id",
|
||||
"if",
|
||||
"ill",
|
||||
"im",
|
||||
"in",
|
||||
"into",
|
||||
"is",
|
||||
"isn't",
|
||||
"it",
|
||||
"it's",
|
||||
"itself",
|
||||
"i've",
|
||||
"just",
|
||||
"know",
|
||||
"let's",
|
||||
"like",
|
||||
//"look",
|
||||
"make",
|
||||
"me",
|
||||
"more",
|
||||
"most",
|
||||
"mustn't",
|
||||
"my",
|
||||
"myself",
|
||||
"new",
|
||||
"no",
|
||||
"nor",
|
||||
"not",
|
||||
"now",
|
||||
"of",
|
||||
"off",
|
||||
"on",
|
||||
"once",
|
||||
//"one",
|
||||
"only",
|
||||
"or",
|
||||
"other",
|
||||
"ought",
|
||||
"our",
|
||||
"our's",
|
||||
"ourselves",
|
||||
"out",
|
||||
"over",
|
||||
"own",
|
||||
//"people",
|
||||
"same",
|
||||
"say",
|
||||
"see",
|
||||
"shan't",
|
||||
"she",
|
||||
"she'd",
|
||||
"shell",
|
||||
"shes",
|
||||
"should",
|
||||
"shouldn't",
|
||||
"so",
|
||||
"some",
|
||||
"such",
|
||||
//"take",
|
||||
"than",
|
||||
"that",
|
||||
"that's",
|
||||
"the",
|
||||
"their",
|
||||
"theirs",
|
||||
"them",
|
||||
"themselves",
|
||||
"then",
|
||||
"there",
|
||||
"there's",
|
||||
"these",
|
||||
"they",
|
||||
"they'd",
|
||||
"they'll",
|
||||
"they're",
|
||||
"they've",
|
||||
//"think",
|
||||
"this",
|
||||
"those",
|
||||
"through",
|
||||
"time",
|
||||
"to",
|
||||
"too",
|
||||
//"two",
|
||||
//"under",
|
||||
"until",
|
||||
"up",
|
||||
"us",
|
||||
//"use",
|
||||
"very",
|
||||
"want",
|
||||
"was",
|
||||
"wasn't",
|
||||
"way",
|
||||
"we",
|
||||
"wed",
|
||||
"well",
|
||||
"were",
|
||||
"weren't",
|
||||
"we've",
|
||||
"what",
|
||||
"what's",
|
||||
"when",
|
||||
"when's",
|
||||
"where",
|
||||
"where's",
|
||||
"which",
|
||||
"while",
|
||||
"who",
|
||||
"whom",
|
||||
"who's",
|
||||
"why",
|
||||
"why's",
|
||||
"will",
|
||||
"with",
|
||||
"won't",
|
||||
//"work",
|
||||
"would",
|
||||
"wouldn't",
|
||||
//"year",
|
||||
"you",
|
||||
"you'd",
|
||||
"you'll",
|
||||
"your",
|
||||
"you're",
|
||||
"your's",
|
||||
"yourself",
|
||||
"yourselves",
|
||||
"you've"
|
||||
];
|
||||
|
||||
/**
|
||||
* @type {Object<string, string>}
|
||||
*/
|
||||
|
||||
export const stemmer = {
|
||||
|
||||
"ational": "ate",
|
||||
"iveness": "ive",
|
||||
"fulness": "ful",
|
||||
"ousness": "ous",
|
||||
"ization": "ize",
|
||||
"tional": "tion",
|
||||
"biliti": "ble",
|
||||
"icate": "ic",
|
||||
"ative": "",
|
||||
"alize": "al",
|
||||
"iciti": "ic",
|
||||
"entli": "ent",
|
||||
"ousli": "ous",
|
||||
"alism": "al",
|
||||
"ation": "ate",
|
||||
"aliti": "al",
|
||||
"iviti": "ive",
|
||||
"ement": "",
|
||||
"enci": "ence",
|
||||
"anci": "ance",
|
||||
"izer": "ize",
|
||||
"alli": "al",
|
||||
"ator": "ate",
|
||||
"logi": "log",
|
||||
"ical": "ic",
|
||||
"ance": "",
|
||||
"ence": "",
|
||||
"ness": "",
|
||||
"able": "",
|
||||
"ible": "",
|
||||
"ment": "",
|
||||
"eli": "e",
|
||||
"bli": "ble",
|
||||
"ful": "",
|
||||
"ant": "",
|
||||
"ent": "",
|
||||
"ism": "",
|
||||
"ate": "",
|
||||
"iti": "",
|
||||
"ous": "",
|
||||
"ive": "",
|
||||
"ize": "",
|
||||
"al": "",
|
||||
"ou": "",
|
||||
"er": "",
|
||||
"ic": ""
|
||||
};
|
||||
|
||||
export const matcher = {};
|
||||
|
||||
export default {
|
||||
|
||||
filter: filter,
|
||||
stemmer: stemmer,
|
||||
matcher: matcher
|
||||
}
|
79
paige/node_modules/flexsearch/src/polyfill.js
generated
vendored
Normal file
79
paige/node_modules/flexsearch/src/polyfill.js
generated
vendored
Normal file
@@ -0,0 +1,79 @@
|
||||
// COMPILER BLOCK -->
|
||||
import { POLYFILL, SUPPORT_ASYNC } from "./config.js";
|
||||
// <-- COMPILER BLOCK
|
||||
export let promise = Promise;
|
||||
|
||||
if(POLYFILL){
|
||||
|
||||
Object.assign || (Object.assign = function(){
|
||||
|
||||
const args = arguments;
|
||||
const size = args.length;
|
||||
const obj = args[0];
|
||||
|
||||
for(let x = 1, current, keys, length; x < size; x++){
|
||||
|
||||
current = args[x];
|
||||
keys = Object.keys(current);
|
||||
length = keys.length;
|
||||
|
||||
for(let i = 0, key; i < length; i++){
|
||||
|
||||
key = keys[i];
|
||||
obj[key] = current[key];
|
||||
}
|
||||
}
|
||||
|
||||
return obj;
|
||||
});
|
||||
|
||||
// Object.values || (Object.values = function(obj){
|
||||
//
|
||||
// const keys = Object.keys(obj);
|
||||
// const length = keys.length;
|
||||
// const values = new Array(length);
|
||||
//
|
||||
// for(let x = 0; x < length; x++){
|
||||
//
|
||||
// values[x] = obj[keys[x]];
|
||||
// }
|
||||
//
|
||||
// return values;
|
||||
// });
|
||||
|
||||
if(SUPPORT_ASYNC && !promise){
|
||||
|
||||
/**
|
||||
* @param {Function} fn
|
||||
* @constructor
|
||||
*/
|
||||
|
||||
function SimplePromise(fn){
|
||||
|
||||
this.callback = null;
|
||||
|
||||
const self = this;
|
||||
|
||||
fn(function(val){
|
||||
|
||||
if(self.callback){
|
||||
|
||||
self.callback(val);
|
||||
// self.callback = null;
|
||||
// self = null;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {Function} callback
|
||||
*/
|
||||
|
||||
SimplePromise.prototype.then = function(callback){
|
||||
|
||||
this.callback = callback;
|
||||
};
|
||||
|
||||
promise = SimplePromise;
|
||||
}
|
||||
}
|
100
paige/node_modules/flexsearch/src/preset.js
generated
vendored
Normal file
100
paige/node_modules/flexsearch/src/preset.js
generated
vendored
Normal file
@@ -0,0 +1,100 @@
|
||||
// COMPILER BLOCK -->
|
||||
import { DEBUG } from "./config.js";
|
||||
// <-- COMPILER BLOCK
|
||||
import { is_string } from "./common.js";
|
||||
|
||||
/**
|
||||
* @enum {Object}
|
||||
* @const
|
||||
*/
|
||||
|
||||
const preset = {
|
||||
|
||||
"memory": {
|
||||
charset: "latin:extra",
|
||||
//tokenize: "strict",
|
||||
resolution: 3,
|
||||
//threshold: 0,
|
||||
minlength: 4,
|
||||
fastupdate: false
|
||||
},
|
||||
|
||||
"performance": {
|
||||
//charset: "latin",
|
||||
//tokenize: "strict",
|
||||
resolution: 3,
|
||||
minlength: 3,
|
||||
//fastupdate: true,
|
||||
optimize: false,
|
||||
//fastupdate: true,
|
||||
context: {
|
||||
depth: 2,
|
||||
resolution: 1
|
||||
//bidirectional: false
|
||||
}
|
||||
},
|
||||
|
||||
"match": {
|
||||
charset: "latin:extra",
|
||||
tokenize: "reverse",
|
||||
//resolution: 9,
|
||||
//threshold: 0
|
||||
},
|
||||
|
||||
"score": {
|
||||
charset: "latin:advanced",
|
||||
//tokenize: "strict",
|
||||
resolution: 20,
|
||||
minlength: 3,
|
||||
context: {
|
||||
depth: 3,
|
||||
resolution: 9,
|
||||
//bidirectional: true
|
||||
}
|
||||
},
|
||||
|
||||
"default": {
|
||||
// charset: "latin:default",
|
||||
// tokenize: "strict",
|
||||
// resolution: 3,
|
||||
// threshold: 0,
|
||||
// depth: 3
|
||||
},
|
||||
|
||||
// "fast": {
|
||||
// //charset: "latin",
|
||||
// //tokenize: "strict",
|
||||
// threshold: 8,
|
||||
// resolution: 9,
|
||||
// depth: 1
|
||||
// }
|
||||
};
|
||||
|
||||
export default function apply_preset(options){
|
||||
|
||||
if(is_string(options)){
|
||||
|
||||
if(DEBUG && !preset[options]){
|
||||
|
||||
console.warn("Preset not found: " + options);
|
||||
}
|
||||
|
||||
options = preset[options];
|
||||
}
|
||||
else{
|
||||
|
||||
const preset = options["preset"];
|
||||
|
||||
if(preset){
|
||||
|
||||
if(DEBUG && !preset[preset]){
|
||||
|
||||
console.warn("Preset not found: " + preset);
|
||||
}
|
||||
|
||||
options = Object.assign({}, preset[preset], /** @type {Object} */ (options));
|
||||
}
|
||||
}
|
||||
|
||||
return options;
|
||||
}
|
274
paige/node_modules/flexsearch/src/serialize.js
generated
vendored
Normal file
274
paige/node_modules/flexsearch/src/serialize.js
generated
vendored
Normal file
@@ -0,0 +1,274 @@
|
||||
// TODO return promises instead of inner await
|
||||
|
||||
import { IndexInterface, DocumentInterface } from "./type.js";
|
||||
import { create_object, is_string } from "./common.js";
|
||||
|
||||
function async(callback, self, field, key, index_doc, index, data, on_done){
|
||||
|
||||
setTimeout(function(){
|
||||
|
||||
const res = callback(field ? field + "." + key : key, JSON.stringify(data));
|
||||
|
||||
// await isn't supported by ES5
|
||||
|
||||
if(res && res["then"]){
|
||||
|
||||
res["then"](function(){
|
||||
|
||||
self.export(callback, self, field, index_doc, index + 1, on_done);
|
||||
})
|
||||
}
|
||||
else{
|
||||
|
||||
self.export(callback, self, field, index_doc, index + 1, on_done);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* @this IndexInterface
|
||||
*/
|
||||
|
||||
export function exportIndex(callback, self, field, index_doc, index, on_done){
|
||||
|
||||
let return_value = true
|
||||
if (typeof on_done === 'undefined') {
|
||||
return_value = new Promise((resolve) => {
|
||||
on_done = resolve
|
||||
})
|
||||
}
|
||||
|
||||
let key, data;
|
||||
|
||||
switch(index || (index = 0)){
|
||||
|
||||
case 0:
|
||||
|
||||
key = "reg";
|
||||
|
||||
// fastupdate isn't supported by export
|
||||
|
||||
if(this.fastupdate){
|
||||
|
||||
data = create_object();
|
||||
|
||||
for(let key in this.register){
|
||||
|
||||
data[key] = 1;
|
||||
}
|
||||
}
|
||||
else{
|
||||
|
||||
data = this.register;
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case 1:
|
||||
|
||||
key = "cfg";
|
||||
data = {
|
||||
"doc": 0,
|
||||
"opt": this.optimize ? 1 : 0
|
||||
};
|
||||
|
||||
break;
|
||||
|
||||
case 2:
|
||||
|
||||
key = "map";
|
||||
data = this.map;
|
||||
break;
|
||||
|
||||
case 3:
|
||||
|
||||
key = "ctx";
|
||||
data = this.ctx;
|
||||
break;
|
||||
|
||||
default:
|
||||
|
||||
if (typeof field === 'undefined' && on_done) {
|
||||
|
||||
on_done();
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
async(callback, self || this, field, key, index_doc, index, data, on_done);
|
||||
|
||||
return return_value;
|
||||
}
|
||||
|
||||
/**
|
||||
* @this IndexInterface
|
||||
*/
|
||||
|
||||
export function importIndex(key, data){
|
||||
|
||||
if(!data){
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if(is_string(data)){
|
||||
|
||||
data = JSON.parse(data);
|
||||
}
|
||||
|
||||
switch(key){
|
||||
|
||||
case "cfg":
|
||||
|
||||
this.optimize = !!data["opt"];
|
||||
break;
|
||||
|
||||
case "reg":
|
||||
|
||||
// fastupdate isn't supported by import
|
||||
|
||||
this.fastupdate = false;
|
||||
this.register = data;
|
||||
break;
|
||||
|
||||
case "map":
|
||||
|
||||
this.map = data;
|
||||
break;
|
||||
|
||||
case "ctx":
|
||||
|
||||
this.ctx = data;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @this DocumentInterface
|
||||
*/
|
||||
|
||||
export function exportDocument(callback, self, field, index_doc, index, on_done){
|
||||
|
||||
let return_value
|
||||
if (typeof on_done === 'undefined') {
|
||||
return_value = new Promise((resolve) => {
|
||||
on_done = resolve
|
||||
})
|
||||
}
|
||||
|
||||
index || (index = 0);
|
||||
index_doc || (index_doc = 0);
|
||||
|
||||
if(index_doc < this.field.length){
|
||||
|
||||
const field = this.field[index_doc];
|
||||
const idx = this.index[field];
|
||||
|
||||
self = this;
|
||||
|
||||
setTimeout(function(){
|
||||
|
||||
if(!idx.export(callback, self, index ? field/*.replace(":", "-")*/ : "", index_doc, index++, on_done)){
|
||||
|
||||
index_doc++;
|
||||
index = 1;
|
||||
|
||||
self.export(callback, self, field, index_doc, index, on_done);
|
||||
}
|
||||
});
|
||||
}
|
||||
else{
|
||||
|
||||
let key, data;
|
||||
|
||||
switch(index){
|
||||
|
||||
case 1:
|
||||
|
||||
key = "tag";
|
||||
data = this.tagindex;
|
||||
field = null;
|
||||
break;
|
||||
|
||||
case 2:
|
||||
|
||||
key = "store";
|
||||
data = this.store;
|
||||
field = null;
|
||||
break;
|
||||
|
||||
// case 3:
|
||||
//
|
||||
// key = "reg";
|
||||
// data = this.register;
|
||||
// break;
|
||||
|
||||
default:
|
||||
|
||||
on_done();
|
||||
return;
|
||||
}
|
||||
|
||||
async(callback, this, field, key, index_doc, index, data, on_done);
|
||||
}
|
||||
|
||||
return return_value
|
||||
}
|
||||
|
||||
/**
|
||||
* @this DocumentInterface
|
||||
*/
|
||||
|
||||
export function importDocument(key, data){
|
||||
|
||||
if(!data){
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if(is_string(data)){
|
||||
|
||||
data = JSON.parse(data);
|
||||
}
|
||||
|
||||
switch(key){
|
||||
|
||||
case "tag":
|
||||
|
||||
this.tagindex = data;
|
||||
break;
|
||||
|
||||
case "reg":
|
||||
|
||||
// fastupdate isn't supported by import
|
||||
|
||||
this.fastupdate = false;
|
||||
this.register = data;
|
||||
|
||||
for(let i = 0, index; i < this.field.length; i++){
|
||||
|
||||
index = this.index[this.field[i]];
|
||||
index.register = data;
|
||||
index.fastupdate = false;
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case "store":
|
||||
|
||||
this.store = data;
|
||||
break;
|
||||
|
||||
default:
|
||||
|
||||
key = key.split(".");
|
||||
const field = key[0];
|
||||
key = key[1];
|
||||
|
||||
if(field && key){
|
||||
|
||||
this.index[field].import(key, data);
|
||||
}
|
||||
}
|
||||
}
|
69
paige/node_modules/flexsearch/src/type.js
generated
vendored
Normal file
69
paige/node_modules/flexsearch/src/type.js
generated
vendored
Normal file
@@ -0,0 +1,69 @@
|
||||
/**
|
||||
* @interface
|
||||
*/
|
||||
|
||||
export function IndexInterface(){
|
||||
|
||||
this.cache = null;
|
||||
this.matcher = null;
|
||||
this.stemmer = null;
|
||||
this.filter = null;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {!string} str
|
||||
* @param {boolean|Array<string|RegExp>=} normalize
|
||||
* @param {boolean|string|RegExp=} split
|
||||
* @param {boolean=} collapse
|
||||
* @returns {string|Array<string>}
|
||||
*/
|
||||
|
||||
//IndexInterface.prototype.pipeline;
|
||||
|
||||
/**
|
||||
* @param {!number|string} id
|
||||
* @param {!string} content
|
||||
*/
|
||||
|
||||
IndexInterface.prototype.add;
|
||||
|
||||
/**
|
||||
* @param {!number|string} id
|
||||
* @param {!string} content
|
||||
*/
|
||||
|
||||
IndexInterface.prototype.append;
|
||||
|
||||
/**
|
||||
* @param {!string|Object} query
|
||||
* @param {number|Object=} limit
|
||||
* @param {Object=} options
|
||||
* @returns {Array<number|string>}
|
||||
*/
|
||||
|
||||
IndexInterface.prototype.search;
|
||||
|
||||
/**
|
||||
* @param {!number|string} id
|
||||
* @param {!string} content
|
||||
*/
|
||||
|
||||
IndexInterface.prototype.update;
|
||||
|
||||
/**
|
||||
* @param {!number|string} id
|
||||
*/
|
||||
|
||||
IndexInterface.prototype.remove;
|
||||
|
||||
/**
|
||||
* @interface
|
||||
*/
|
||||
|
||||
export function DocumentInterface(){
|
||||
|
||||
this.field = null;
|
||||
|
||||
/** @type IndexInterface */
|
||||
this.index = null;
|
||||
}
|
100
paige/node_modules/flexsearch/src/webpack.js
generated
vendored
Normal file
100
paige/node_modules/flexsearch/src/webpack.js
generated
vendored
Normal file
@@ -0,0 +1,100 @@
|
||||
import { RELEASE, SUPPORT_ASYNC, SUPPORT_DOCUMENT, SUPPORT_CACHE, SUPPORT_SERIALIZE, SUPPORT_WORKER, SUPPORT_ENCODER } from "./config.js";
|
||||
import Document from "./document.js";
|
||||
import Index from "./index.js";
|
||||
import WorkerIndex from "./worker/index.js";
|
||||
import { registerCharset, registerLanguage } from "./global.js";
|
||||
import charset_default from "./lang/latin/default.js"
|
||||
import charset_simple from "./lang/latin/simple.js"
|
||||
import charset_balance from "./lang/latin/balance.js"
|
||||
import charset_advanced from "./lang/latin/advanced.js"
|
||||
import charset_extra from "./lang/latin/extra.js"
|
||||
|
||||
/** @export */ Document.prototype.add;
|
||||
/** @export */ Document.prototype.append;
|
||||
/** @export */ Document.prototype.search;
|
||||
/** @export */ Document.prototype.update;
|
||||
/** @export */ Document.prototype.remove;
|
||||
/** @export */ Document.prototype.contain;
|
||||
/** @export */ Document.prototype.get;
|
||||
/** @export */ Document.prototype.set;
|
||||
|
||||
/** @export */ Index.prototype.add;
|
||||
/** @export */ Index.prototype.append;
|
||||
/** @export */ Index.prototype.search;
|
||||
/** @export */ Index.prototype.update;
|
||||
/** @export */ Index.prototype.remove;
|
||||
/** @export */ Index.prototype.contain;
|
||||
|
||||
if(SUPPORT_CACHE){
|
||||
|
||||
/** @export */ Index.prototype.searchCache;
|
||||
/** @export */ Document.prototype.searchCache;
|
||||
}
|
||||
|
||||
if(SUPPORT_ASYNC){
|
||||
|
||||
/** @export */ Document.prototype.addAsync;
|
||||
/** @export */ Document.prototype.appendAsync;
|
||||
/** @export */ Document.prototype.searchAsync;
|
||||
/** @export */ Document.prototype.updateAsync;
|
||||
/** @export */ Document.prototype.removeAsync;
|
||||
|
||||
/** @export */ Index.prototype.addAsync;
|
||||
/** @export */ Index.prototype.appendAsync;
|
||||
/** @export */ Index.prototype.searchAsync;
|
||||
/** @export */ Index.prototype.updateAsync;
|
||||
/** @export */ Index.prototype.removeAsync;
|
||||
}
|
||||
|
||||
if(SUPPORT_SERIALIZE){
|
||||
|
||||
/** @export */ Index.prototype.export;
|
||||
/** @export */ Index.prototype.import;
|
||||
/** @export */ Document.prototype.export;
|
||||
/** @export */ Document.prototype.import;
|
||||
}
|
||||
|
||||
if(SUPPORT_ENCODER){
|
||||
|
||||
registerCharset("latin:default", charset_default);
|
||||
registerCharset("latin:simple", charset_simple);
|
||||
registerCharset("latin:balance", charset_balance);
|
||||
registerCharset("latin:advanced", charset_advanced);
|
||||
registerCharset("latin:extra", charset_extra);
|
||||
}
|
||||
|
||||
const FlexSearch = {
|
||||
|
||||
"Index": Index,
|
||||
"Document": SUPPORT_DOCUMENT ? Document : null,
|
||||
"Worker": SUPPORT_WORKER ? WorkerIndex : null,
|
||||
"registerCharset": registerCharset,
|
||||
"registerLanguage": registerLanguage
|
||||
};
|
||||
|
||||
if(RELEASE !== "bundle.module" && RELEASE !== "light.module" && RELEASE !== "compact.module"){
|
||||
|
||||
let tmp;
|
||||
|
||||
if((tmp = self["define"]) && tmp["amd"]){
|
||||
|
||||
tmp([], function(){
|
||||
|
||||
return FlexSearch;
|
||||
});
|
||||
}
|
||||
else if(self["exports"]){
|
||||
|
||||
self["exports"] = FlexSearch;
|
||||
}
|
||||
else{
|
||||
|
||||
/** @export */
|
||||
self.FlexSearch = FlexSearch;
|
||||
}
|
||||
}
|
||||
else{
|
||||
|
||||
/** @export */
|
||||
self.FlexSearch = FlexSearch;
|
||||
}
|
51
paige/node_modules/flexsearch/src/worker/handler.js
generated
vendored
Normal file
51
paige/node_modules/flexsearch/src/worker/handler.js
generated
vendored
Normal file
@@ -0,0 +1,51 @@
|
||||
import Index from "../index.js";
|
||||
|
||||
export default function(data) {
|
||||
|
||||
data = data["data"];
|
||||
|
||||
/** @type Index */
|
||||
const index = self["_index"];
|
||||
const args = data["args"];
|
||||
const task = data["task"];
|
||||
|
||||
switch(task){
|
||||
|
||||
case "init":
|
||||
|
||||
const options = data["options"] || {};
|
||||
const factory = data["factory"];
|
||||
const encode = options["encode"];
|
||||
|
||||
options["cache"] = false;
|
||||
|
||||
if(encode && (encode.indexOf("function") === 0)){
|
||||
|
||||
options["encode"] = Function("return " + encode)();
|
||||
}
|
||||
|
||||
if(factory){
|
||||
|
||||
// export the FlexSearch global payload to "self"
|
||||
Function("return " + factory)()(self);
|
||||
|
||||
/** @type Index */
|
||||
self["_index"] = new self["FlexSearch"]["Index"](options);
|
||||
|
||||
// destroy the exported payload
|
||||
delete self["FlexSearch"];
|
||||
}
|
||||
else{
|
||||
|
||||
self["_index"] = new Index(options);
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
default:
|
||||
|
||||
const id = data["id"];
|
||||
const message = index[task].apply(index, args);
|
||||
postMessage(task === "search" ? { "id": id, "msg": message } : { "id": id });
|
||||
}
|
||||
};
|
157
paige/node_modules/flexsearch/src/worker/index.js
generated
vendored
Normal file
157
paige/node_modules/flexsearch/src/worker/index.js
generated
vendored
Normal file
@@ -0,0 +1,157 @@
|
||||
//import { promise as Promise } from "../polyfill.js";
|
||||
import { create_object, is_function, is_object, is_string } from "../common.js";
|
||||
import handler from "./handler.js";
|
||||
|
||||
let pid = 0;
|
||||
|
||||
/**
|
||||
* @param {Object=} options
|
||||
* @constructor
|
||||
*/
|
||||
|
||||
function WorkerIndex(options){
|
||||
|
||||
if(!(this instanceof WorkerIndex)) {
|
||||
|
||||
return new WorkerIndex(options);
|
||||
}
|
||||
|
||||
let opt;
|
||||
|
||||
if(options){
|
||||
|
||||
if(is_function(opt = options["encode"])){
|
||||
|
||||
options["encode"] = opt.toString();
|
||||
}
|
||||
}
|
||||
else{
|
||||
|
||||
options = {};
|
||||
}
|
||||
|
||||
// the factory is the outer wrapper from the build
|
||||
// we use "self" as a trap for node.js
|
||||
|
||||
let factory = (self||window)["_factory"];
|
||||
|
||||
if(factory){
|
||||
|
||||
factory = factory.toString();
|
||||
}
|
||||
|
||||
const is_node_js = typeof window === "undefined" && self["exports"];
|
||||
const _self = this;
|
||||
|
||||
this.worker = create(factory, is_node_js, options["worker"]);
|
||||
this.resolver = create_object();
|
||||
|
||||
if(!this.worker){
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if(is_node_js){
|
||||
|
||||
this.worker["on"]("message", function(msg){
|
||||
|
||||
_self.resolver[msg["id"]](msg["msg"]) ;
|
||||
delete _self.resolver[msg["id"]];
|
||||
});
|
||||
}
|
||||
else{
|
||||
|
||||
this.worker.onmessage = function(msg){
|
||||
|
||||
msg = msg["data"];
|
||||
_self.resolver[msg["id"]](msg["msg"]);
|
||||
delete _self.resolver[msg["id"]];
|
||||
};
|
||||
}
|
||||
|
||||
this.worker.postMessage({
|
||||
|
||||
"task": "init",
|
||||
"factory": factory,
|
||||
"options": options
|
||||
});
|
||||
}
|
||||
|
||||
export default WorkerIndex;
|
||||
|
||||
register("add");
|
||||
register("append");
|
||||
register("search");
|
||||
register("update");
|
||||
register("remove");
|
||||
|
||||
function register(key){
|
||||
|
||||
WorkerIndex.prototype[key] =
|
||||
WorkerIndex.prototype[key + "Async"] = function(){
|
||||
|
||||
const self = this;
|
||||
const args = [].slice.call(arguments);
|
||||
const arg = args[args.length - 1];
|
||||
let callback;
|
||||
|
||||
if(is_function(arg)){
|
||||
|
||||
callback = arg;
|
||||
args.splice(args.length - 1, 1);
|
||||
}
|
||||
|
||||
const promise = new Promise(function(resolve){
|
||||
|
||||
setTimeout(function(){
|
||||
|
||||
self.resolver[++pid] = resolve;
|
||||
self.worker.postMessage({
|
||||
|
||||
"task": key,
|
||||
"id": pid,
|
||||
"args": args
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
if(callback){
|
||||
|
||||
promise.then(callback);
|
||||
return this;
|
||||
}
|
||||
else{
|
||||
|
||||
return promise;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
function create(factory, is_node_js, worker_path){
|
||||
|
||||
let worker
|
||||
|
||||
try{
|
||||
|
||||
worker = is_node_js ?
|
||||
|
||||
eval('new (require("worker_threads")["Worker"])(__dirname + "/node/node.js")')
|
||||
:(
|
||||
factory ?
|
||||
|
||||
new Worker(URL.createObjectURL(
|
||||
|
||||
new Blob([
|
||||
|
||||
"onmessage=" + handler.toString()
|
||||
|
||||
], { "type": "text/javascript" })
|
||||
))
|
||||
:
|
||||
new Worker(is_string(worker_path) ? worker_path : "worker/worker.js", { type: "module" })
|
||||
);
|
||||
}
|
||||
catch(e){}
|
||||
|
||||
return worker;
|
||||
}
|
35
paige/node_modules/flexsearch/src/worker/node.js
generated
vendored
Normal file
35
paige/node_modules/flexsearch/src/worker/node.js
generated
vendored
Normal file
@@ -0,0 +1,35 @@
|
||||
const { parentPort } = require("worker_threads");
|
||||
const { Index } = require("../flexsearch.bundle.min.js");
|
||||
|
||||
let index;
|
||||
|
||||
parentPort.on("message", function(data){
|
||||
|
||||
/** @type Index */
|
||||
const args = data["args"];
|
||||
const task = data["task"];
|
||||
const id = data["id"];
|
||||
|
||||
switch(task){
|
||||
|
||||
case "init":
|
||||
|
||||
const options = data["options"] || {};
|
||||
const encode = options["encode"];
|
||||
|
||||
options["cache"] = false;
|
||||
|
||||
if(encode && (encode.indexOf("function") === 0)){
|
||||
|
||||
options["encode"] = new Function("return " + encode)();
|
||||
}
|
||||
|
||||
index = new Index(options);
|
||||
break;
|
||||
|
||||
default:
|
||||
|
||||
const message = index[task].apply(index, args);
|
||||
parentPort.postMessage(task === "search" ? { "id": id, "msg": message } : { "id": id });
|
||||
}
|
||||
});
|
2
paige/node_modules/flexsearch/src/worker/worker.js
generated
vendored
Normal file
2
paige/node_modules/flexsearch/src/worker/worker.js
generated
vendored
Normal file
@@ -0,0 +1,2 @@
|
||||
import handler from "./handler.js";
|
||||
onmessage = handler;
|
Reference in New Issue
Block a user