fumadocs-core 13.0.3 → 13.0.5
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.
- package/dist/chunk-NREWOIVI.js +19 -0
- package/dist/search/client.js +4 -13
- package/dist/search/server.d.ts +3 -1
- package/dist/search/server.js +19 -0
- package/dist/search-algolia/client.d.ts +7 -1
- package/dist/search-algolia/client.js +8 -4
- package/dist/search-algolia/server.d.ts +11 -12
- package/dist/search-algolia/server.js +24 -29
- package/package.json +1 -1
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
// src/utils/use-debounce.ts
|
|
2
|
+
import { useRef, useState } from "react";
|
|
3
|
+
function useDebounce(value, delayMs = 1e3) {
|
|
4
|
+
const [debouncedValue, setDebouncedValue] = useState(value);
|
|
5
|
+
const timer = useRef();
|
|
6
|
+
if (delayMs === 0) return value;
|
|
7
|
+
if (value !== debouncedValue && timer.current?.value !== value) {
|
|
8
|
+
if (timer.current) clearTimeout(timer.current.handler);
|
|
9
|
+
const handler = window.setTimeout(() => {
|
|
10
|
+
setDebouncedValue(value);
|
|
11
|
+
}, delayMs);
|
|
12
|
+
timer.current = { value, handler };
|
|
13
|
+
}
|
|
14
|
+
return debouncedValue;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
export {
|
|
18
|
+
useDebounce
|
|
19
|
+
};
|
package/dist/search/client.js
CHANGED
|
@@ -1,7 +1,10 @@
|
|
|
1
|
+
import {
|
|
2
|
+
useDebounce
|
|
3
|
+
} from "../chunk-NREWOIVI.js";
|
|
1
4
|
import "../chunk-MLKGABMK.js";
|
|
2
5
|
|
|
3
6
|
// src/search/client.ts
|
|
4
|
-
import {
|
|
7
|
+
import { useState } from "react";
|
|
5
8
|
import useSWR from "swr";
|
|
6
9
|
async function fetchDocs(api, query, locale, tag) {
|
|
7
10
|
if (query.length === 0) return "empty";
|
|
@@ -25,18 +28,6 @@ function useDocsSearch(locale, tag, api = "/api/search", delayMs = 100) {
|
|
|
25
28
|
);
|
|
26
29
|
return { search, setSearch, query };
|
|
27
30
|
}
|
|
28
|
-
function useDebounce(value, delayMs = 1e3) {
|
|
29
|
-
const [debouncedValue, setDebouncedValue] = useState(value);
|
|
30
|
-
useEffect(() => {
|
|
31
|
-
const handler = setTimeout(() => {
|
|
32
|
-
setDebouncedValue(value);
|
|
33
|
-
}, delayMs);
|
|
34
|
-
return () => {
|
|
35
|
-
clearTimeout(handler);
|
|
36
|
-
};
|
|
37
|
-
}, [value, delayMs]);
|
|
38
|
-
return debouncedValue;
|
|
39
|
-
}
|
|
40
31
|
export {
|
|
41
32
|
useDocsSearch
|
|
42
33
|
};
|
package/dist/search/server.d.ts
CHANGED
|
@@ -41,6 +41,7 @@ declare function createSearchAPI<T extends 'simple' | 'advanced'>(type: T, optio
|
|
|
41
41
|
declare function createI18nSearchAPI<T extends 'simple' | 'advanced'>(type: T, options: T extends 'simple' ? ToI18n<SimpleOptions> : ToI18n<AdvancedOptions>): SearchAPI;
|
|
42
42
|
interface Index {
|
|
43
43
|
title: string;
|
|
44
|
+
description?: string;
|
|
44
45
|
content: string;
|
|
45
46
|
url: string;
|
|
46
47
|
keywords?: string;
|
|
@@ -49,9 +50,10 @@ declare function initSearchAPI({ indexes, language }: SimpleOptions): SearchAPI;
|
|
|
49
50
|
interface AdvancedIndex {
|
|
50
51
|
id: string;
|
|
51
52
|
title: string;
|
|
53
|
+
description?: string;
|
|
52
54
|
keywords?: string;
|
|
53
55
|
/**
|
|
54
|
-
* Required if
|
|
56
|
+
* Required if tag filter is enabled
|
|
55
57
|
*/
|
|
56
58
|
tag?: string;
|
|
57
59
|
/**
|
package/dist/search/server.js
CHANGED
|
@@ -63,6 +63,14 @@ function initSearchAPI({ indexes, language }) {
|
|
|
63
63
|
tokenize: "forward",
|
|
64
64
|
resolution: 9
|
|
65
65
|
},
|
|
66
|
+
{
|
|
67
|
+
field: "description",
|
|
68
|
+
tokenize: "strict",
|
|
69
|
+
context: {
|
|
70
|
+
depth: 1,
|
|
71
|
+
resolution: 9
|
|
72
|
+
}
|
|
73
|
+
},
|
|
66
74
|
{
|
|
67
75
|
field: "content",
|
|
68
76
|
tokenize: "strict",
|
|
@@ -82,6 +90,7 @@ function initSearchAPI({ indexes, language }) {
|
|
|
82
90
|
for (const page of items) {
|
|
83
91
|
index.add({
|
|
84
92
|
title: page.title,
|
|
93
|
+
description: page.description,
|
|
85
94
|
url: page.url,
|
|
86
95
|
content: page.content,
|
|
87
96
|
keywords: page.keywords
|
|
@@ -146,6 +155,16 @@ function initSearchAPIAdvanced({
|
|
|
146
155
|
tag: page.tag,
|
|
147
156
|
url: page.url
|
|
148
157
|
});
|
|
158
|
+
if (page.description) {
|
|
159
|
+
index.add({
|
|
160
|
+
id: page.id + (id++).toString(),
|
|
161
|
+
page_id: page.id,
|
|
162
|
+
tag: page.tag,
|
|
163
|
+
type: "text",
|
|
164
|
+
url: page.url,
|
|
165
|
+
content: page.description
|
|
166
|
+
});
|
|
167
|
+
}
|
|
149
168
|
for (const heading of data.headings) {
|
|
150
169
|
index.add({
|
|
151
170
|
id: page.id + (id++).toString(),
|
|
@@ -15,6 +15,12 @@ interface Options extends SearchOptions {
|
|
|
15
15
|
* @defaultValue true
|
|
16
16
|
*/
|
|
17
17
|
allowEmpty?: boolean;
|
|
18
|
+
/**
|
|
19
|
+
* Delay to debounce (in ms)
|
|
20
|
+
*
|
|
21
|
+
* @defaultValue 300
|
|
22
|
+
*/
|
|
23
|
+
delay?: number;
|
|
18
24
|
}
|
|
19
25
|
declare function groupResults(hits: Hit<BaseIndex>[]): SortedResult[];
|
|
20
26
|
declare function searchDocs(index: SearchIndex, query: string, options?: SearchOptions): Promise<SortedResult[]>;
|
|
@@ -25,6 +31,6 @@ interface UseAlgoliaSearch {
|
|
|
25
31
|
keepPreviousData: true;
|
|
26
32
|
}>;
|
|
27
33
|
}
|
|
28
|
-
declare function useAlgoliaSearch(index: SearchIndex, { allowEmpty, ...options }?: Options): UseAlgoliaSearch;
|
|
34
|
+
declare function useAlgoliaSearch(index: SearchIndex, { allowEmpty, delay, ...options }?: Options): UseAlgoliaSearch;
|
|
29
35
|
|
|
30
36
|
export { type Options, groupResults, searchDocs, useAlgoliaSearch };
|
|
@@ -1,3 +1,6 @@
|
|
|
1
|
+
import {
|
|
2
|
+
useDebounce
|
|
3
|
+
} from "../chunk-NREWOIVI.js";
|
|
1
4
|
import "../chunk-MLKGABMK.js";
|
|
2
5
|
|
|
3
6
|
// src/search-algolia/client.ts
|
|
@@ -41,13 +44,14 @@ async function searchDocs(index, query, options) {
|
|
|
41
44
|
});
|
|
42
45
|
return groupResults(result.hits);
|
|
43
46
|
}
|
|
44
|
-
function useAlgoliaSearch(index, { allowEmpty = true, ...options } = {}) {
|
|
47
|
+
function useAlgoliaSearch(index, { allowEmpty = true, delay = 150, ...options } = {}) {
|
|
45
48
|
const [search, setSearch] = useState("");
|
|
49
|
+
const debouncedValue = useDebounce(search, delay);
|
|
46
50
|
const query = useSWR(
|
|
47
|
-
["algolia-search",
|
|
51
|
+
["algolia-search", debouncedValue, allowEmpty, options],
|
|
48
52
|
async () => {
|
|
49
|
-
if (allowEmpty &&
|
|
50
|
-
return searchDocs(index,
|
|
53
|
+
if (allowEmpty && debouncedValue.length === 0) return "empty";
|
|
54
|
+
return searchDocs(index, debouncedValue, options);
|
|
51
55
|
},
|
|
52
56
|
{
|
|
53
57
|
keepPreviousData: true
|
|
@@ -9,6 +9,7 @@ interface DocumentRecord {
|
|
|
9
9
|
*/
|
|
10
10
|
_id: string;
|
|
11
11
|
title: string;
|
|
12
|
+
description?: string;
|
|
12
13
|
/**
|
|
13
14
|
* URL to the page
|
|
14
15
|
*/
|
|
@@ -41,19 +42,8 @@ interface SyncOptions {
|
|
|
41
42
|
*/
|
|
42
43
|
declare function sync(client: SearchClient, options: SyncOptions): Promise<void>;
|
|
43
44
|
declare function setIndexSettings(index: SearchIndex): Promise<void>;
|
|
44
|
-
interface Section {
|
|
45
|
-
/**
|
|
46
|
-
* Heading content
|
|
47
|
-
*/
|
|
48
|
-
section?: string;
|
|
49
|
-
/**
|
|
50
|
-
* The anchor id
|
|
51
|
-
*/
|
|
52
|
-
section_id?: string;
|
|
53
|
-
content: string;
|
|
54
|
-
}
|
|
55
45
|
declare function updateDocuments(index: SearchIndex, documents: DocumentRecord[]): Promise<void>;
|
|
56
|
-
interface BaseIndex
|
|
46
|
+
interface BaseIndex {
|
|
57
47
|
objectID: string;
|
|
58
48
|
title: string;
|
|
59
49
|
url: string;
|
|
@@ -62,6 +52,15 @@ interface BaseIndex extends Section {
|
|
|
62
52
|
* The id of page, used for distinct
|
|
63
53
|
*/
|
|
64
54
|
page_id: string;
|
|
55
|
+
/**
|
|
56
|
+
* Heading content
|
|
57
|
+
*/
|
|
58
|
+
section?: string;
|
|
59
|
+
/**
|
|
60
|
+
* Heading (anchor) id
|
|
61
|
+
*/
|
|
62
|
+
section_id?: string;
|
|
63
|
+
content: string;
|
|
65
64
|
}
|
|
66
65
|
|
|
67
66
|
export { type BaseIndex, type SyncOptions, setIndexSettings, sync, updateDocuments };
|
|
@@ -16,43 +16,38 @@ async function setIndexSettings(index) {
|
|
|
16
16
|
attributesForFaceting: ["tag"]
|
|
17
17
|
});
|
|
18
18
|
}
|
|
19
|
-
function
|
|
19
|
+
function toIndex(page) {
|
|
20
|
+
let id = 0;
|
|
21
|
+
const indexes = [];
|
|
20
22
|
const scannedHeadings = /* @__PURE__ */ new Set();
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
23
|
+
function createIndex(section, sectionId, content) {
|
|
24
|
+
return {
|
|
25
|
+
objectID: `${page._id}-${(id++).toString()}`,
|
|
26
|
+
title: page.title,
|
|
27
|
+
url: page.url,
|
|
28
|
+
page_id: page._id,
|
|
29
|
+
tag: page.tag,
|
|
30
|
+
section,
|
|
31
|
+
section_id: sectionId,
|
|
32
|
+
content,
|
|
33
|
+
...page.extra_data
|
|
27
34
|
};
|
|
35
|
+
}
|
|
36
|
+
if (page.description)
|
|
37
|
+
indexes.push(createIndex(void 0, void 0, page.description));
|
|
38
|
+
page.structured.contents.forEach((p) => {
|
|
39
|
+
const heading = p.heading ? page.structured.headings.find((h) => p.heading === h.id) : null;
|
|
40
|
+
const index = createIndex(heading?.content, heading?.id, p.content);
|
|
28
41
|
if (heading && !scannedHeadings.has(heading.id)) {
|
|
29
42
|
scannedHeadings.add(heading.id);
|
|
30
|
-
|
|
31
|
-
{
|
|
32
|
-
section: heading.content,
|
|
33
|
-
section_id: heading.id,
|
|
34
|
-
content: heading.content
|
|
35
|
-
},
|
|
36
|
-
section
|
|
37
|
-
];
|
|
43
|
+
indexes.push(createIndex(heading.content, heading.id, heading.content));
|
|
38
44
|
}
|
|
39
|
-
|
|
45
|
+
indexes.push(index);
|
|
40
46
|
});
|
|
47
|
+
return indexes;
|
|
41
48
|
}
|
|
42
49
|
async function updateDocuments(index, documents) {
|
|
43
|
-
const objects = documents.flatMap(
|
|
44
|
-
return getSections(page).map(
|
|
45
|
-
(section, idx) => ({
|
|
46
|
-
objectID: `${page._id}-${idx.toString()}`,
|
|
47
|
-
title: page.title,
|
|
48
|
-
url: page.url,
|
|
49
|
-
page_id: page._id,
|
|
50
|
-
tag: page.tag,
|
|
51
|
-
...section,
|
|
52
|
-
...page.extra_data
|
|
53
|
-
})
|
|
54
|
-
);
|
|
55
|
-
});
|
|
50
|
+
const objects = documents.flatMap(toIndex);
|
|
56
51
|
await index.replaceAllObjects(objects);
|
|
57
52
|
}
|
|
58
53
|
export {
|