1
0
mirror of https://github.com/nextapps-de/flexsearch.git synced 2025-09-25 12:58:59 +02:00
Files
flexsearch/dist/module-debug/resolver.js
2025-09-07 12:32:39 +02:00

263 lines
7.6 KiB
JavaScript

import { ResolverOptions, IntermediateSearchResults, SearchResults, EnrichedSearchResults, HighlightOptions } from "./type.js";
import Index from "./index.js";
import Document from "./document.js";
import WorkerIndex from "./worker.js";
import default_resolver from "./resolve/default.js";
import "./resolve/handler.js";
import "./resolve/or.js";
import "./resolve/and.js";
import "./resolve/xor.js";
import "./resolve/not.js";
import { apply_enrich } from "./document/search.js";
import { highlight_fields } from "./document/highlight.js";
/**
* @param {IntermediateSearchResults|ResolverOptions=} result
* @param {Index|Document|WorkerIndex=} index
* @return {Resolver}
* @constructor
*/
export default function Resolver(result, index) {
if (!this || this.constructor !== Resolver) {
return new Resolver(result, index);
}
let boost = 0,
promises,
query,
field,
highlight,
_await,
_return;
if (result && result.index) {
const options = /** @type {ResolverOptions} */result;
index = options.index;
boost = options.boost || 0;
if (query = options.query) {
field = options.field || options.pluck;
highlight = options.highlight;
const resolve = options.resolve,
async = options.async || options.queue;
options.resolve = !1;
options.highlight = "";
options.index = null;
result = async ? index.searchAsync(options) : index.search(options);
options.resolve = resolve;
options.highlight = highlight;
options.index = index;
result = result.result || result;
} else {
result = [];
}
}
if (result && result.then) {
const self = this;
result = result.then(function (result) {
self.promises[0] = self.result = result.result || result;
self.execute();
});
promises = [result];
result = [];
_await = new Promise(function (resolve) {
_return = resolve;
});
}
/** @type {Index|Document|WorkerIndex|null} */
this.index = index || null;
/** @type {IntermediateSearchResults} */
this.result = /** @type {IntermediateSearchResults} */result || [];
/** @type {number} */
this.boostval = boost;
/** @type {Array<Promise<IntermediateSearchResults>|IntermediateSearchResults|Function>} */
this.promises = promises || [];
/** @type {Promise<SearchResults|EnrichedSearchResults>} */
this.await = _await || null;
/** @type {Function} */
this.return = _return || null;
/** @type {HighlightOptions|null} */
this.highlight = /** @type {HighlightOptions|null} */highlight || null;
/** @type {string} */
this.query = query || "";
/** @type {string} */
this.field = field || "";
}
/**
* @param {number} limit
*/
Resolver.prototype.limit = function (limit) {
if (this.await) {
const self = this;
this.promises.push(function () {
return self.limit(limit).result;
});
} else {
if (this.result.length) {
/** @type {IntermediateSearchResults} */
const final = [];
for (let j = 0, ids; j < this.result.length; j++) {
if (ids = this.result[j]) {
if (ids.length <= limit) {
final[j] = ids;
limit -= ids.length;
if (!limit) break;
} else {
final[j] = ids.slice(0, limit);
break;
}
}
}
this.result = final;
}
}
return this;
};
/**
* @param {number} offset
*/
Resolver.prototype.offset = function (offset) {
if (this.await) {
const self = this;
this.promises.push(function () {
return self.offset(offset).result;
});
} else {
if (this.result.length) {
/** @type {IntermediateSearchResults} */
const final = [];
for (let j = 0, ids; j < this.result.length; j++) {
if (ids = this.result[j]) {
if (ids.length <= offset) {
offset -= ids.length;
} else {
final[j] = ids.slice(offset);
offset = 0;
}
}
}
this.result = final;
}
}
return this;
};
/**
* @param {number} boost
*/
Resolver.prototype.boost = function (boost) {
if (this.await) {
const self = this;
this.promises.push(function () {
return self.boost(boost).result;
});
} else {
this.boostval += boost;
}
return this;
};
/**
* @param {boolean=} _skip_callback
* @this {Resolver}
*/
Resolver.prototype.execute = function (_skip_callback) {
let result = this.result,
execute = this.await;
this.await = null;
for (let i = 0, promise; i < this.promises.length; i++) {
if (promise = this.promises[i]) {
if ("function" == typeof promise) {
result = promise();
this.promises[i] = result = result.result || result;
i--;
} else if (promise._fn) {
result = promise._fn();
this.promises[i] = result = result.result || result;
i--;
} else if (promise.then) {
return this.await = execute;
}
}
}
const fn = this.return;
this.promises = [];
this.return = null;
_skip_callback || fn(result);
return result;
};
/**
* @param {number|ResolverOptions=} limit
* @param {number=} offset
* @param {boolean=} enrich
* @param {string|HighlightOptions|boolean=} highlight
* @param {boolean=} _resolved
*/
Resolver.prototype.resolve = function (limit, offset, enrich, highlight, _resolved) {
let result = this.await ? this.execute(!0) : this.result;
if (result.then) {
const self = this;
return result.then(function () {
return self.resolve(limit, offset, enrich, highlight, _resolved);
});
}
if (result.length) {
if ("object" == typeof limit) {
highlight = limit.highlight || this.highlight;
enrich = !!highlight || limit.enrich;
offset = limit.offset;
limit = limit.limit;
} else {
highlight = highlight || this.highlight;
enrich = !!highlight || enrich;
}
result = _resolved ? enrich ? apply_enrich.call(
/** @type {Document} */this.index,
/** @type {SearchResults} */result) : result : default_resolver.call(this.index, result, limit || 100, offset, enrich);
}
return this.finalize(result, highlight);
};
Resolver.prototype.finalize = function (result, highlight) {
if (result.then) {
const self = this;
return result.then(function (result) {
return self.finalize(result, highlight);
});
}
if (highlight && !this.query) {
console.warn('There was no query specified for highlighting. Please specify a query within the highlight resolver stage like { query: "...", highlight: ... }.');
}
if (highlight && result.length && this.query) {
result = highlight_fields(this.query, result, this.index.index, this.field, highlight);
}
const fn = this.return;
this.index = this.result = this.promises = this.await = this.return = null;
this.highlight = null;
this.query = this.field = "";
fn && fn(result);
return result;
};