1+ self . onmessage = function ( e ) {
2+ const { messageId, type, data } = e . data ;
3+
4+ const respond = ( type , data ) => {
5+ self . postMessage ( { messageId, type, data } ) ;
6+ } ;
7+
8+ const respondError = ( error ) => {
9+ self . postMessage ( { messageId, type : 'error' , error : error . message || String ( error ) } ) ;
10+ } ;
11+
12+ try {
13+ if ( type === 'tokenize' ) {
14+ const tokens = ( typeof data === 'string' ? data : '' )
15+ . toLowerCase ( )
16+ . match ( / \b [ a - z A - Z 0 - 9 _ - ] + \b / g) || [ ]
17+ . filter ( word => word . length > 2 ) ;
18+
19+ const uniqueTokens = Array . from ( new Set ( tokens ) ) ;
20+ respond ( 'tokens' , uniqueTokens ) ;
21+ }
22+
23+ if ( type === 'search' ) {
24+ const { documents, query, limit } = data ;
25+ const searchTerms = ( typeof query === 'string' ? query : '' )
26+ . toLowerCase ( )
27+ . match ( / \b [ a - z A - Z 0 - 9 _ - ] + \b / g) || [ ]
28+ . filter ( word => word . length > 2 ) ;
29+
30+ const docScores = new Map ( ) ;
31+
32+ // Pre-compute lower-case terms once
33+ const lowerSearchTerms = searchTerms . map ( term => term . toLowerCase ( ) ) ;
34+
35+ // Pre-compute lower-case strings for each document
36+ const processedDocs = documents . map ( ( doc , docId ) => ( {
37+ docId,
38+ title : doc . title ,
39+ content : doc . content ,
40+ lowerTitle : doc . title . toLowerCase ( ) ,
41+ lowerContent : doc . content . toLowerCase ( )
42+ } ) ) ;
43+
44+ lowerSearchTerms . forEach ( lowerTerm => {
45+ processedDocs . forEach ( ( { docId, title, content, lowerTitle, lowerContent } ) => {
46+ if ( lowerTitle . includes ( lowerTerm ) || lowerContent . includes ( lowerTerm ) ) {
47+ const score = lowerTitle === lowerTerm ? 30 :
48+ lowerTitle . includes ( lowerTerm ) ? 10 : 2 ;
49+ docScores . set ( docId , ( docScores . get ( docId ) || 0 ) + score ) ;
50+ }
51+ } ) ;
52+ } ) ;
53+
54+ const results = Array . from ( docScores . entries ( ) )
55+ . sort ( ( a , b ) => b [ 1 ] - a [ 1 ] )
56+ . slice ( 0 , limit )
57+ . map ( ( [ docId , score ] ) => ( { ...documents [ docId ] , score } ) ) ;
58+
59+ respond ( 'results' , results ) ;
60+ }
61+ } catch ( error ) {
62+ respondError ( error ) ;
63+ }
64+ } ;
0 commit comments