feat: performance and visual improvements

This commit is contained in:
SethBurkart123
2025-05-26 21:45:17 +10:00
parent 70a1ebf881
commit 34024d70c2
7 changed files with 17 additions and 52 deletions
@@ -18,11 +18,9 @@
const { const {
transparencyEffects, transparencyEffects,
showRecentFirst,
searchHotkey: initialSearchHotkey searchHotkey: initialSearchHotkey
} = $props<{ } = $props<{
transparencyEffects: boolean, transparencyEffects: boolean,
showRecentFirst: boolean,
searchHotkey: string searchHotkey: string
}>(); }>();
@@ -170,10 +168,7 @@
combinedResults = await doSearch( combinedResults = await doSearch(
term, term,
commandsFuse, commandsFuse,
dynamicContentFuse,
commandIdToItemMap, commandIdToItemMap,
dynamicIdToItemMap,
showRecentFirst
); );
} else { } else {
combinedResults = []; combinedResults = [];
@@ -19,7 +19,7 @@
> >
<div class="flex items-center w-full"> <div class="flex items-center w-full">
<div class="flex-none scale-90 w-8 h-8 text-xl font-IconFamily flex items-center justify-center text-white bg-gradient-to-br from-[#59aaf6] to-[#1b62c6] rounded-md">{item.metadata?.icon || '\uebe7'}</div> <div class="flex-none scale-90 w-8 h-8 text-xl font-IconFamily flex items-center justify-center text-white bg-gradient-to-br from-[#59aaf6] to-[#1b62c6] rounded-md">{item.metadata?.icon || '\uebe7'}</div>
<span class="ml-4 text-lg truncate"> <span class="ml-4 text-lg truncate {item.metadata?.closed ? 'line-through opacity-80' : ''}">
<HighlightedText text={item.text} term={searchTerm} matches={matches} /> <HighlightedText text={item.text} term={searchTerm} matches={matches} />
</span> </span>
<span class="flex-none ml-auto text-xs text-zinc-500 dark:text-zinc-400"> <span class="flex-none ml-auto text-xs text-zinc-500 dark:text-zinc-400">
@@ -80,4 +80,8 @@ export const actionMap: Record<string, ActionHandler<any>> = {
subjectcourse: ((item: IndexItem) => { subjectcourse: ((item: IndexItem) => {
window.location.href = `/#?page=/courses/${item.metadata.programme}:${item.metadata.subjectId}`; window.location.href = `/#?page=/courses/${item.metadata.programme}:${item.metadata.subjectId}`;
}) as ActionHandler<any>, }) as ActionHandler<any>,
forum: ((item: IndexItem) => {
window.location.href = `/#?page=/forums/${item.metadata.forumId}`;
}) as ActionHandler<any>,
}; };
@@ -51,6 +51,7 @@ export const forumsJob: Job = {
forumId: forum.id, forumId: forum.id,
owner: forum.owner, owner: forum.owner,
title: forum.title, title: forum.title,
closed: forum.closed,
}, },
actionId: "forum", actionId: "forum",
renderComponentId: "forum", renderComponentId: "forum",
@@ -60,9 +61,9 @@ export const forumsJob: Job = {
return items; return items;
}, },
/** Keep only forums from the last 2years. */ /** Keep only forums from the lastyear. */
purge: (items) => { purge: (items) => {
const twoYearsAgo = Date.now() - 2 * 365 * 24 * 60 * 60 * 1000; const oneYearAgo = Date.now() - 365 * 24 * 60 * 60 * 1000;
return items.filter((i) => i.dateAdded >= twoYearsAgo); return items.filter((i) => i.dateAdded >= oneYearAgo);
}, },
}; };
@@ -27,7 +27,7 @@ export const subjectsJob: Job = {
let score = 0; let score = 0;
if (item.metadata.isActive) { if (item.metadata.isActive) {
score += 1; // Boost for active subjects score += 0.01; // Boost for active subjects
} else { } else {
score -= 50; // Penalty for inactive subjects score -= 50; // Penalty for inactive subjects
} }
@@ -130,10 +130,7 @@ export function searchDynamicItems(
export async function performSearch( export async function performSearch(
query: string, query: string,
commandsFuse: Fuse<StaticCommandItem>, commandsFuse: Fuse<StaticCommandItem>,
dynamicContentFuse: Fuse<IndexItem>,
commandIdToItemMap: Map<string, StaticCommandItem>, commandIdToItemMap: Map<string, StaticCommandItem>,
dynamicIdToItemMap: Map<string, IndexItem>,
showRecentFirst: boolean,
): Promise<CombinedResult[]> { ): Promise<CombinedResult[]> {
// Get all results first // Get all results first
const commandResults = searchCommands( const commandResults = searchCommands(
@@ -141,18 +138,11 @@ export async function performSearch(
query, query,
commandIdToItemMap, commandIdToItemMap,
); );
const dynamicResults = searchDynamicItems(
dynamicContentFuse,
query,
dynamicIdToItemMap,
10,
showRecentFirst,
);
// Get vector results in parallel // Get vector results in parallel
let vectorResults: VectorSearchResult[] = []; let vectorResults: VectorSearchResult[] = [];
try { try {
vectorResults = await searchVectors(query, 10); vectorResults = await searchVectors(query);
} catch (e) {} } catch (e) {}
// Create a map to store our final results, using ID as key to avoid duplicates // Create a map to store our final results, using ID as key to avoid duplicates
@@ -164,35 +154,6 @@ export async function performSearch(
// Process dynamic results and vector results together // Process dynamic results and vector results together
const seenIds = new Set<string>(); const seenIds = new Set<string>();
// Add dynamic results first
dynamicResults.forEach((r) => {
seenIds.add(r.id);
if (r.type === "dynamic") {
const dynamicItem = r.item as IndexItem;
const job = jobs[dynamicItem.category];
if (job && typeof job.boostCriteria === 'function') {
const boost = job.boostCriteria(dynamicItem, query);
if (boost) {
r.score += boost; // Add the boost to the score
}
}
}
const vectorMatch = vectorResults.find((v) => v.object.id === r.id);
if (vectorMatch) {
// If we found it in both searches, combine the scores
resultMap.set(r.id, {
...r,
score: r.score + vectorMatch.similarity * 0.6, // Boost exact matches
});
} else {
// If only in Fuse results, keep as is
resultMap.set(r.id, r);
}
});
// Now add any vector results we haven't seen yet
vectorResults.forEach((v) => { vectorResults.forEach((v) => {
const id = v.object.id; const id = v.object.id;
@@ -20,7 +20,7 @@ export interface VectorSearchResult extends SearchResult {
export async function searchVectors( export async function searchVectors(
query: string, query: string,
topK: number = 10, topK: number = 20,
): Promise<VectorSearchResult[]> { ): Promise<VectorSearchResult[]> {
if (!vectorIndex) await initVectorSearch(); if (!vectorIndex) await initVectorSearch();
@@ -32,7 +32,11 @@ export async function searchVectors(
dedupeEntries: true, dedupeEntries: true,
}); });
return results as VectorSearchResult[]; // filter results with a similarity below 0.81
const filteredResults = results.filter((r) => r.similarity > 0.81);
console.log("Vector search results", filteredResults);
return filteredResults as VectorSearchResult[];
} }
export async function refreshVectorCache() { export async function refreshVectorCache() {