create search web worker

This commit is contained in:
Youwen Wu 2024-02-12 21:21:55 -08:00
parent a074952678
commit 0c4e56ab74
4 changed files with 72 additions and 31 deletions

View file

@ -2,6 +2,7 @@ import Link from 'next/link'
import { Fragment } from 'react' import { Fragment } from 'react'
import { affiliations, nationalities, authors } from '../../db/data' import { affiliations, nationalities, authors } from '../../db/data'
import { Zilla_Slab } from 'next/font/google' import { Zilla_Slab } from 'next/font/google'
import { notFound } from 'next/navigation'
const zillaSlab = Zilla_Slab({ subsets: ['latin'], weight: ['500'] }) const zillaSlab = Zilla_Slab({ subsets: ['latin'], weight: ['500'] })
@ -9,6 +10,10 @@ export default function AuthorDisplay({
author, author,
}: Readonly<{ author: string }>) { }: Readonly<{ author: string }>) {
const data = authors[author] const data = authors[author]
if (!data) {
notFound()
}
const { name, affiliation, image, nationality, formerAffiliations } = data const { name, affiliation, image, nationality, formerAffiliations } = data
const MainPosition = () => { const MainPosition = () => {

View file

@ -0,0 +1,2 @@
These worker files should not be touched unless you know what you are doing! They're simply utilities to be imported
by the loaders library to launch asynchronous web worker threads.

View file

@ -0,0 +1,34 @@
import { documents } from '@/app/db/data'
import MiniSearch from 'minisearch'
import { CustomSearchResult } from './searchDocs'
const docs = Object.entries(documents).map(([key, value]) => ({
id: key,
keywords: value.manifest.keywords.join(' '),
abstract: value.abstract,
topics: value.manifest.topics.join(' '),
authors: value.manifest.authors.join(' '),
title: value.manifest.title,
manifest: value.manifest,
type: value.manifest.type,
}))
const miniSearch = new MiniSearch({
fields: ['abstract', 'keywords', 'topics', 'authors', 'title', 'type'],
storeFields: ['key', 'abstract', 'manifest'],
searchOptions: {
boost: {
title: 2,
keywords: 2,
topics: 1,
authors: 2,
},
fuzzy: 0.2,
prefix: true,
},
})
miniSearch.addAll(docs)
onmessage = (e: MessageEvent<string>) => {
postMessage(miniSearch.search(e.data) as CustomSearchResult[])
}

View file

@ -1,32 +1,5 @@
import MiniSearch, { SearchResult } from 'minisearch' import { SearchResult } from 'minisearch'
import { documents, DocumentManifest } from '../db/data' import { DocumentManifest } from '../db/data'
const docs = Object.entries(documents).map(([key, value]) => ({
id: key,
keywords: value.manifest.keywords.join(' '),
abstract: value.abstract,
topics: value.manifest.topics.join(' '),
authors: value.manifest.authors.join(' '),
title: value.manifest.title,
manifest: value.manifest,
type: value.manifest.type,
}))
const miniSearch = new MiniSearch({
fields: ['abstract', 'keywords', 'topics', 'authors', 'title', 'type'],
storeFields: ['key', 'abstract', 'manifest'],
searchOptions: {
boost: {
title: 2,
keywords: 2,
topics: 1,
authors: 2,
},
fuzzy: 0.2,
prefix: true,
},
})
miniSearch.addAll(docs)
export interface CustomSearchResult extends SearchResult { export interface CustomSearchResult extends SearchResult {
manifest: DocumentManifest manifest: DocumentManifest
@ -36,6 +9,33 @@ export interface CustomSearchResult extends SearchResult {
export default function searchDocs( export default function searchDocs(
query: string, query: string,
limit = 10 limit = 10
): CustomSearchResult[] { ): Promise<CustomSearchResult[]> {
return miniSearch.search(query).slice(0, limit) as CustomSearchResult[] return new Promise((resolve, reject) => {
if (typeof Worker !== 'undefined') {
const worker = new Worker(
new URL('./search.worker.ts', import.meta.url),
{ type: 'module' }
)
worker.onmessage = (e: MessageEvent<CustomSearchResult[]>) => {
const data = e.data
resolve(data.slice(0, limit))
worker.terminate()
}
worker.onerror = (error) => {
reject(error)
worker.terminate()
}
worker.postMessage(query)
} else {
reject(
new Error(
`Web Workers are not supported in this environment. Please avoid using a prehistoric browser.
If nothing else seems wrong, this error message is probably showing up due to ghosts in your browser.`
)
)
}
})
} }