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 { 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 = () => {
|
||||||
|
|
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 { 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.`
|
||||||
|
)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue