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 {
transparencyEffects,
showRecentFirst,
searchHotkey: initialSearchHotkey
} = $props<{
transparencyEffects: boolean,
showRecentFirst: boolean,
searchHotkey: string
}>();
@@ -170,10 +168,7 @@
combinedResults = await doSearch(
term,
commandsFuse,
dynamicContentFuse,
commandIdToItemMap,
dynamicIdToItemMap,
showRecentFirst
);
} else {
combinedResults = [];
@@ -19,7 +19,7 @@
>
<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>
<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} />
</span>
<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) => {
window.location.href = `/#?page=/courses/${item.metadata.programme}:${item.metadata.subjectId}`;
}) 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,
owner: forum.owner,
title: forum.title,
closed: forum.closed,
},
actionId: "forum",
renderComponentId: "forum",
@@ -60,9 +61,9 @@ export const forumsJob: Job = {
return items;
},
/** Keep only forums from the last 2years. */
/** Keep only forums from the lastyear. */
purge: (items) => {
const twoYearsAgo = Date.now() - 2 * 365 * 24 * 60 * 60 * 1000;
return items.filter((i) => i.dateAdded >= twoYearsAgo);
const oneYearAgo = Date.now() - 365 * 24 * 60 * 60 * 1000;
return items.filter((i) => i.dateAdded >= oneYearAgo);
},
};
@@ -27,7 +27,7 @@ export const subjectsJob: Job = {
let score = 0;
if (item.metadata.isActive) {
score += 1; // Boost for active subjects
score += 0.01; // Boost for active subjects
} else {
score -= 50; // Penalty for inactive subjects
}
@@ -130,10 +130,7 @@ export function searchDynamicItems(
export async function performSearch(
query: string,
commandsFuse: Fuse<StaticCommandItem>,
dynamicContentFuse: Fuse<IndexItem>,
commandIdToItemMap: Map<string, StaticCommandItem>,
dynamicIdToItemMap: Map<string, IndexItem>,
showRecentFirst: boolean,
): Promise<CombinedResult[]> {
// Get all results first
const commandResults = searchCommands(
@@ -141,18 +138,11 @@ export async function performSearch(
query,
commandIdToItemMap,
);
const dynamicResults = searchDynamicItems(
dynamicContentFuse,
query,
dynamicIdToItemMap,
10,
showRecentFirst,
);
// Get vector results in parallel
let vectorResults: VectorSearchResult[] = [];
try {
vectorResults = await searchVectors(query, 10);
vectorResults = await searchVectors(query);
} catch (e) {}
// 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
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) => {
const id = v.object.id;
@@ -20,7 +20,7 @@ export interface VectorSearchResult extends SearchResult {
export async function searchVectors(
query: string,
topK: number = 10,
topK: number = 20,
): Promise<VectorSearchResult[]> {
if (!vectorIndex) await initVectorSearch();
@@ -32,7 +32,11 @@ export async function searchVectors(
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() {