feat: Refactor autocomplete data handling to build FlexSearch index after tags are loaded
This commit is contained in:
@@ -103,8 +103,8 @@ function searchCompletionCandidates(textareaElement) {
|
||||
|
||||
const sources = getEnabledTagSourceInPriorityOrder();
|
||||
for (const source of sources) {
|
||||
if (autoCompleteData[source].use_fuse && autoCompleteData[source].fuse) {
|
||||
const searchResults = autoCompleteData[source].fuse.search(partialTag, {
|
||||
if (settingValues.useFastSearch && autoCompleteData[source].flexSearchIndex) {
|
||||
const searchResults = autoCompleteData[source].flexSearchIndex.search(partialTag, {
|
||||
limit: settingValues.maxSuggestions,
|
||||
suggest: false,
|
||||
cache: true,
|
||||
|
||||
+29
-15
@@ -1,4 +1,4 @@
|
||||
import { Index } from './thirdparty/flexsearch.bundle.module.min.js'
|
||||
import { Charset, Index } from './thirdparty/flexsearch.bundle.module.min.js'
|
||||
import { settingValues } from "./settings.js";
|
||||
|
||||
// --- Constants ---
|
||||
@@ -65,10 +65,7 @@ export class TagData {
|
||||
class AutocompleteData {
|
||||
constructor() {
|
||||
/** @type {Index} */
|
||||
this.fuse = null;
|
||||
|
||||
/** @type {boolean} */
|
||||
this.use_fuse = false;
|
||||
this.flexSearchIndex = null;
|
||||
|
||||
/** @type {TagData[]} */
|
||||
this.sortedTags = [];
|
||||
@@ -189,8 +186,20 @@ async function loadTags(csvUrl, siteName) {
|
||||
}
|
||||
});
|
||||
|
||||
autoCompleteData[siteName].fuse = new Index({
|
||||
} catch (error) {
|
||||
console.error(`[Autocomplete-Plus] Failed to fetch or process tags from ${csvUrl}:`, error);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Build FlexSearch index for the given site name.
|
||||
* @param {string} siteName
|
||||
*/
|
||||
async function buildFlexSearchIndex(siteName) {
|
||||
try {
|
||||
const index = new Index({
|
||||
tokenize: "forward",
|
||||
// encoder: Charset.CJK, // FIXME: English search doesn't work properly when using CJK
|
||||
});
|
||||
|
||||
let startIdx = 0;
|
||||
@@ -208,7 +217,7 @@ async function loadTags(csvUrl, siteName) {
|
||||
});
|
||||
}
|
||||
allTags = [...new Set(allTags)];
|
||||
autoCompleteData[siteName].fuse.add(startIdx, allTags.join(','));
|
||||
index.add(startIdx, allTags.join(','));
|
||||
}
|
||||
|
||||
if (startIdx < autoCompleteData[siteName].sortedTags.length) {
|
||||
@@ -217,13 +226,13 @@ async function loadTags(csvUrl, siteName) {
|
||||
} else {
|
||||
const endTime = performance.now();
|
||||
const duration = endTime - startTime;
|
||||
autoCompleteData[siteName].use_fuse = true;
|
||||
autoCompleteData[siteName].flexSearchIndex = index;
|
||||
console.debug(`[Autocomplete-Plus] Building ${autoCompleteData[siteName].sortedTags.length} index for ${siteName} took ${duration.toFixed(2)}ms.`);
|
||||
}
|
||||
}
|
||||
processChunkTasks();
|
||||
} catch (error) {
|
||||
console.error(`[Autocomplete-Plus] Failed to fetch or process tags from ${csvUrl}:`, error);
|
||||
console.error(`[Autocomplete-Plus] Failed to building flexSearch index`, error);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -415,12 +424,17 @@ export async function initializeData(csvListData, source) {
|
||||
// Now, execute all promise factories and wait for their completion.
|
||||
// The actual loading (fetch calls) will start when the factories are invoked here.
|
||||
await Promise.all([
|
||||
Promise.all(tagsLoadPromiseFactories.map(factory => factory())).then(() => {
|
||||
const endTime = performance.now();
|
||||
if (csvListData[source].base_tags) {
|
||||
console.log(`[Autocomplete-Plus] "${source}" Tags loading complete in ${(endTime - startTime).toFixed(2)}ms`);
|
||||
}
|
||||
}),
|
||||
Promise.all(tagsLoadPromiseFactories.map(factory => factory()))
|
||||
.then(() => {
|
||||
// Build FlexSearch index after tags are loaded
|
||||
return buildFlexSearchIndex(source);
|
||||
})
|
||||
.then(() => {
|
||||
const endTime = performance.now();
|
||||
if (csvListData[source].base_tags) {
|
||||
console.log(`[Autocomplete-Plus] "${source}" Tags loading complete in ${(endTime - startTime).toFixed(2)}ms`);
|
||||
}
|
||||
}),
|
||||
Promise.all(cooccurrenceLoadPromiseFactories.map(factory => factory())).then(() => {
|
||||
const endTime = performance.now();
|
||||
if (csvListData[source].base_cooccurrence) {
|
||||
|
||||
@@ -7,6 +7,7 @@ export const settingValues = {
|
||||
// Autocomplete feature settings
|
||||
enabled: true,
|
||||
maxSuggestions: 10,
|
||||
useFastSearch: false,
|
||||
|
||||
// Related tags feature settings
|
||||
enableRelatedTags: true,
|
||||
|
||||
Reference in New Issue
Block a user