chore: improve plugin-search code comments

This commit is contained in:
pengzhanbo 2026-03-08 16:16:04 +08:00
parent 7751e4c798
commit 552f0f5c32
19 changed files with 553 additions and 10 deletions

View File

@ -1,2 +1,9 @@
/**
* Composables Entry Point
*
*
*
* @module plugin-search/client/composables
*/
export * from './locale.js' export * from './locale.js'
export * from './searchIndex.js' export * from './searchIndex.js'

View File

@ -1,8 +1,20 @@
/**
* Locale Composable for Search Plugin
*
*
*
* @module plugin-search/client/composables/locale
*/
import type { ComputedRef, MaybeRef } from 'vue' import type { ComputedRef, MaybeRef } from 'vue'
import type { SearchBoxLocales, SearchLocaleOptions } from '../../shared/index.js' import type { SearchBoxLocales, SearchLocaleOptions } from '../../shared/index.js'
import { computed, toRef } from 'vue' import { computed, toRef } from 'vue'
import { useRouteLocale } from 'vuepress/client' import { useRouteLocale } from 'vuepress/client'
/**
* Default locale configuration for search.
*
*
*/
const defaultLocales: SearchBoxLocales = { const defaultLocales: SearchBoxLocales = {
'/': { '/': {
placeholder: 'Search', placeholder: 'Search',
@ -21,6 +33,17 @@ const defaultLocales: SearchBoxLocales = {
}, },
} }
/**
* Get locale configuration for the current route.
*
*
*
* @param locales - Locale configuration object /
* @returns Computed ref to the current locale settings /
* @example
* const locale = useLocale(locales)
* console.log(locale.value.placeholder) // 'Search' or localized value
*/
export function useLocale(locales: MaybeRef<SearchBoxLocales>): ComputedRef<Partial<SearchLocaleOptions>> { export function useLocale(locales: MaybeRef<SearchBoxLocales>): ComputedRef<Partial<SearchLocaleOptions>> {
const localesRef = toRef(locales) const localesRef = toRef(locales)
const routeLocale = useRouteLocale() const routeLocale = useRouteLocale()

View File

@ -1,13 +1,44 @@
/**
* Search Index Composable for Search Plugin
*
*
*
* @module plugin-search/client/composables/searchIndex
*/
import type { ShallowRef } from 'vue' import type { ShallowRef } from 'vue'
import { searchIndex } from '@internal/minisearchIndex' import { searchIndex } from '@internal/minisearchIndex'
import { shallowRef } from 'vue' import { shallowRef } from 'vue'
declare const __VUE_HMR_RUNTIME__: Record<string, any> declare const __VUE_HMR_RUNTIME__: Record<string, any>
/**
* Type definition for search index data.
*
*
*
* Maps locale paths to functions that load the corresponding search index.
*
*
*/
type SearchIndexData = Record<string, () => Promise<{ default: string }>> type SearchIndexData = Record<string, () => Promise<{ default: string }>>
/**
* Reactive reference to the search index data.
*
*
*/
const searchIndexData = shallowRef<SearchIndexData>(searchIndex) const searchIndexData = shallowRef<SearchIndexData>(searchIndex)
/**
* Get the search index data for all locales.
*
*
*
* @returns Shallow ref to the search index data /
* @example
* const indexData = useSearchIndex()
* const localeIndex = await indexData.value['/zh/']()
*/
export function useSearchIndex(): ShallowRef<SearchIndexData> { export function useSearchIndex(): ShallowRef<SearchIndexData> {
return searchIndexData return searchIndexData
} }

View File

@ -1,3 +1,15 @@
/**
* VuePress Client Configuration for Search Plugin
*
* VuePress
*
* Registers the SearchBox component globally and provides locale and option
* configuration to the search component.
*
* SearchBox
*
* @module plugin-search/client/config
*/
import type { ClientConfig } from 'vuepress/client' import type { ClientConfig } from 'vuepress/client'
import type { SearchBoxLocales, SearchOptions } from '../shared/index.js' import type { SearchBoxLocales, SearchOptions } from '../shared/index.js'
import { h } from 'vue' import { h } from 'vue'

View File

@ -1,3 +1,15 @@
/**
* VuePress Search Plugin - Client Side Entry
*
* VuePress -
*
* Exports the SearchBox component and search index composable for use in
* VuePress theme components.
*
* SearchBox VuePress 使
*
* @module plugin-search/client
*/
import SearchBox from './components/Search.vue' import SearchBox from './components/Search.vue'
import { useSearchIndex } from './composables/index.js' import { useSearchIndex } from './composables/index.js'

View File

@ -1 +1,8 @@
/**
* Utilities Entry Point
*
*
*
* @module plugin-search/client/utils
*/
export * from './lru.js' export * from './lru.js'

View File

@ -1,14 +1,63 @@
// adapted from https://stackoverflow.com/a/46432113/11613622 /**
* LRU (Least Recently Used) Cache Implementation
*
* LRU使
*
* Adapted from https://stackoverflow.com/a/46432113/11613622
*
* @module plugin-search/client/utils/lru
*/
/**
* Generic LRU Cache implementation using Map.
*
* 使 Map LRU
*
* Automatically evicts the least recently used item when the cache reaches
* its maximum size.
*
* 使
*
* @template K - Key type /
* @template V - Value type /
* @example
* const cache = new LRUCache<string, number>(3)
* cache.set('a', 1)
* cache.set('b', 2)
* cache.set('c', 3)
* cache.set('d', 4) // 'a' is evicted
* cache.get('b') // returns 2, 'b' becomes most recent
*/
export class LRUCache<K, V> { export class LRUCache<K, V> {
/** Maximum number of items in the cache / 缓存中的最大项数 */
private max: number private max: number
/** Internal Map storage / 内部 Map 存储 */
private cache: Map<K, V> private cache: Map<K, V>
/**
* Create a new LRU Cache instance.
*
* LRU
*
* @param max - Maximum cache size (default: 10) / 10
*/
constructor(max: number = 10) { constructor(max: number = 10) {
this.max = max this.max = max
this.cache = new Map<K, V>() this.cache = new Map<K, V>()
} }
/**
* Get a value from the cache.
*
*
*
* Accessing an item moves it to the end (most recently used position).
*
* 访使
*
* @param key - Cache key /
* @returns Cached value or undefined if not found / undefined
*/
get(key: K): V | undefined { get(key: K): V | undefined {
const item = this.cache.get(key) const item = this.cache.get(key)
if (item !== undefined) { if (item !== undefined) {
@ -19,6 +68,19 @@ export class LRUCache<K, V> {
return item return item
} }
/**
* Set a value in the cache.
*
*
*
* If the key already exists, it is moved to the end. If the cache is full,
* the oldest item is evicted.
*
*
*
* @param key - Cache key /
* @param val - Value to cache /
*/
set(key: K, val: V): void { set(key: K, val: V): void {
// refresh key // refresh key
if (this.cache.has(key)) if (this.cache.has(key))
@ -29,10 +91,22 @@ export class LRUCache<K, V> {
this.cache.set(key, val) this.cache.set(key, val)
} }
/**
* Get the first (oldest) key in the cache.
*
*
*
* @returns The oldest key or undefined if cache is empty / undefined
*/
first(): K | undefined { first(): K | undefined {
return this.cache.keys().next().value return this.cache.keys().next().value
} }
/**
* Clear all items from the cache.
*
*
*/
clear(): void { clear(): void {
this.cache.clear() this.cache.clear()
} }

View File

@ -1,3 +1,14 @@
/**
* VuePress Search Plugin - Node Side Entry
*
* VuePress - Node
*
* Exports the search plugin and search index preparation utilities.
*
*
*
* @module plugin-search/node
*/
export * from '../shared/index.js' export * from '../shared/index.js'
export { prepareSearchIndex } from './prepareSearchIndex.js' export { prepareSearchIndex } from './prepareSearchIndex.js'
export { searchPlugin } from './searchPlugin.js' export { searchPlugin } from './searchPlugin.js'

View File

@ -1,6 +1,17 @@
/** 德语 */ /**
* German locale configuration for search plugin.
*
*
*
* @module plugin-search/node/locales/de
*/
import type { SearchLocaleOptions } from '../../shared/index.js' import type { SearchLocaleOptions } from '../../shared/index.js'
/**
* German search locale strings.
*
*
*/
export const deSearchLocale: Partial<SearchLocaleOptions> = { export const deSearchLocale: Partial<SearchLocaleOptions> = {
placeholder: 'Dokumente durchsuchen', placeholder: 'Dokumente durchsuchen',
resetButtonTitle: 'Suche zurücksetzen', resetButtonTitle: 'Suche zurücksetzen',

View File

@ -1,5 +1,17 @@
/**
* English locale configuration for search plugin.
*
*
*
* @module plugin-search/node/locales/en
*/
import type { SearchLocaleOptions } from '../../shared/index.js' import type { SearchLocaleOptions } from '../../shared/index.js'
/**
* English search locale strings.
*
*
*/
export const enSearchLocale: Partial<SearchLocaleOptions> = { export const enSearchLocale: Partial<SearchLocaleOptions> = {
placeholder: 'Search', placeholder: 'Search',
resetButtonTitle: 'Reset search', resetButtonTitle: 'Reset search',

View File

@ -1,6 +1,17 @@
/** 法语 */ /**
* French locale configuration for search plugin.
*
*
*
* @module plugin-search/node/locales/fr
*/
import type { SearchLocaleOptions } from '../../shared/index.js' import type { SearchLocaleOptions } from '../../shared/index.js'
/**
* French search locale strings.
*
*
*/
export const frSearchLocale: Partial<SearchLocaleOptions> = { export const frSearchLocale: Partial<SearchLocaleOptions> = {
placeholder: 'Rechercher dans la documentation', placeholder: 'Rechercher dans la documentation',
resetButtonTitle: 'Réinitialiser la recherche', resetButtonTitle: 'Réinitialiser la recherche',

View File

@ -1,7 +1,14 @@
/** /**
* * Multi-language presets for search plugin.
* /zh/ /en/ AI *
* issue *
*
* Language presets other than /zh/ and /en/ are generated by AI and may not be accurate.
* If you find any errors, please submit an issue.
*
* /zh/ /en/ AI issue
*
* @module plugin-search/node/locales
*/ */
import type { DefaultLocaleInfo } from '@vuepress/helper' import type { DefaultLocaleInfo } from '@vuepress/helper'
import type { SearchLocaleOptions } from '../../shared/index.js' import type { SearchLocaleOptions } from '../../shared/index.js'
@ -13,6 +20,15 @@ import { ruSearchLocale } from './ru.js'
import { zhTwSearchLocale } from './zh-tw.js' import { zhTwSearchLocale } from './zh-tw.js'
import { zhSearchLocale } from './zh.js' import { zhSearchLocale } from './zh.js'
/**
* Default locale configurations for search plugin.
*
*
*
* Maps language codes to their respective locale strings.
*
*
*/
export const SEARCH_LOCALES: DefaultLocaleInfo<Partial<SearchLocaleOptions>> = [ export const SEARCH_LOCALES: DefaultLocaleInfo<Partial<SearchLocaleOptions>> = [
[['en', 'en-US'], enSearchLocale], [['en', 'en-US'], enSearchLocale],
[['zh', 'zh-CN', 'zh-Hans', 'zh-Hant'], zhSearchLocale], [['zh', 'zh-CN', 'zh-Hans', 'zh-Hant'], zhSearchLocale],

View File

@ -1,6 +1,17 @@
/** 日语 */ /**
* Japanese locale configuration for search plugin.
*
*
*
* @module plugin-search/node/locales/ja
*/
import type { SearchLocaleOptions } from '../../shared/index.js' import type { SearchLocaleOptions } from '../../shared/index.js'
/**
* Japanese search locale strings.
*
*
*/
export const jaSearchLocale: Partial<SearchLocaleOptions> = { export const jaSearchLocale: Partial<SearchLocaleOptions> = {
placeholder: 'ドキュメントを検索', placeholder: 'ドキュメントを検索',
resetButtonTitle: '検索をリセット', resetButtonTitle: '検索をリセット',

View File

@ -1,6 +1,17 @@
/** 俄语 */ /**
* Russian locale configuration for search plugin.
*
*
*
* @module plugin-search/node/locales/ru
*/
import type { SearchLocaleOptions } from '../../shared/index.js' import type { SearchLocaleOptions } from '../../shared/index.js'
/**
* Russian search locale strings.
*
*
*/
export const ruSearchLocale: Partial<SearchLocaleOptions> = { export const ruSearchLocale: Partial<SearchLocaleOptions> = {
placeholder: 'Поиск по документации', placeholder: 'Поиск по документации',
resetButtonTitle: 'Сбросить поиск', resetButtonTitle: 'Сбросить поиск',

View File

@ -1,6 +1,17 @@
/** 繁体中文 */ /**
* Traditional Chinese (Taiwan) locale configuration for search plugin.
*
*
*
* @module plugin-search/node/locales/zh-tw
*/
import type { SearchLocaleOptions } from '../../shared/index.js' import type { SearchLocaleOptions } from '../../shared/index.js'
/**
* Traditional Chinese (Taiwan) search locale strings.
*
*
*/
export const zhTwSearchLocale: Partial<SearchLocaleOptions> = { export const zhTwSearchLocale: Partial<SearchLocaleOptions> = {
placeholder: '搜尋文件', placeholder: '搜尋文件',
resetButtonTitle: '重設搜尋', resetButtonTitle: '重設搜尋',

View File

@ -1,5 +1,17 @@
/**
* Simplified Chinese locale configuration for search plugin.
*
*
*
* @module plugin-search/node/locales/zh
*/
import type { SearchLocaleOptions } from '../../shared/index.js' import type { SearchLocaleOptions } from '../../shared/index.js'
/**
* Simplified Chinese search locale strings.
*
*
*/
export const zhSearchLocale: Partial<SearchLocaleOptions> = { export const zhSearchLocale: Partial<SearchLocaleOptions> = {
placeholder: '搜索文档', placeholder: '搜索文档',
resetButtonTitle: '重置搜索', resetButtonTitle: '重置搜索',

View File

@ -1,26 +1,71 @@
/**
* Search Index Preparation Module
*
*
*
* This module handles the creation, update, and management of MiniSearch indexes
* for VuePress pages, supporting multiple locales and hot module replacement.
*
* VuePress MiniSearch
*
*
* @module plugin-search/node/prepareSearchIndex
*/
import type { App, Page } from 'vuepress/core' import type { App, Page } from 'vuepress/core'
import type { SearchOptions, SearchPluginOptions } from '../shared/index.js' import type { SearchOptions, SearchPluginOptions } from '../shared/index.js'
import MiniSearch from 'minisearch' import MiniSearch from 'minisearch'
import pMap from 'p-map' import pMap from 'p-map'
import { colors, logger } from 'vuepress/utils' import { colors, logger } from 'vuepress/utils'
/**
* Options for search index preparation.
*
*
*/
export interface SearchIndexOptions { export interface SearchIndexOptions {
/** VuePress application instance / VuePress 应用实例 */
app: App app: App
/** MiniSearch configuration options / MiniSearch 配置选项 */
searchOptions: SearchOptions searchOptions: SearchOptions
/** Function to filter searchable pages / 过滤可搜索页面的函数 */
isSearchable: SearchPluginOptions['isSearchable'] isSearchable: SearchPluginOptions['isSearchable']
} }
/**
* Internal index object structure for MiniSearch.
*
* MiniSearch
*/
interface IndexObject { interface IndexObject {
/** Unique identifier for the indexed item / 索引项的唯一标识符 */
id: string id: string
/** Text content for searching / 用于搜索的文本内容 */
text: string text: string
/** Title of the section / 章节标题 */
title: string title: string
/** Parent titles hierarchy / 父级标题层级 */
titles: string[] titles: string[]
} }
/** Directory path for storing search index files / 存储搜索索引文件的目录路径 */
const SEARCH_INDEX_DIR = 'internal/minisearchIndex/' const SEARCH_INDEX_DIR = 'internal/minisearchIndex/'
/** Map of locale paths to their MiniSearch instances / 语言路径到 MiniSearch 实例的映射 */
const indexByLocales = new Map<string, MiniSearch<IndexObject>>() const indexByLocales = new Map<string, MiniSearch<IndexObject>>()
/** Cache for index objects by file path / 按文件路径缓存索引对象 */
const indexCache = new Map<string, IndexObject[]>() const indexCache = new Map<string, IndexObject[]>()
/**
* Get or create a MiniSearch index for a specific locale.
*
* MiniSearch
*
* @param locale - Locale path (e.g., '/', '/zh/') /
* @param lang - Language code for tokenization /
* @param options - Search index options /
* @returns MiniSearch instance for the locale / MiniSearch
*/
function getIndexByLocale(locale: string, lang: string, options: SearchIndexOptions['searchOptions']) { function getIndexByLocale(locale: string, lang: string, options: SearchIndexOptions['searchOptions']) {
let index = indexByLocales.get(locale) let index = indexByLocales.get(locale)
if (!index) { if (!index) {
@ -38,6 +83,14 @@ function getIndexByLocale(locale: string, lang: string, options: SearchIndexOpti
return index return index
} }
/**
* Get or create an index cache for a specific file path.
*
*
*
* @param filepath - File path to get cache for /
* @returns Array of index objects for the file /
*/
function getIndexCache(filepath: string) { function getIndexCache(filepath: string) {
let index = indexCache.get(filepath) let index = indexCache.get(filepath)
if (!index) { if (!index) {
@ -47,10 +100,39 @@ function getIndexCache(filepath: string) {
return index return index
} }
/**
* Write a placeholder search index file for development mode.
*
*
*
* This is used to provide an empty index before the actual index is prepared,
* preventing errors when the search component loads before indexing completes.
*
*
*
*
* @param app - VuePress application instance / VuePress
*/
export async function prepareSearchIndexPlaceholder(app: App) { export async function prepareSearchIndexPlaceholder(app: App) {
await app.writeTemp(`${SEARCH_INDEX_DIR}index.js`, 'export const searchIndex = {}') await app.writeTemp(`${SEARCH_INDEX_DIR}index.js`, 'export const searchIndex = {}')
} }
/**
* Prepare search indexes for all pages in the VuePress application.
*
* VuePress
*
* This function indexes all pages concurrently, creating separate MiniSearch
* instances for each locale, and writes the indexes to temporary files.
*
* MiniSearch
*
*
* @param options - Search index preparation options /
* @param options.app - VuePress application instance / VuePress
* @param options.isSearchable - Function to filter searchable pages /
* @param options.searchOptions - MiniSearch configuration / MiniSearch
*/
export async function prepareSearchIndex({ export async function prepareSearchIndex({
app, app,
isSearchable, isSearchable,
@ -78,6 +160,17 @@ export async function prepareSearchIndex({
} }
} }
/**
* Handle search index update when a page is modified.
*
*
*
* @param filepath - Path of the modified file relative to project root /
* @param options - Search index preparation options /
* @param options.app - VuePress application instance / VuePress
* @param options.isSearchable - Function to filter searchable pages /
* @param options.searchOptions - MiniSearch configuration / MiniSearch
*/
export async function onSearchIndexUpdated( export async function onSearchIndexUpdated(
filepath: string, filepath: string,
{ {
@ -97,6 +190,17 @@ export async function onSearchIndexUpdated(
} }
} }
/**
* Handle search index update when a page is removed.
*
*
*
* @param filepath - Path of the removed file relative to project root /
* @param options - Search index preparation options /
* @param options.app - VuePress application instance / VuePress
* @param options.isSearchable - Function to filter searchable pages /
* @param options.searchOptions - MiniSearch configuration / MiniSearch
*/
export async function onSearchIndexRemoved( export async function onSearchIndexRemoved(
filepath: string, filepath: string,
{ {
@ -119,6 +223,19 @@ export async function onSearchIndexRemoved(
} }
} }
/**
* Write all search indexes to temporary files.
*
*
*
* Creates separate JavaScript files for each locale's search index,
* enabling lazy loading of indexes in the client.
*
* JavaScript
*
*
* @param app - VuePress application instance / VuePress
*/
async function writeTemp(app: App) { async function writeTemp(app: App) {
const records: string[] = [] const records: string[] = []
const promises: Promise<string>[] = [] const promises: Promise<string>[] = []
@ -145,6 +262,21 @@ async function writeTemp(app: App) {
await Promise.all(promises) await Promise.all(promises)
} }
/**
* Index a single page for search.
*
*
*
* Extracts content from the page, splits it into sections based on headings,
* and adds each section to the appropriate locale's MiniSearch index.
*
*
* MiniSearch
*
* @param page - VuePress page object / VuePress
* @param options - MiniSearch options / MiniSearch
* @param isSearchable - Function to check if page should be indexed /
*/
async function indexFile(page: Page, options: SearchIndexOptions['searchOptions'], isSearchable: SearchPluginOptions['isSearchable']) { async function indexFile(page: Page, options: SearchIndexOptions['searchOptions'], isSearchable: SearchPluginOptions['isSearchable']) {
if (!page.filePath || page.frontmatter?.search === false) if (!page.filePath || page.frontmatter?.search === false)
return return
@ -194,13 +326,27 @@ ${page.contentRendered}`
} }
} }
/** Regex pattern for matching heading tags / 匹配标题标签的正则表达式 */
// eslint-disable-next-line regexp/no-super-linear-backtracking // eslint-disable-next-line regexp/no-super-linear-backtracking
const headingRegex = /<h(\d*).*?>(<a.*? href="#.*?".*?>[\s\S]*?<\/a>)<\/h\1>/gi const headingRegex = /<h(\d*).*?>(<a.*? href="#.*?".*?>[\s\S]*?<\/a>)<\/h\1>/gi
/** Regex pattern for extracting heading content / 提取标题内容的正则表达式 */
// eslint-disable-next-line regexp/no-super-linear-backtracking // eslint-disable-next-line regexp/no-super-linear-backtracking
const headingContentRegex = /<a.*? href="#(.*?)".*?><span>([\s\S]*?)<\/span><\/a>/i const headingContentRegex = /<a.*? href="#(.*?)".*?><span>([\s\S]*?)<\/span><\/a>/i
/** Regex pattern for ignoring template content / 忽略模板内容的正则表达式 */
const ignoreHeadingRegex = /<template[^>]*>[\s\S]*<\/template>/gi const ignoreHeadingRegex = /<template[^>]*>[\s\S]*<\/template>/gi
/** /**
* Splits HTML into sections based on headings * Split HTML content into sections based on heading elements.
*
* HTML
*
* This generator function parses HTML content and yields section objects
* containing anchor, titles hierarchy, and searchable text.
*
* HTML
*
* @param html - HTML content to split / HTML
* @yields Section objects with anchor, titles, and text /
*/ */
function* splitPageIntoSections(html: string) { function* splitPageIntoSections(html: string) {
const result = html.split(headingRegex) const result = html.split(headingRegex)
@ -228,17 +374,41 @@ function* splitPageIntoSections(html: string) {
} }
} }
/**
* Extract searchable text from HTML content by removing tags.
*
* HTML
*
* @param content - HTML content / HTML
* @returns Plain text content /
*/
function getSearchableText(content: string) { function getSearchableText(content: string) {
content = clearHtmlTags(content) content = clearHtmlTags(content)
return content return content
} }
/**
* Remove all HTML tags from a string.
*
* HTML
*
* @param str - String containing HTML / HTML
* @returns String with HTML tags removed / HTML
*/
function clearHtmlTags(str: string) { function clearHtmlTags(str: string) {
str = str.replace(ignoreHeadingRegex, '') str = str.replace(ignoreHeadingRegex, '')
// 移除其他所有HTML标签 // 移除其他所有HTML标签
return str.replace(/<[^>]*>/g, '') return str.replace(/<[^>]*>/g, '')
} }
/**
* Generate HMR (Hot Module Replacement) code for the search index.
*
* HMR
*
* @param m - Module name /
* @returns HMR code string / HMR
*/
function genHmrCode(m: string) { function genHmrCode(m: string) {
const func = `update${m[0].toUpperCase()}${m.slice(1)}` const func = `update${m[0].toUpperCase()}${m.slice(1)}`
return ` return `

View File

@ -8,6 +8,36 @@ import { onSearchIndexRemoved, onSearchIndexUpdated, prepareSearchIndex, prepare
const __dirname = getDirname(import.meta.url) const __dirname = getDirname(import.meta.url)
/**
* Create a VuePress search plugin instance.
*
* VuePress
*
* @param options - Plugin configuration options /
* @param options.locales - Locale-specific search configurations /
* @param options.isSearchable - Function to determine if a page should be indexed /
* @param options.searchOptions - MiniSearch options / MiniSearch
* @returns VuePress plugin object / VuePress
* @example
* // Basic usage
* export default {
* plugins: [
* searchPlugin()
* ]
* }
*
* // With custom options
* export default {
* plugins: [
* searchPlugin({
* locales: {
* '/zh/': { placeholder: '搜索文档' }
* },
* isSearchable: (page) => page.path !== '/secret/'
* })
* ]
* }
*/
export function searchPlugin({ export function searchPlugin({
locales = {}, locales = {},
isSearchable, isSearchable,

View File

@ -1,40 +1,107 @@
/**
* Shared Types for VuePress Search Plugin
*
* VuePress
*
* This module contains type definitions shared between the node and client
* sides of the search plugin.
*
* Node
*
* @module plugin-search/shared
*/
import type { Options as MiniSearchOptions } from 'minisearch' import type { Options as MiniSearchOptions } from 'minisearch'
import type { LocaleConfig, Page } from 'vuepress/core' import type { LocaleConfig, Page } from 'vuepress/core'
/**
* Locale options for search UI strings.
*
* UI
*/
export interface SearchLocaleOptions { export interface SearchLocaleOptions {
/** Placeholder text for search input / 搜索输入框的占位文本 */
placeholder: string placeholder: string
/** Text for search button / 搜索按钮的文本 */
buttonText: string buttonText: string
/** Title for reset button / 重置按钮的标题 */
resetButtonTitle: string resetButtonTitle: string
/** Title for back/close button / 返回/关闭按钮的标题 */
backButtonTitle: string backButtonTitle: string
/** Text shown when no results found / 无搜索结果时显示的文本 */
noResultsText: string noResultsText: string
/** Footer keyboard shortcut hints / 底部键盘快捷键提示 */
footer: { footer: {
/** Text for select action / 选择操作的文本 */
selectText: string selectText: string
/** ARIA label for select key / 选择键的 ARIA 标签 */
selectKeyAriaLabel: string selectKeyAriaLabel: string
/** Text for navigate action / 导航操作的文本 */
navigateText: string navigateText: string
/** ARIA label for navigate up key / 向上导航键的 ARIA 标签 */
navigateUpKeyAriaLabel: string navigateUpKeyAriaLabel: string
/** ARIA label for navigate down key / 向下导航键的 ARIA 标签 */
navigateDownKeyAriaLabel: string navigateDownKeyAriaLabel: string
/** Text for close action / 关闭操作的文本 */
closeText: string closeText: string
/** ARIA label for close key / 关闭键的 ARIA 标签 */
closeKeyAriaLabel: string closeKeyAriaLabel: string
} }
} }
/**
* Locale configuration type for search box.
*
*
*/
export type SearchBoxLocales = LocaleConfig<SearchLocaleOptions> export type SearchBoxLocales = LocaleConfig<SearchLocaleOptions>
/**
* Options for the search plugin.
*
*
*/
export interface SearchPluginOptions extends SearchOptions { export interface SearchPluginOptions extends SearchOptions {
/** Locale-specific search configurations / 特定语言的搜索配置 */
locales?: SearchBoxLocales locales?: SearchBoxLocales
/**
* Function to determine if a page should be indexed.
*
*
*
* @param page - VuePress page object / VuePress
* @returns Whether the page should be searchable /
*/
isSearchable?: (page: Page) => boolean isSearchable?: (page: Page) => boolean
} }
/**
* Search configuration options.
*
*
*/
export interface SearchOptions { export interface SearchOptions {
/** /**
* Whether to disable query persistence in session storage.
*
*
*
* @default false * @default false
*/ */
disableQueryPersistence?: boolean disableQueryPersistence?: boolean
/**
* MiniSearch configuration options.
*
* MiniSearch
*/
miniSearch?: { miniSearch?: {
/** /**
* MiniSearch instance options.
*
* MiniSearch
*
* @see https://lucaong.github.io/minisearch/modules/_minisearch_.html#options * @see https://lucaong.github.io/minisearch/modules/_minisearch_.html#options
*/ */
options?: Pick< options?: Pick<
@ -42,6 +109,10 @@ export interface SearchOptions {
'extractField' | 'tokenize' | 'processTerm' 'extractField' | 'tokenize' | 'processTerm'
> >
/** /**
* MiniSearch search options.
*
* MiniSearch
*
* @see https://lucaong.github.io/minisearch/modules/_minisearch_.html#searchoptions-1 * @see https://lucaong.github.io/minisearch/modules/_minisearch_.html#searchoptions-1
*/ */
searchOptions?: MiniSearchOptions['searchOptions'] searchOptions?: MiniSearchOptions['searchOptions']