Encapsulate logic into filters instead of spreading around
| @@ -1,113 +0,0 @@ | ||
| 1 | -## Input Sources to printCharacters | |
| 2 | - | |
| 3 | -`printCharacters` is the main function that triggers the fuzzy search process if fuzzy search is enabled. | |
| 4 | - | |
| 5 | -```mermaid | |
| 6 | -%%{init: {'flowchart': {'nodeSpacing': 50, 'rankSpacing': 50}}}%% | |
| 7 | -flowchart TD | |
| 8 | - subgraph User Actions | |
| 9 | - UA1[Character Search Input] | |
| 10 | - UA2[Tag Filter Click] | |
| 11 | - UA3[Folder Navigation] | |
| 12 | - UA4[Character Delete] | |
| 13 | - UA5[Character Create] | |
| 14 | - UA6[Character Import] | |
| 15 | - UA7[Clear All Filters] | |
| 16 | - UA8[Bulk Edit Operations] | |
| 17 | - UA9[Persona Changes] | |
| 18 | - end | |
| 19 | - | |
| 20 | - subgraph API Events | |
| 21 | - API1[Character List Update] | |
| 22 | - API2[Group Update] | |
| 23 | - API3[Tag Update] | |
| 24 | - end | |
| 25 | - | |
| 26 | - subgraph System Events | |
| 27 | - SE1[Page Load] | |
| 28 | - SE2[Content Manager Update] | |
| 29 | - SE3[Extension Events] | |
| 30 | - end | |
| 31 | - | |
| 32 | - UA1 -->|triggers| PCD[printCharactersDebounced] | |
| 33 | - UA2 -->|triggers| PCD | |
| 34 | - UA7 -->|triggers| PCD | |
| 35 | - UA8 -->|triggers| PCD | |
| 36 | - UA9 -->|triggers| PCD | |
| 37 | - | |
| 38 | - UA3 -->|triggers| PC[printCharacters] | |
| 39 | - UA4 -->|triggers| PC | |
| 40 | - UA5 -->|triggers| PC | |
| 41 | - UA6 -->|triggers| PC | |
| 42 | - | |
| 43 | - API1 -->|triggers| PC | |
| 44 | - API2 -->|triggers| PC | |
| 45 | - API3 -->|triggers| PC | |
| 46 | - | |
| 47 | - SE1 -->|triggers| PC | |
| 48 | - SE2 -->|triggers| PC | |
| 49 | - SE3 -->|triggers| PC | |
| 50 | - | |
| 51 | - PCD -->|debounced call| PC | |
| 52 | - | |
| 53 | - style PC fill:#f96,stroke:#333 | |
| 54 | - style PCD fill:#f96,stroke:#333 | |
| 55 | -``` | |
| 56 | - | |
| 57 | -This diagram shows how `printCharacters` is called throughout the application: | |
| 58 | - | |
| 59 | -1. User Actions that trigger character list updates: | |
| 60 | - - Search input (debounced) | |
| 61 | - - Tag filter clicks (debounced) | |
| 62 | - - Folder navigation (direct) | |
| 63 | - - Character management operations (direct) | |
| 64 | - | |
| 65 | -2. API Events that require list refresh: | |
| 66 | - - Character list updates | |
| 67 | - - Group updates | |
| 68 | - - Tag system updates | |
| 69 | - | |
| 70 | -3. System Events: | |
| 71 | - - Initial page load | |
| 72 | - - Content manager updates | |
| 73 | - - Extension-triggered refreshes | |
| 74 | - | |
| 75 | - | |
| 76 | - | |
| 77 | -## Fuzzy Search Flow | |
| 78 | - | |
| 79 | - | |
| 80 | -This diagram shows the flow of fuzzy search operations: | |
| 81 | -```mermaid | |
| 82 | -sequenceDiagram | |
| 83 | - participant Data as Data Sources | |
| 84 | - participant PC as printCharacters | |
| 85 | - participant GEL as getEntitiesList | |
| 86 | - participant FH as FilterHelper | |
| 87 | - participant AF as applyFilters | |
| 88 | - participant FS as FuzzySearch Functions | |
| 89 | - participant Cache as FuzzySearchCaches | |
| 90 | - | |
| 91 | - Note over Data: Changes from:<br/>- Tags<br/>- Personas<br/>- World Info<br/>- Groups | |
| 92 | - | |
| 93 | - Data->>PC: All changes trigger printCharacters<br/>(direct or debounced) | |
| 94 | - | |
| 95 | - PC->>GEL: Call with {doFilter: true} | |
| 96 | - GEL->>FH: filterByTagState(entities) | |
| 97 | - GEL->>AF: entitiesFilter.applyFilters(entities) | |
| 98 | - | |
| 99 | - AF->>FH: Check scoreCache for existing results | |
| 100 | - FH-->>AF: Return cached scores if exist | |
| 101 | - | |
| 102 | - Note over FS: Filter functions include:<br/>SEARCH, <br/>FAV, <br/>GROUP, <br/>FOLDER, <br/>TAG, <br/>WORLD_INFO_SEARCH, <br/>PERSONA_SEARCH | |
| 103 | - AF->>FS: fuzzySearchCharacters/Groups/Tags | |
| 104 | - FS->>Cache: Check/Store results | |
| 105 | - | |
| 106 | - FS-->>AF: Return search results | |
| 107 | - AF->>FH: Cache new scores | |
| 108 | - AF-->>GEL: Return filtered entities | |
| 109 | - GEL-->>PC: Return final entities list | |
| 110 | - | |
| 111 | - PC->>Cache: clearFuzzySearchCaches() | |
| 112 | - Note over Cache: Cache is cleared at the end of<br/>each printCharacters call,<br/>ensuring fresh results for next search | |
| 113 | -``` | |
| @@ -268,7 +268,6 @@ import { initServerHistory } from './scripts/server-history.js'; | ||
| 268 | 268 | import { initSettingsSearch } from './scripts/setting-search.js'; |
| 269 | 269 | import { initBulkEdit } from './scripts/bulk-edit.js'; |
| 270 | 270 | import { deriveTemplatesFromChatTemplate } from './scripts/chat-templates.js'; |
| 271 | -import { clearFuzzySearchCaches } from './scripts/power-user.js'; | |
| 272 | 271 | |
| 273 | 272 | //exporting functions and vars for mods |
| 274 | 273 | export { |
| @@ -1516,7 +1515,6 @@ export async function printCharacters(fullRefresh = false) { | ||
| 1516 | 1515 | }); |
| 1517 | 1516 | |
| 1518 | 1517 | favsToHotswap(); |
| 1519 | - clearFuzzySearchCaches(); | |
| 1520 | 1518 | } |
| 1521 | 1519 | |
| 1522 | 1520 | /** Checks the state of the current search, and adds/removes the search sorting option accordingly */ |
| @@ -1623,7 +1621,7 @@ export function getEntitiesList({ doFilter = false, doSort = true } = {}) { | ||
| 1623 | 1621 | subEntities = filterByTagState(entities, { subForEntity: entity }); |
| 1624 | 1622 | if (doFilter) { |
| 1625 | 1623 | // sub entities filter "hacked" because folder filter should not be applied there, so even in "only folders" mode characters show up |
| 1626 | 1624 | subEntities = entitiesFilter.applyFilters(subEntities, { clearScoreCache: false, tempOverrides: { [FILTER_TYPES.FOLDER]: FILTER_STATES.UNDEFINED }, clearFuzzySearchCaches: false }); |
| 1627 | 1625 | } |
| 1628 | 1626 | if (doSort) { |
| 1629 | 1627 | sortEntitiesList(subEntities); |
| @@ -1636,11 +1634,11 @@ export function getEntitiesList({ doFilter = false, doSort = true } = {}) { | ||
| 1636 | 1634 | // Second run filters, hiding whatever should be filtered later |
| 1637 | 1635 | if (doFilter) { |
| 1638 | 1636 | const beforeFinalEntities = filterByTagState(entities, { globalDisplayFilters: true }); |
| 1639 | 1637 | entities = entitiesFilter.applyFilters(beforeFinalEntities, { clearFuzzySearchCaches: false }); |
| 1640 | 1638 | |
| 1641 | 1639 | // Magic for folder filter. If that one is enabled, and no folders are display anymore, we remove that filter to actually show the characters. |
| 1642 | 1640 | if (isFilterState(entitiesFilter.getFilterData(FILTER_TYPES.FOLDER), FILTER_STATES.SELECTED) && entities.filter(x => x.type == 'tag').length == 0) { |
| 1643 | 1641 | entities = entitiesFilter.applyFilters(beforeFinalEntities, { tempOverrides: { [FILTER_TYPES.FOLDER]: FILTER_STATES.UNDEFINED }, clearFuzzySearchCaches: false }); |
| 1644 | 1642 | } |
| 1645 | 1643 | } |
| 1646 | 1644 | |
| @@ -1656,6 +1654,7 @@ export function getEntitiesList({ doFilter = false, doSort = true } = {}) { | ||
| 1656 | 1654 | if (doSort) { |
| 1657 | 1655 | sortEntitiesList(entities); |
| 1658 | 1656 | } |
| 1657 | + entitiesFilter.clearFuzzySearchCaches(); | |
| 1659 | 1658 | return entities; |
| 1660 | 1659 | } |
| 1661 | 1660 | |
| @@ -1751,6 +1750,7 @@ export async function getCharacters() { | ||
| 1751 | 1750 | } |
| 1752 | 1751 | |
| 1753 | 1752 | await getGroups(); |
| 1753 | + // clearFuzzySearchCaches(); | |
| 1754 | 1754 | await printCharacters(true); |
| 1755 | 1755 | } |
| 1756 | 1756 | } |
| @@ -56,6 +56,19 @@ export function isFilterState(a, b) { | ||
| 56 | 56 | } |
| 57 | 57 | |
| 58 | 58 | /** |
| 59 | + * The fuzzy search categories | |
| 60 | + * @type {{ characters: string, worldInfo: string, personas: string, tags: string, groups: string }} | |
| 61 | + */ | |
| 62 | +export const fuzzySearchCategories = Object.freeze({ | |
| 63 | + characters: 'characters', | |
| 64 | + worldInfo: 'worldInfo', | |
| 65 | + personas: 'personas', | |
| 66 | + tags: 'tags', | |
| 67 | + groups: 'groups', | |
| 68 | +}); | |
| 69 | + | |
| 70 | + | |
| 71 | +/** | |
| 59 | 72 | * Helper class for filtering data. |
| 60 | 73 | * @example |
| 61 | 74 | * const filterHelper = new FilterHelper(() => console.log('data changed')); |
| @@ -73,12 +86,25 @@ export class FilterHelper { | ||
| 73 | 86 | scoreCache; |
| 74 | 87 | |
| 75 | 88 | /** |
| 89 | + * Cache for fuzzy search results per category. | |
| 90 | + * @type {Object.<string, { resultMap: Map<string, any> }>} | |
| 91 | + */ | |
| 92 | + fuzzySearchCaches; | |
| 93 | + | |
| 94 | + /** | |
| 76 | 95 | * Creates a new FilterHelper |
| 77 | 96 | * @param {Function} onDataChanged Callback to trigger when the filter data changes |
| 78 | 97 | */ |
| 79 | 98 | constructor(onDataChanged) { |
| 80 | 99 | this.onDataChanged = onDataChanged; |
| 81 | 100 | this.scoreCache = new Map(); |
| 101 | + this.fuzzySearchCaches = { | |
| 102 | + [fuzzySearchCategories.characters]: { resultMap: new Map() }, | |
| 103 | + [fuzzySearchCategories.worldInfo]: { resultMap: new Map() }, | |
| 104 | + [fuzzySearchCategories.personas]: { resultMap: new Map() }, | |
| 105 | + [fuzzySearchCategories.tags]: { resultMap: new Map() }, | |
| 106 | + [fuzzySearchCategories.groups]: { resultMap: new Map() }, | |
| 107 | + }; | |
| 82 | 108 | } |
| 83 | 109 | |
| 84 | 110 | /** |
| @@ -151,7 +177,7 @@ export class FilterHelper { | ||
| 151 | 177 | return data; |
| 152 | 178 | } |
| 153 | 179 | |
| 154 | 180 | const fuzzySearchResults = fuzzySearchWorldInfo(data, term, this.fuzzySearchCaches); |
| 155 | 181 | this.cacheScores(FILTER_TYPES.WORLD_INFO_SEARCH, new Map(fuzzySearchResults.map(i => [i.item?.uid, i.score]))); |
| 156 | 182 | |
| 157 | 183 | const filteredData = data.filter(entity => fuzzySearchResults.find(x => x.item === entity)); |
| @@ -170,7 +196,7 @@ export class FilterHelper { | ||
| 170 | 196 | return data; |
| 171 | 197 | } |
| 172 | 198 | |
| 173 | 199 | const fuzzySearchResults = fuzzySearchPersonas(data, term, this.fuzzySearchCaches); |
| 174 | 200 | this.cacheScores(FILTER_TYPES.PERSONA_SEARCH, new Map(fuzzySearchResults.map(i => [i.item.key, i.score]))); |
| 175 | 201 | |
| 176 | 202 | const filteredData = data.filter(name => fuzzySearchResults.find(x => x.item.key === name)); |
| @@ -289,9 +315,9 @@ export class FilterHelper { | ||
| 289 | 315 | |
| 290 | 316 | // Save fuzzy search results and scores if enabled |
| 291 | 317 | if (power_user.fuzzy_search) { |
| 292 | 318 | const fuzzySearchCharactersResults = fuzzySearchCharacters(searchValue, this.fuzzySearchCaches); |
| 293 | 319 | const fuzzySearchGroupsResults = fuzzySearchGroups(searchValue, this.fuzzySearchCaches); |
| 294 | 320 | const fuzzySearchTagsResult = fuzzySearchTags(searchValue, this.fuzzySearchCaches); |
| 295 | 321 | this.cacheScores(FILTER_TYPES.SEARCH, new Map(fuzzySearchCharactersResults.map(i => [`character.${i.refIndex}`, i.score]))); |
| 296 | 322 | this.cacheScores(FILTER_TYPES.SEARCH, new Map(fuzzySearchGroupsResults.map(i => [`group.${i.item.id}`, i.score]))); |
| 297 | 323 | this.cacheScores(FILTER_TYPES.SEARCH, new Map(fuzzySearchTagsResult.map(i => [`tag.${i.item.id}`, i.score]))); |
| @@ -343,11 +369,14 @@ export class FilterHelper { | ||
| 343 | 369 | * @param {object} options - Optional call parameters |
| 344 | 370 | * @param {boolean} [options.clearScoreCache=true] - Whether the score cache should be cleared. |
| 345 | 371 | * @param {Object.<FilterType, any>} [options.tempOverrides={}] - Temporarily override specific filters for this filter application |
| 372 | + * @param {boolean} [options.clearFuzzySearchCaches=true] - Whether the fuzzy search caches should be cleared. | |
| 346 | 373 | * @returns {any[]} The filtered data. |
| 347 | 374 | */ |
| 348 | 375 | applyFilters(data, { clearScoreCache = true, tempOverrides = {}, clearFuzzySearchCaches = true } = {}) { |
| 349 | 376 | if (clearScoreCache) this.clearScoreCache(); |
| 350 | 377 | |
| 378 | + if (clearFuzzySearchCaches) this.clearFuzzySearchCaches(); | |
| 379 | + | |
| 351 | 380 | // Save original filter states |
| 352 | 381 | const originalStates = {}; |
| 353 | 382 | for (const key in tempOverrides) { |
| @@ -411,4 +440,20 @@ export class FilterHelper { | ||
| 411 | 440 | this.scoreCache = new Map(); |
| 412 | 441 | } |
| 413 | 442 | } |
| 443 | + | |
| 444 | + /** | |
| 445 | + * Clears fuzzy search caches | |
| 446 | + * @param {keyof typeof fuzzySearchCategories} [type] Optional cache type to clear. If not provided, clears all caches | |
| 447 | + */ | |
| 448 | + clearFuzzySearchCaches(type = null) { | |
| 449 | + if (type && this.fuzzySearchCaches[type]) { | |
| 450 | + this.fuzzySearchCaches[type].resultMap.clear(); | |
| 451 | + console.log(`Fuzzy search cache cleared for: ${type}`); | |
| 452 | + } else { | |
| 453 | + for (const cache of Object.values(this.fuzzySearchCaches)) { | |
| 454 | + cache.resultMap.clear(); | |
| 455 | + } | |
| 456 | + console.log('All fuzzy search caches cleared'); | |
| 457 | + } | |
| 458 | + } | |
| 414 | 459 | } |
| @@ -53,6 +53,7 @@ import { SlashCommandEnumValue, enumTypes } from './slash-commands/SlashCommandE | ||
| 53 | 53 | import { commonEnumProviders, enumIcons } from './slash-commands/SlashCommandCommonEnumsProvider.js'; |
| 54 | 54 | import { POPUP_TYPE, callGenericPopup } from './popup.js'; |
| 55 | 55 | import { loadSystemPrompts } from './sysprompt.js'; |
| 56 | +import { fuzzySearchCategories } from './filters.js'; | |
| 56 | 57 | |
| 57 | 58 | export { |
| 58 | 59 | loadPowerUserSettings, |
| @@ -328,22 +329,6 @@ const contextControls = [ | ||
| 328 | 329 | let browser_has_focus = true; |
| 329 | 330 | const debug_functions = []; |
| 330 | 331 | |
| 331 | -const fuzzySearchCaches = { | |
| 332 | - characters: { resultMap: new Map() }, | |
| 333 | - worldInfo: { resultMap: new Map() }, | |
| 334 | - personas: { resultMap: new Map() }, | |
| 335 | - tags: { resultMap: new Map() }, | |
| 336 | - groups: { resultMap: new Map() }, | |
| 337 | -}; | |
| 338 | - | |
| 339 | -const fuzzySearchCategories = { | |
| 340 | - characters: 'characters', | |
| 341 | - worldInfo: 'worldInfo', | |
| 342 | - personas: 'personas', | |
| 343 | - tags: 'tags', | |
| 344 | - groups: 'groups', | |
| 345 | -}; | |
| 346 | - | |
| 347 | 332 | const setHotswapsDebounced = debounce(favsToHotswap); |
| 348 | 333 | |
| 349 | 334 | function playMessageSound() { |
| @@ -1845,19 +1830,26 @@ async function loadContextSettings() { | ||
| 1845 | 1830 | }); |
| 1846 | 1831 | } |
| 1847 | 1832 | |
| 1833 | + | |
| 1848 | 1834 | /** |
| 1849 | 1835 | * Common function to perform fuzzy search with caching |
| 1850 | 1836 | * @param {string} type - Type of search from fuzzySearchCategories |
| 1851 | 1837 | * @param {any[]} data - Data array to search in |
| 1852 | 1838 | * @param {Array<{name: string, weight: number, getFn?: Function}>} keys - Fuse.js keys configuration |
| 1853 | 1839 | * @param {string} searchValue - The search term |
| 1840 | + * @param {Object.<string, { resultMap: Map<string, any> }>} fuzzySearchCaches - Fuzzy search caches | |
| 1854 | 1841 | * @returns {import('fuse.js').FuseResult<any>[]} Results as items with their score |
| 1855 | 1842 | */ |
| 1856 | 1843 | function performFuzzySearch(type, data, keys, searchValue, fuzzySearchCaches) { |
| 1844 | + let startTime = performance.now(); | |
| 1857 | 1845 | const cache = fuzzySearchCaches[type]; |
| 1858 | 1846 | |
| 1859 | 1847 | // Check cache for existing results |
| 1860 | 1848 | if (cache.resultMap.has(searchValue)) { |
| 1849 | + let endTime = performance.now(); | |
| 1850 | + if (endTime - startTime > 1.0) { | |
| 1851 | + console.log(`Fuzzy search for ${type} took ${endTime - startTime}ms (cached)`); | |
| 1852 | + } | |
| 1861 | 1853 | return cache.resultMap.get(searchValue); |
| 1862 | 1854 | } |
| 1863 | 1855 | |
| @@ -1872,26 +1864,20 @@ function performFuzzySearch(type, data, keys, searchValue) { | ||
| 1872 | 1864 | |
| 1873 | 1865 | const results = fuse.search(searchValue); |
| 1874 | 1866 | cache.resultMap.set(searchValue, results); |
| 1875 | - return results; | |
| 1867 | + let endTime = performance.now(); | |
| 1876 | -} | |
| 1868 | + if (endTime - startTime > 1.0) { | |
| 1877 | - | |
| 1869 | + console.log(`Fuzzy search for ${type} took ${endTime - startTime}ms`); | |
| 1878 | - | |
| 1879 | -/** | |
| 1880 | - * Clears all fuzzy search caches | |
| 1881 | - */ | |
| 1882 | -export function clearFuzzySearchCaches() { | |
| 1883 | - for (const cache of Object.values(fuzzySearchCaches)) { | |
| 1884 | - cache.resultMap.clear(); | |
| 1885 | 1870 | } |
| 1886 | - console.log('Fuzzy search caches cleared'); | |
| 1871 | + return results; | |
| 1887 | 1872 | } |
| 1888 | 1873 | |
| 1889 | 1874 | /** |
| 1890 | 1875 | * Fuzzy search characters by a search term |
| 1891 | 1876 | * @param {string} searchValue - The search term |
| 1877 | + * @param {Object.<string, { resultMap: Map<string, any> }>} fuzzySearchCaches - Fuzzy search caches | |
| 1892 | 1878 | * @returns {import('fuse.js').FuseResult<any>[]} Results as items with their score |
| 1893 | 1879 | */ |
| 1894 | 1880 | export function fuzzySearchCharacters(searchValue, fuzzySearchCaches) { |
| 1895 | 1881 | const keys = [ |
| 1896 | 1882 | { name: 'data.name', weight: 20 }, |
| 1897 | 1883 | { name: '#tags', weight: 10, getFn: (character) => getTagsList(character.avatar).map(x => x.name).join('||') }, |
| @@ -1906,16 +1892,17 @@ export function fuzzySearchCharacters(searchValue) { | ||
| 1906 | 1892 | { name: 'data.alternate_greetings', weight: 1 }, |
| 1907 | 1893 | ]; |
| 1908 | 1894 | |
| 1909 | 1895 | return performFuzzySearch(fuzzySearchCategories.characters, characters, keys, searchValue, fuzzySearchCaches); |
| 1910 | 1896 | } |
| 1911 | 1897 | |
| 1912 | 1898 | /** |
| 1913 | 1899 | * Fuzzy search world info entries by a search term |
| 1914 | 1900 | * @param {*[]} data - WI items data array |
| 1915 | 1901 | * @param {string} searchValue - The search term |
| 1902 | + * @param {Object.<string, { resultMap: Map<string, any> }>} fuzzySearchCaches - Fuzzy search caches | |
| 1916 | 1903 | * @returns {import('fuse.js').FuseResult<any>[]} Results as items with their score |
| 1917 | 1904 | */ |
| 1918 | 1905 | export function fuzzySearchWorldInfo(data, searchValue, fuzzySearchCaches) { |
| 1919 | 1906 | const keys = [ |
| 1920 | 1907 | { name: 'key', weight: 20 }, |
| 1921 | 1908 | { name: 'group', weight: 15 }, |
| @@ -1926,16 +1913,17 @@ export function fuzzySearchWorldInfo(data, searchValue) { | ||
| 1926 | 1913 | { name: 'automationId', weight: 1 }, |
| 1927 | 1914 | ]; |
| 1928 | 1915 | |
| 1929 | 1916 | return performFuzzySearch(fuzzySearchCategories.worldInfo, data, keys, searchValue, fuzzySearchCaches); |
| 1930 | 1917 | } |
| 1931 | 1918 | |
| 1932 | 1919 | /** |
| 1933 | 1920 | * Fuzzy search persona entries by a search term |
| 1934 | 1921 | * @param {*[]} data - persona data array |
| 1935 | 1922 | * @param {string} searchValue - The search term |
| 1923 | + * @param {Object.<string, { resultMap: Map<string, any> }>} fuzzySearchCaches - Fuzzy search caches | |
| 1936 | 1924 | * @returns {import('fuse.js').FuseResult<any>[]} Results as items with their score |
| 1937 | 1925 | */ |
| 1938 | 1926 | export function fuzzySearchPersonas(data, searchValue, fuzzySearchCaches) { |
| 1939 | 1927 | const mappedData = data.map(x => ({ |
| 1940 | 1928 | key: x, |
| 1941 | 1929 | name: power_user.personas[x] ?? '', |
| @@ -1947,28 +1935,30 @@ export function fuzzySearchPersonas(data, searchValue) { | ||
| 1947 | 1935 | { name: 'description', weight: 3 }, |
| 1948 | 1936 | ]; |
| 1949 | 1937 | |
| 1950 | 1938 | return performFuzzySearch(fuzzySearchCategories.personas, mappedData, keys, searchValue, fuzzySearchCaches); |
| 1951 | 1939 | } |
| 1952 | 1940 | |
| 1953 | 1941 | /** |
| 1954 | 1942 | * Fuzzy search tags by a search term |
| 1955 | 1943 | * @param {string} searchValue - The search term |
| 1944 | + * @param {Object.<string, { resultMap: Map<string, any> }>} fuzzySearchCaches - Fuzzy search caches | |
| 1956 | 1945 | * @returns {import('fuse.js').FuseResult<any>[]} Results as items with their score |
| 1957 | 1946 | */ |
| 1958 | 1947 | export function fuzzySearchTags(searchValue, fuzzySearchCaches) { |
| 1959 | 1948 | const keys = [ |
| 1960 | 1949 | { name: 'name', weight: 1 }, |
| 1961 | 1950 | ]; |
| 1962 | 1951 | |
| 1963 | 1952 | return performFuzzySearch(fuzzySearchCategories.tags, tags, keys, searchValue, fuzzySearchCaches); |
| 1964 | 1953 | } |
| 1965 | 1954 | |
| 1966 | 1955 | /** |
| 1967 | 1956 | * Fuzzy search groups by a search term |
| 1968 | 1957 | * @param {string} searchValue - The search term |
| 1958 | + * @param {Object.<string, { resultMap: Map<string, any> }>} fuzzySearchCaches - Fuzzy search caches | |
| 1969 | 1959 | * @returns {import('fuse.js').FuseResult<any>[]} Results as items with their score |
| 1970 | 1960 | */ |
| 1971 | 1961 | export function fuzzySearchGroups(searchValue, fuzzySearchCaches) { |
| 1972 | 1962 | const keys = [ |
| 1973 | 1963 | { name: 'name', weight: 20 }, |
| 1974 | 1964 | { name: 'members', weight: 15 }, |
| @@ -1976,7 +1966,7 @@ export function fuzzySearchGroups(searchValue) { | ||
| 1976 | 1966 | { name: 'id', weight: 1 }, |
| 1977 | 1967 | ]; |
| 1978 | 1968 | |
| 1979 | 1969 | return performFuzzySearch(fuzzySearchCategories.groups, groups, keys, searchValue, fuzzySearchCaches); |
| 1980 | 1970 | } |
| 1981 | 1971 | |
| 1982 | 1972 | /** |