local search: avoid indexing 2 times when bundling for server and client

pull/3386/head
Yuxuan Zhang 2 years ago
parent e98da5ba9c
commit 58627479c5
No known key found for this signature in database
GPG Key ID: 6910B04F3351EF7D

@ -5,7 +5,10 @@ import pMap from 'p-map'
import path from 'path' import path from 'path'
import type { Plugin, ViteDevServer } from 'vite' import type { Plugin, ViteDevServer } from 'vite'
import type { SiteConfig } from '../config' import type { SiteConfig } from '../config'
import { createMarkdownRenderer } from '../markdown/markdown' import {
createMarkdownRenderer,
type MarkdownRenderer
} from '../markdown/markdown'
import { import {
resolveSiteDataByRoute, resolveSiteDataByRoute,
slash, slash,
@ -29,6 +32,26 @@ interface IndexObject {
titles: string[] titles: string[]
} }
let md: MarkdownRenderer
let flagAllIndexed = false
const taskByLocale = new Map<string, Promise<void>>()
const filesByLocale = new Map<string, Set<string>>()
const indexByLocale = new Map<string, MiniSearch<IndexObject>>()
function getIndexByLocale(locale: string, options?: any) {
let index = indexByLocale.get(locale)
if (!index) {
index = new MiniSearch<IndexObject>({
fields: ['title', 'titles', 'text'],
storeFields: ['title', 'titles'],
...options
})
indexByLocale.set(locale, index)
}
return index
}
export async function localSearchPlugin( export async function localSearchPlugin(
siteConfig: SiteConfig<DefaultTheme.Config> siteConfig: SiteConfig<DefaultTheme.Config>
): Promise<Plugin> { ): Promise<Plugin> {
@ -48,7 +71,7 @@ export async function localSearchPlugin(
} }
} }
const md = await createMarkdownRenderer( md ??= await createMarkdownRenderer(
siteConfig.srcDir, siteConfig.srcDir,
siteConfig.markdown, siteConfig.markdown,
siteConfig.site.base, siteConfig.site.base,
@ -71,21 +94,6 @@ export async function localSearchPlugin(
} }
} }
const indexByLocales = new Map<string, MiniSearch<IndexObject>>()
function getIndexByLocale(locale: string) {
let index = indexByLocales.get(locale)
if (!index) {
index = new MiniSearch<IndexObject>({
fields: ['title', 'titles', 'text'],
storeFields: ['title', 'titles'],
...options.miniSearch?.options
})
indexByLocales.set(locale, index)
}
return index
}
function getLocaleForPath(file: string) { function getLocaleForPath(file: string) {
const relativePath = slash(path.relative(siteConfig.srcDir, file)) const relativePath = slash(path.relative(siteConfig.srcDir, file))
const siteData = resolveSiteDataByRoute(siteConfig.site, relativePath) const siteData = resolveSiteDataByRoute(siteConfig.site, relativePath)
@ -125,21 +133,10 @@ export async function localSearchPlugin(
return id return id
} }
function scanForLocales() { async function indexFile(file: string, parallel: boolean = false) {
for (const page of siteConfig.pages) {
const file = path.join(siteConfig.srcDir, page)
const locale = getLocaleForPath(file)
// dry-fetch the index for this locale
getIndexByLocale(locale)
}
}
async function indexFile(page: string, parallel: boolean = false) {
const file = path.join(siteConfig.srcDir, page)
// get file metadata
const fileId = getDocId(file) const fileId = getDocId(file)
const locale = getLocaleForPath(file) const locale = getLocaleForPath(file)
const index = getIndexByLocale(locale) const index = getIndexByLocale(locale, options.miniSearch?.options)
// retrieve file and split into "sections" // retrieve file and split into "sections"
const html = await render(file) const html = await render(file)
const sections = const sections =
@ -163,29 +160,28 @@ export async function localSearchPlugin(
} }
} }
async function indexAll() { function indexAll() {
const concurrency = siteConfig.concurrency if (flagAllIndexed) return
let numIndexed = 0 flagAllIndexed = true
const updateProgress = () =>
updateCurrentTask(
++numIndexed,
siteConfig.pages.length,
'indexing local search'
)
const parallel = shouldUseParallel(siteConfig, 'local-search')
await pMap( for (const page of siteConfig.pages) {
siteConfig.pages, const file = path.join(siteConfig.srcDir, page)
(page) => indexFile(page, parallel).then(updateProgress), const locale = getLocaleForPath(file)
{ concurrency } if (!filesByLocale.has(locale)) filesByLocale.set(locale, new Set())
) filesByLocale.get(locale)!.add(file)
}
}
updateCurrentTask() async function indexLocale(locale: string) {
let numIndexed = 0
const update = () =>
updateCurrentTask(++numIndexed, files.length, `🔍️ indexing ${locale}`)
const files = [...filesByLocale.get(locale)!]
const task = (f: string) => indexFile(f, parallel).then(update)
await pMap(files, task, { concurrency: siteConfig.concurrency })
} }
let indexAllPromise: Promise<void> | undefined const parallel = shouldUseParallel(siteConfig, 'local-search')
return { return {
name: 'vitepress:local-search', name: 'vitepress:local-search',
@ -213,28 +209,28 @@ export async function localSearchPlugin(
async load(id) { async load(id) {
if (id === LOCAL_SEARCH_INDEX_REQUEST_PATH) { if (id === LOCAL_SEARCH_INDEX_REQUEST_PATH) {
scanForLocales() indexAll()
let records: string[] = [] let records: string[] = []
for (const [locale] of indexByLocales) { for (const [locale] of filesByLocale) {
records.push( records.push(
`${JSON.stringify( `${JSON.stringify(
locale locale
)}: () => import('${LOCAL_SEARCH_INDEX_ID}-${locale}')` )}: () => import('${LOCAL_SEARCH_INDEX_ID}:${locale}')`
) )
} }
return `export default {${records.join(',')}}` return `export default {${records.join(',')}}`
} else if (id.startsWith(LOCAL_SEARCH_INDEX_REQUEST_PATH)) { } else if (id.startsWith(LOCAL_SEARCH_INDEX_REQUEST_PATH)) {
const locale = id.slice(LOCAL_SEARCH_INDEX_REQUEST_PATH.length + 1) const locale = id.slice(LOCAL_SEARCH_INDEX_REQUEST_PATH.length + 1)
await (indexAllPromise ??= indexAll()) await ((taskByLocale as any)[locale] ??= indexLocale(locale))
return `export default ${JSON.stringify( return `export default ${JSON.stringify(
JSON.stringify(indexByLocales.get(locale) ?? {}) JSON.stringify(indexByLocale.get(locale) ?? {})
)}` )}`
} }
}, },
async handleHotUpdate({ file }) { async handleHotUpdate({ file }) {
if (file.endsWith('.md')) { if (file.endsWith('.md')) {
await indexFile(file) await indexFile(file, parallel)
debug('🔍️ Updated', file) debug('🔍️ Updated', file)
onIndexUpdated() onIndexUpdated()
} }

Loading…
Cancel
Save