@vuepress-plume/plugin-search 1.0.0-rc.214 → 1.0.0-rc.215

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -61,5 +61,4 @@ if (__VUEPRESS_DEV__ && (import.meta.webpackHot || import.meta.hot))
61
61
  __VUE_HMR_RUNTIME__.updateSearchIndex = (data) => {
62
62
  searchIndexData.value = data
63
63
  }
64
-
65
64
  export {loadSearchIndexJSON, useLocale, useSearchIndex}
@@ -15,5 +15,4 @@ var config_default = defineClientConfig({
15
15
  )
16
16
  },
17
17
  })
18
-
19
18
  export {config_default as default}
@@ -20,9 +20,6 @@ interface SearchIndexOptions {
20
20
  *
21
21
  * 为 VuePress 应用中的所有页面准备搜索索引。
22
22
  *
23
- * This function indexes all pages concurrently, creating separate MiniSearch
24
- * instances for each locale, and writes the indexes to temporary files.
25
- *
26
23
  * 此函数并发索引所有页面,为每个语言创建独立的 MiniSearch 实例,
27
24
  * 并将索引写入临时文件。
28
25
  *
@@ -485,5 +485,4 @@ function searchPlugin({locales = {}, isSearchable, ...searchOptions} = {}) {
485
485
  },
486
486
  })
487
487
  }
488
-
489
488
  export {prepareSearchIndex, searchPlugin}
@@ -1,5 +1,27 @@
1
1
  import {Options} from 'minisearch'
2
2
  import {LocaleConfig, Page} from 'vuepress/core'
3
+ /**
4
+ * Create a tokenizer shared by the node (index build) and client (query) sides.
5
+ *
6
+ * 创建由 Node 端(构建索引)与客户端(查询)共享的分词器。
7
+ *
8
+ * MiniSearch requires the tokenizer used to build the index to be identical to
9
+ * the one used at query time. Defining it in one place guarantees both sides
10
+ * use the same strategy: `Intl.Segmenter` when available, otherwise the same
11
+ * deterministic whitespace fallback. Blank and punctuation-only tokens are
12
+ * discarded on both sides, so they never pollute the index or the query.
13
+ *
14
+ * MiniSearch 要求构建索引与查询时使用完全一致的分词器。集中定义可保证两端策略一致:
15
+ * 支持 `Intl.Segmenter` 时使用它分词,否则统一退化为确定性的空白符分词。
16
+ * 两端都会丢弃空白与纯标点词元,避免污染索引与查询。
17
+ *
18
+ * @param lang - Language code for word segmentation / 用于分词的语言代码
19
+ * @returns Tokenizer that splits a string into tokens / 将字符串切分为词元的函数
20
+ * @example
21
+ * const tokenize = createTokenizer('en')
22
+ * tokenize('Hello world') // ['Hello', 'world'] with Intl.Segmenter
23
+ */
24
+ export declare function createTokenizer(lang: string): (text: string) => string[]
3
25
  /**
4
26
  * Locale options for search UI strings.
5
27
  *
@@ -59,28 +81,6 @@ export interface SearchLocaleOptions {
59
81
  * 搜索框的语言配置类型。
60
82
  */
61
83
  export type SearchBoxLocales = LocaleConfig<SearchLocaleOptions>
62
- /**
63
- * Create a tokenizer shared by the node (index build) and client (query) sides.
64
- *
65
- * 创建由 Node 端(构建索引)与客户端(查询)共享的分词器。
66
- *
67
- * MiniSearch requires the tokenizer used to build the index to be identical to
68
- * the one used at query time. Defining it in one place guarantees both sides
69
- * use the same strategy: `Intl.Segmenter` when available, otherwise the same
70
- * deterministic whitespace fallback. Blank and punctuation-only tokens are
71
- * discarded on both sides, so they never pollute the index or the query.
72
- *
73
- * MiniSearch 要求构建索引与查询时使用完全一致的分词器。集中定义可保证两端策略一致:
74
- * 支持 `Intl.Segmenter` 时使用它分词,否则统一退化为确定性的空白符分词。
75
- * 两端都会丢弃空白与纯标点词元,避免污染索引与查询。
76
- *
77
- * @param lang - Language code for word segmentation / 用于分词的语言代码
78
- * @returns Tokenizer that splits a string into tokens / 将字符串切分为词元的函数
79
- * @example
80
- * const tokenize = createTokenizer('en')
81
- * tokenize('Hello world') // ['Hello', 'world'] with Intl.Segmenter
82
- */
83
- export declare function createTokenizer(lang: string): (text: string) => string[]
84
84
  /**
85
85
  * Options for the search plugin.
86
86
  *
@@ -1,16 +1,32 @@
1
+ const SPACE_OR_PUNCTUATION_RE = /[\n\r\p{Z}\p{P}]+/u
2
+ const UNSPACED_RUN_RE =
3
+ /[\p{scx=Han}\p{scx=Hiragana}\p{scx=Katakana}]+|[^\p{scx=Han}\p{scx=Hiragana}\p{scx=Katakana}]+/gu
4
+ const UNSPACED_START_RE = /^[\p{scx=Han}\p{scx=Hiragana}\p{scx=Katakana}]/u
5
+ const NO_SPACE_AND_PUNCTUATION_RE_RE = /\p{L}|\p{N}/u
6
+
1
7
  function isWordToken(token) {
2
- return /\p{L}|\p{N}/u.test(token)
8
+ return NO_SPACE_AND_PUNCTUATION_RE_RE.test(token)
3
9
  }
4
10
 
5
11
  function createTokenizer(lang) {
6
12
  if (typeof Intl !== 'undefined' && typeof Intl.Segmenter === 'function') {
7
13
  const segmenter = new Intl.Segmenter(lang, {granularity: 'word'})
8
- return (text) =>
9
- Array.from(segmenter.segment(text))
10
- .map((segment) => segment.segment)
14
+ return (text) => {
15
+ return text
16
+ .split(SPACE_OR_PUNCTUATION_RE)
17
+ .flatMap(
18
+ (term) =>
19
+ term
20
+ .match(UNSPACED_RUN_RE)
21
+ ?.flatMap((run) =>
22
+ UNSPACED_START_RE.test(run)
23
+ ? Array.from(segmenter.segment(run), (part) => part.segment)
24
+ : run,
25
+ ) ?? term,
26
+ )
11
27
  .filter(isWordToken)
28
+ }
12
29
  }
13
- return (text) => text.split(/\s+/).filter(isWordToken)
30
+ return (text) => text.split(SPACE_OR_PUNCTUATION_RE).filter(isWordToken)
14
31
  }
15
-
16
32
  export {createTokenizer}
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@vuepress-plume/plugin-search",
3
3
  "type": "module",
4
- "version": "1.0.0-rc.214",
4
+ "version": "1.0.0-rc.215",
5
5
  "description": "The Plugin for VuePress 2 - local search",
6
6
  "author": "pengzhanbo <volodymyr@foxmail.com>",
7
7
  "license": "MIT",
@@ -44,12 +44,12 @@
44
44
  "@vueuse/core": "^15.0.0",
45
45
  "@vueuse/integrations": "^15.0.0",
46
46
  "chokidar": "5.0.0",
47
- "focus-trap": "^8.2.3",
47
+ "focus-trap": "^8.2.4",
48
48
  "mark.js": "^8.11.1",
49
49
  "minisearch": "^7.2.0",
50
- "p-map": "^7.0.8",
51
- "sanitize-html": "^2.18.0",
52
- "vue": "^3.5.43",
50
+ "p-map": "^7.1.1",
51
+ "sanitize-html": "^2.18.1",
52
+ "vue": "^3.5.44",
53
53
  "vue-router": "^5.4.0"
54
54
  },
55
55
  "publishConfig": {