Handle stale cache

2661881bc4c95f752786b35daa06af3cffe05e15

Joe <joenunezb@gmail.com>

1 files changed, +165 -63Ignore whitespace
public/scripts/power-user.js+165 -63
@@ -330,12 +330,6 @@ const debug_functions = [];
330330
331331const setHotswapsDebounced = debounce(favsToHotswap);
332332
333-const fuzzySearchCharactersCache = new Map();
334-const fuzzySearchWorldInfoCache = new Map();
335-const fuzzySearchPersonasCache = new Map();
336-const fuzzySearchTagsCache = new Map();
337-const fuzzySearchGroupsCache = new Map();
338-
339333function playMessageSound() {
340334 if (!power_user.play_message_sound) {
341335 return;
@@ -1830,32 +1824,70 @@ async function loadContextSettings() {
18301824 });
18311825}
18321826
1827+// Create separate caches for each type of fuzzy search
1828+const fuzzySearchCaches = {
1829+ characters: { keyHash: null, resultMap: new Map() },
1830+ worldInfo: { keyHash: null, resultMap: new Map() },
1831+ personas: { keyHash: null, resultMap: new Map() },
1832+ tags: { keyHash: null, resultMap: new Map() },
1833+ groups: { keyHash: null, resultMap: new Map() },
1834+};
1835+
1836+/**
1837+ * Generates a hash of the Fuse configuration keys
1838+ * @param {Array<{name: string, weight: number, getFn?: Function}>} keys
1839+ * @returns {number} Hash of the keys configuration
1840+ */
1841+function hashFuseKeys(keys) {
1842+ // Convert keys to a stable string representation
1843+ const keyString = keys.map(k => {
1844+ const getFnString = k.getFn ? k.getFn.toString() : '';
1845+ return `${k.name}:${k.weight}:${getFnString}`;
1846+ }).join('|');
1847+
1848+ return getStringHash(keyString);
1849+}
1850+
18331851/**
18341852 * Fuzzy search characters by a search term with caching
18351853 * @param {string} searchValue - The search term
18361854 * @returns {import('fuse.js').FuseResult<any>[]} Results as items with their score
18371855 */
18381856export function fuzzySearchCharacters(searchValue) {
1857+ const fuseKeys = [
1858+ { name: 'data.name', weight: 20 },
1859+ { name: '#tags', weight: 10, getFn: (character) => getTagsList(character.avatar).map(x => x.name).join('||') },
1860+ { name: 'data.description', weight: 3 },
1861+ { name: 'data.mes_example', weight: 3 },
1862+ { name: 'data.scenario', weight: 2 },
1863+ { name: 'data.personality', weight: 2 },
1864+ { name: 'data.first_mes', weight: 2 },
1865+ { name: 'data.creator_notes', weight: 2 },
1866+ { name: 'data.creator', weight: 1 },
1867+ { name: 'data.tags', weight: 1 },
1868+ { name: 'data.alternate_greetings', weight: 1 },
1869+ ];
1870+
1871+ // Generate hash of current keys configuration
1872+ const currentKeyHash = hashFuseKeys(fuseKeys);
1873+ const cache = fuzzySearchCaches.characters;
18391874
1840- if (fuzzySearchCharactersCache.has(searchValue)) {
1875+ // Check if we have a cached result for this search value
1841- return fuzzySearchCharactersCache.get(searchValue);
1876+ if (cache.keyHash === currentKeyHash && cache.resultMap.has(searchValue)) {
1877+ console.debug('Using cached fuzzy search results for ' + searchValue);
1878+ return cache.resultMap.get(searchValue);
18421879 }
18431880
1844- // @ts-ignore
1881+ // If key configuration changed, clear the cache
1882+ if (cache.keyHash !== currentKeyHash) {
1883+ console.debug('Fuse keys changed, clearing cache');
1884+ cache.keyHash = currentKeyHash;
1885+ cache.resultMap.clear();
1886+ }
1887+
1888+ // Create new Fuse instance and perform search
18451889 const fuse = new Fuse(characters, {
18461890 keys: [fuseKeys,
1847- { name: 'data.name', weight: 20 },
1848- { name: '#tags', weight: 10, getFn: (character) => getTagsList(character.avatar).map(x => x.name).join('||') },
1849- { name: 'data.description', weight: 3 },
1850- { name: 'data.mes_example', weight: 3 },
1851- { name: 'data.scenario', weight: 2 },
1852- { name: 'data.personality', weight: 2 },
1853- { name: 'data.first_mes', weight: 2 },
1854- { name: 'data.creator_notes', weight: 2 },
1855- { name: 'data.creator', weight: 1 },
1856- { name: 'data.tags', weight: 1 },
1857- { name: 'data.alternate_greetings', weight: 1 },
1858- ],
18591891 includeScore: true,
18601892 ignoreLocation: true,
18611893 useExtendedSearch: true,
@@ -1863,8 +1895,11 @@ export function fuzzySearchCharacters(searchValue) {
18631895 });
18641896
18651897 const results = fuse.search(searchValue);
1898+
1899+ // Cache the results
1900+ cache.resultMap.set(searchValue, results);
1901+
18661902 console.debug('Characters fuzzy search results for ' + searchValue, results);
1867- fuzzySearchCharactersCache.set(searchValue, results);
18681903 return results;
18691904}
18701905
@@ -1875,21 +1910,34 @@ export function fuzzySearchCharacters(searchValue) {
18751910 * @returns {import('fuse.js').FuseResult<any>[]} Results as items with their score
18761911 */
18771912export function fuzzySearchWorldInfo(data, searchValue) {
1878- if (fuzzySearchWorldInfoCache.has(searchValue)) {
1913+ const fuseKeys = [
1879- return fuzzySearchWorldInfoCache.get(searchValue);
1914+ { name: 'key', weight: 20 },
1915+ { name: 'group', weight: 15 },
1916+ { name: 'comment', weight: 10 },
1917+ { name: 'keysecondary', weight: 10 },
1918+ { name: 'content', weight: 3 },
1919+ { name: 'uid', weight: 1 },
1920+ { name: 'automationId', weight: 1 },
1921+ ];
1922+
1923+ const currentKeyHash = hashFuseKeys(fuseKeys);
1924+ const cache = fuzzySearchCaches.worldInfo;
1925+
1926+ // Check cache for existing results
1927+ if (cache.keyHash === currentKeyHash && cache.resultMap.has(searchValue)) {
1928+ console.debug('Using cached WI fuzzy search results for ' + searchValue);
1929+ return cache.resultMap.get(searchValue);
1930+ }
1931+
1932+ // Clear cache if keys changed
1933+ if (cache.keyHash !== currentKeyHash) {
1934+ console.debug('WI Fuse keys changed, clearing cache');
1935+ cache.keyHash = currentKeyHash;
1936+ cache.resultMap.clear();
18801937 }
18811938
1882- // @ts-ignore
18831939 const fuse = new Fuse(data, {
18841940 keys: [fuseKeys,
1885- { name: 'key', weight: 20 },
1886- { name: 'group', weight: 15 },
1887- { name: 'comment', weight: 10 },
1888- { name: 'keysecondary', weight: 10 },
1889- { name: 'content', weight: 3 },
1890- { name: 'uid', weight: 1 },
1891- { name: 'automationId', weight: 1 },
1892- ],
18931941 includeScore: true,
18941942 ignoreLocation: true,
18951943 useExtendedSearch: true,
@@ -1897,8 +1945,9 @@ export function fuzzySearchWorldInfo(data, searchValue) {
18971945 });
18981946
18991947 const results = fuse.search(searchValue);
1948+ cache.resultMap.set(searchValue, results);
1949+
19001950 console.debug('World Info fuzzy search results for ' + searchValue, results);
1901- fuzzySearchWorldInfoCache.set(searchValue, results);
19021951 return results;
19031952}
19041953
@@ -1909,17 +1958,31 @@ export function fuzzySearchWorldInfo(data, searchValue) {
19091958 * @returns {import('fuse.js').FuseResult<any>[]} Results as items with their score
19101959 */
19111960export function fuzzySearchPersonas(data, searchValue) {
1912- if (fuzzySearchPersonasCache.has(searchValue)) {
1961+ data = data.map(x => ({ key: x, name: power_user.personas[x] ?? '', description: power_user.persona_descriptions[x]?.description ?? '' }));
1913- return fuzzySearchPersonasCache.get(searchValue);
1962+
1963+ const fuseKeys = [
1964+ { name: 'name', weight: 20 },
1965+ { name: 'description', weight: 3 },
1966+ ];
1967+
1968+ const currentKeyHash = hashFuseKeys(fuseKeys);
1969+ const cache = fuzzySearchCaches.personas;
1970+
1971+ // Check cache for existing results
1972+ if (cache.keyHash === currentKeyHash && cache.resultMap.has(searchValue)) {
1973+ console.debug('Using cached personas fuzzy search results for ' + searchValue);
1974+ return cache.resultMap.get(searchValue);
1975+ }
1976+
1977+ // Clear cache if keys changed
1978+ if (cache.keyHash !== currentKeyHash) {
1979+ console.debug('Personas Fuse keys changed, clearing cache');
1980+ cache.keyHash = currentKeyHash;
1981+ cache.resultMap.clear();
19141982 }
19151983
1916- data = data.map(x => ({ key: x, name: power_user.personas[x] ?? '', description: power_user.persona_descriptions[x]?.description ?? '' }));
1917- // @ts-ignore
19181984 const fuse = new Fuse(data, {
19191985 keys: [fuseKeys,
1920- { name: 'name', weight: 20 },
1921- { name: 'description', weight: 3 },
1922- ],
19231986 includeScore: true,
19241987 ignoreLocation: true,
19251988 useExtendedSearch: true,
@@ -1927,8 +1990,9 @@ export function fuzzySearchPersonas(data, searchValue) {
19271990 });
19281991
19291992 const results = fuse.search(searchValue);
1993+ cache.resultMap.set(searchValue, results);
1994+
19301995 console.debug('Personas fuzzy search results for ' + searchValue, results);
1931- fuzzySearchPersonasCache.set(searchValue, results);
19321996 return results;
19331997}
19341998
@@ -1938,15 +2002,28 @@ export function fuzzySearchPersonas(data, searchValue) {
19382002 * @returns {import('fuse.js').FuseResult<any>[]} Results as items with their score
19392003 */
19402004export function fuzzySearchTags(searchValue) {
1941- if (fuzzySearchTagsCache.has(searchValue)) {
2005+ const fuseKeys = [
1942- return fuzzySearchTagsCache.get(searchValue);
2006+ { name: 'name', weight: 1 },
2007+ ];
2008+
2009+ const currentKeyHash = hashFuseKeys(fuseKeys);
2010+ const cache = fuzzySearchCaches.tags;
2011+
2012+ // Check cache for existing results
2013+ if (cache.keyHash === currentKeyHash && cache.resultMap.has(searchValue)) {
2014+ console.debug('Using cached tags fuzzy search results for ' + searchValue);
2015+ return cache.resultMap.get(searchValue);
2016+ }
2017+
2018+ // Clear cache if keys changed
2019+ if (cache.keyHash !== currentKeyHash) {
2020+ console.debug('Tags Fuse keys changed, clearing cache');
2021+ cache.keyHash = currentKeyHash;
2022+ cache.resultMap.clear();
19432023 }
19442024
1945- // @ts-ignore
19462025 const fuse = new Fuse(tags, {
19472026 keys: [fuseKeys,
1948- { name: 'name', weight: 1 },
1949- ],
19502027 includeScore: true,
19512028 ignoreLocation: true,
19522029 useExtendedSearch: true,
@@ -1954,8 +2031,9 @@ export function fuzzySearchTags(searchValue) {
19542031 });
19552032
19562033 const results = fuse.search(searchValue);
2034+ cache.resultMap.set(searchValue, results);
2035+
19572036 console.debug('Tags fuzzy search results for ' + searchValue, results);
1958- fuzzySearchTagsCache.set(searchValue, results);
19592037 return results;
19602038}
19612039
@@ -1965,18 +2043,31 @@ export function fuzzySearchTags(searchValue) {
19652043 * @returns {import('fuse.js').FuseResult<any>[]} Results as items with their score
19662044 */
19672045export function fuzzySearchGroups(searchValue) {
1968- if (fuzzySearchGroupsCache.has(searchValue)) {
2046+ const fuseKeys = [
1969- return fuzzySearchGroupsCache.get(searchValue);
2047+ { name: 'name', weight: 20 },
2048+ { name: 'members', weight: 15 },
2049+ { name: '#tags', weight: 10, getFn: (group) => getTagsList(group.id).map(x => x.name).join('||') },
2050+ { name: 'id', weight: 1 },
2051+ ];
2052+
2053+ const currentKeyHash = hashFuseKeys(fuseKeys);
2054+ const cache = fuzzySearchCaches.groups;
2055+
2056+ // Check cache for existing results
2057+ if (cache.keyHash === currentKeyHash && cache.resultMap.has(searchValue)) {
2058+ console.debug('Using cached groups fuzzy search results for ' + searchValue);
2059+ return cache.resultMap.get(searchValue);
2060+ }
2061+
2062+ // Clear cache if keys changed
2063+ if (cache.keyHash !== currentKeyHash) {
2064+ console.debug('Groups Fuse keys changed, clearing cache');
2065+ cache.keyHash = currentKeyHash;
2066+ cache.resultMap.clear();
19702067 }
19712068
1972- // @ts-ignore
19732069 const fuse = new Fuse(groups, {
19742070 keys: [fuseKeys,
1975- { name: 'name', weight: 20 },
1976- { name: 'members', weight: 15 },
1977- { name: '#tags', weight: 10, getFn: (group) => getTagsList(group.id).map(x => x.name).join('||') },
1978- { name: 'id', weight: 1 },
1979- ],
19802071 includeScore: true,
19812072 ignoreLocation: true,
19822073 useExtendedSearch: true,
@@ -1984,12 +2075,23 @@ export function fuzzySearchGroups(searchValue) {
19842075 });
19852076
19862077 const results = fuse.search(searchValue);
2078+ cache.resultMap.set(searchValue, results);
2079+
19872080 console.debug('Groups fuzzy search results for ' + searchValue, results);
1988- fuzzySearchGroupsCache.set(searchValue, results);
19892081 return results;
19902082}
19912083
19922084/**
2085+ * Clears all fuzzy search caches
2086+ */
2087+export function clearFuzzySearchCaches() {
2088+ for (const cache of Object.values(fuzzySearchCaches)) {
2089+ cache.keyHash = null;
2090+ cache.resultMap.clear();
2091+ }
2092+}
2093+
2094+/**
19932095 * Renders a story string template with the given parameters.
19942096 * @param {object} params Template parameters.
19952097 * @returns {string} The rendered story string.