nvf/docs-preview-1284/assets/search-worker.js
2025-12-13 13:11:31 +00:00

64 lines
No EOL
2 KiB
JavaScript

self.onmessage = function(e) {
const { messageId, type, data } = e.data;
const respond = (type, data) => {
self.postMessage({ messageId, type, data });
};
const respondError = (error) => {
self.postMessage({ messageId, type: 'error', error: error.message || String(error) });
};
try {
if (type === 'tokenize') {
const tokens = (typeof data === 'string' ? data : '')
.toLowerCase()
.match(/\b[a-zA-Z0-9_-]+\b/g) || []
.filter(word => word.length > 2);
const uniqueTokens = Array.from(new Set(tokens));
respond('tokens', uniqueTokens);
}
if (type === 'search') {
const { documents, query, limit } = data;
const searchTerms = (typeof query === 'string' ? query : '')
.toLowerCase()
.match(/\b[a-zA-Z0-9_-]+\b/g) || []
.filter(word => word.length > 2);
const docScores = new Map();
// Pre-compute lower-case terms once
const lowerSearchTerms = searchTerms.map(term => term.toLowerCase());
// Pre-compute lower-case strings for each document
const processedDocs = documents.map((doc, docId) => ({
docId,
title: doc.title,
content: doc.content,
lowerTitle: doc.title.toLowerCase(),
lowerContent: doc.content.toLowerCase()
}));
lowerSearchTerms.forEach(lowerTerm => {
processedDocs.forEach(({ docId, title, content, lowerTitle, lowerContent }) => {
if (lowerTitle.includes(lowerTerm) || lowerContent.includes(lowerTerm)) {
const score = lowerTitle === lowerTerm ? 30 :
lowerTitle.includes(lowerTerm) ? 10 : 2;
docScores.set(docId, (docScores.get(docId) || 0) + score);
}
});
});
const results = Array.from(docScores.entries())
.sort((a, b) => b[1] - a[1])
.slice(0, limit)
.map(([docId, score]) => ({ ...documents[docId], score }));
respond('results', results);
}
} catch (error) {
respondError(error);
}
};