create search web worker
This commit is contained in:
parent
a074952678
commit
0c4e56ab74
4 changed files with 72 additions and 31 deletions
|
@ -2,6 +2,7 @@ import Link from 'next/link'
|
|||
import { Fragment } from 'react'
|
||||
import { affiliations, nationalities, authors } from '../../db/data'
|
||||
import { Zilla_Slab } from 'next/font/google'
|
||||
import { notFound } from 'next/navigation'
|
||||
|
||||
const zillaSlab = Zilla_Slab({ subsets: ['latin'], weight: ['500'] })
|
||||
|
||||
|
@ -9,6 +10,10 @@ export default function AuthorDisplay({
|
|||
author,
|
||||
}: Readonly<{ author: string }>) {
|
||||
const data = authors[author]
|
||||
if (!data) {
|
||||
notFound()
|
||||
}
|
||||
|
||||
const { name, affiliation, image, nationality, formerAffiliations } = data
|
||||
|
||||
const MainPosition = () => {
|
||||
|
|
2
src/app/db/workers/README
Normal file
2
src/app/db/workers/README
Normal 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.
|
34
src/app/utils/search.worker.ts
Normal file
34
src/app/utils/search.worker.ts
Normal 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[])
|
||||
}
|
|
@ -1,32 +1,5 @@
|
|||
import MiniSearch, { SearchResult } from 'minisearch'
|
||||
import { documents, 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)
|
||||
import { SearchResult } from 'minisearch'
|
||||
import { DocumentManifest } from '../db/data'
|
||||
|
||||
export interface CustomSearchResult extends SearchResult {
|
||||
manifest: DocumentManifest
|
||||
|
@ -36,6 +9,33 @@ export interface CustomSearchResult extends SearchResult {
|
|||
export default function searchDocs(
|
||||
query: string,
|
||||
limit = 10
|
||||
): CustomSearchResult[] {
|
||||
return miniSearch.search(query).slice(0, limit) as CustomSearchResult[]
|
||||
): Promise<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.`
|
||||
)
|
||||
)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue