fumadocs-core 16.15.16 → 16.15.18
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.
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { n as SearchClient } from "../../client-BcR4jyFl.js";
|
|
2
|
+
import { Meilisearch } from "meilisearch";
|
|
3
|
+
//#region src/search/client/meilisearch.d.ts
|
|
4
|
+
export interface MeilisearchOptions {
|
|
5
|
+
/**
|
|
6
|
+
* Meilisearch client with a search API key
|
|
7
|
+
*/
|
|
8
|
+
client: Meilisearch;
|
|
9
|
+
indexName: string;
|
|
10
|
+
/**
|
|
11
|
+
* Filter results with specific tag(s).
|
|
12
|
+
*/
|
|
13
|
+
tag?: string | string[];
|
|
14
|
+
/**
|
|
15
|
+
* Filter results by locale.
|
|
16
|
+
*/
|
|
17
|
+
locale?: string;
|
|
18
|
+
}
|
|
19
|
+
export declare function meilisearchClient(options: MeilisearchOptions): SearchClient;
|
|
20
|
+
//#endregion
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import { createContentHighlighter } from "../index.js";
|
|
2
|
+
//#region src/search/client/meilisearch.ts
|
|
3
|
+
function meilisearchClient(options) {
|
|
4
|
+
const { client, indexName, tag, locale } = options;
|
|
5
|
+
return {
|
|
6
|
+
deps: [
|
|
7
|
+
client,
|
|
8
|
+
indexName,
|
|
9
|
+
tag,
|
|
10
|
+
locale
|
|
11
|
+
],
|
|
12
|
+
async search(query) {
|
|
13
|
+
if (query.trim().length === 0) return [];
|
|
14
|
+
const filter = [];
|
|
15
|
+
if (locale) filter.push(`locale = ${JSON.stringify(locale)}`);
|
|
16
|
+
for (const item of typeof tag === "string" ? [tag] : tag ?? []) filter.push(`tag = ${JSON.stringify(item)}`);
|
|
17
|
+
const { hits } = await client.index(indexName).search(query, {
|
|
18
|
+
filter,
|
|
19
|
+
limit: 20
|
|
20
|
+
});
|
|
21
|
+
const highlighter = createContentHighlighter(query);
|
|
22
|
+
const groups = /* @__PURE__ */ new Map();
|
|
23
|
+
for (const hit of hits) {
|
|
24
|
+
let group = groups.get(hit.url);
|
|
25
|
+
if (!group) {
|
|
26
|
+
group = [{
|
|
27
|
+
id: hit.url,
|
|
28
|
+
type: "page",
|
|
29
|
+
content: highlighter.highlightMarkdown(hit.title),
|
|
30
|
+
breadcrumbs: hit.breadcrumbs,
|
|
31
|
+
url: hit.url
|
|
32
|
+
}];
|
|
33
|
+
groups.set(hit.url, group);
|
|
34
|
+
}
|
|
35
|
+
if (hit.type === "page") continue;
|
|
36
|
+
group.push({
|
|
37
|
+
id: hit.id.toString(),
|
|
38
|
+
type: hit.type,
|
|
39
|
+
content: highlighter.highlightMarkdown(hit.content),
|
|
40
|
+
url: hit.heading ? `${hit.url}#${hit.heading}` : hit.url
|
|
41
|
+
});
|
|
42
|
+
}
|
|
43
|
+
const results = [];
|
|
44
|
+
for (const group of groups.values()) results.push(...group);
|
|
45
|
+
return results;
|
|
46
|
+
}
|
|
47
|
+
};
|
|
48
|
+
}
|
|
49
|
+
//#endregion
|
|
50
|
+
export { meilisearchClient };
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import { t as Awaitable } from "../types-D89QoQR-.js";
|
|
2
|
+
import { i as StructuredData } from "../remark-structure-CnHwvNZr.js";
|
|
3
|
+
import { S as LoaderOutput, b as LoaderConfig } from "../index-CBtz3H2e.js";
|
|
4
|
+
import { Meilisearch } from "meilisearch";
|
|
5
|
+
//#region src/search/meilisearch.d.ts
|
|
6
|
+
export interface DocumentRecord {
|
|
7
|
+
title: string;
|
|
8
|
+
description?: string;
|
|
9
|
+
breadcrumbs?: string[];
|
|
10
|
+
/**
|
|
11
|
+
* URL to the page
|
|
12
|
+
*/
|
|
13
|
+
url: string;
|
|
14
|
+
structured: StructuredData;
|
|
15
|
+
/**
|
|
16
|
+
* Tag(s) to filter results
|
|
17
|
+
*/
|
|
18
|
+
tag?: string | string[];
|
|
19
|
+
locale?: string;
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* Document in Meilisearch, for the title, headings and paragraphs of a page
|
|
23
|
+
*/
|
|
24
|
+
export interface MeilisearchDocument extends Omit<DocumentRecord, 'description' | 'structured'> {
|
|
25
|
+
id: number;
|
|
26
|
+
type: 'page' | 'heading' | 'text';
|
|
27
|
+
/**
|
|
28
|
+
* ID of the heading it belongs to
|
|
29
|
+
*/
|
|
30
|
+
heading?: string;
|
|
31
|
+
content: string;
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* Build the search documents of every page in a source.
|
|
35
|
+
*/
|
|
36
|
+
export declare function toDocuments<C extends LoaderConfig>(source: LoaderOutput<C> | (() => Awaitable<LoaderOutput<C>>), options?: {
|
|
37
|
+
/** Tag to filter results by. */
|
|
38
|
+
tag?: (page: C['page']) => string | string[];
|
|
39
|
+
}): Promise<DocumentRecord[]>;
|
|
40
|
+
export interface SyncOptions {
|
|
41
|
+
indexName: string;
|
|
42
|
+
documents: DocumentRecord[];
|
|
43
|
+
}
|
|
44
|
+
/**
|
|
45
|
+
* Configure the index and replace its documents, existing documents stay searchable until the new ones are indexed.
|
|
46
|
+
*
|
|
47
|
+
* @param client - Meilisearch client with an admin API key
|
|
48
|
+
*/
|
|
49
|
+
export declare function sync(client: Meilisearch, options: SyncOptions): Promise<void>;
|
|
50
|
+
//#endregion
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
import { n as buildDocuments, t as buildBreadcrumbs } from "../build-index-BD-VRKOW.js";
|
|
2
|
+
//#region src/search/meilisearch.ts
|
|
3
|
+
/**
|
|
4
|
+
* Build the search documents of every page in a source.
|
|
5
|
+
*/
|
|
6
|
+
async function toDocuments(source, options = {}) {
|
|
7
|
+
const loader = typeof source === "function" ? await source() : source;
|
|
8
|
+
return buildDocuments(loader, (index, page) => ({
|
|
9
|
+
title: index.title,
|
|
10
|
+
description: index.description,
|
|
11
|
+
breadcrumbs: buildBreadcrumbs(loader, page),
|
|
12
|
+
url: index.url,
|
|
13
|
+
structured: index.structuredData,
|
|
14
|
+
tag: options.tag?.(page),
|
|
15
|
+
locale: page.locale
|
|
16
|
+
}));
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* Configure the index and replace its documents, existing documents stay searchable until the new ones are indexed.
|
|
20
|
+
*
|
|
21
|
+
* @param client - Meilisearch client with an admin API key
|
|
22
|
+
*/
|
|
23
|
+
async function sync(client, options) {
|
|
24
|
+
const index = client.index(options.indexName);
|
|
25
|
+
const documents = [];
|
|
26
|
+
for (const { description, structured, ...page } of options.documents) {
|
|
27
|
+
const add = (type, content, heading) => documents.push({
|
|
28
|
+
...page,
|
|
29
|
+
id: documents.length,
|
|
30
|
+
type,
|
|
31
|
+
content,
|
|
32
|
+
heading
|
|
33
|
+
});
|
|
34
|
+
add("page", page.title);
|
|
35
|
+
if (description && !structured.contents.some((item) => item.content === description)) add("text", description);
|
|
36
|
+
for (const heading of structured.headings) add("heading", heading.content, heading.id);
|
|
37
|
+
for (const item of structured.contents) add("text", item.content, item.heading);
|
|
38
|
+
}
|
|
39
|
+
await run(index.updateSettings({
|
|
40
|
+
searchableAttributes: ["content"],
|
|
41
|
+
filterableAttributes: [
|
|
42
|
+
"id",
|
|
43
|
+
"tag",
|
|
44
|
+
"locale"
|
|
45
|
+
]
|
|
46
|
+
}));
|
|
47
|
+
await run(index.addDocuments(documents, { primaryKey: "id" }));
|
|
48
|
+
await run(index.deleteDocuments({ filter: `id >= ${documents.length}` }));
|
|
49
|
+
}
|
|
50
|
+
async function run(task) {
|
|
51
|
+
const { status, error } = await task.waitTask({ timeout: 0 });
|
|
52
|
+
if (status !== "succeeded") throw new Error(error ? error.message : `Meilisearch task ${status}`, { cause: error });
|
|
53
|
+
}
|
|
54
|
+
//#endregion
|
|
55
|
+
export { sync, toDocuments };
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "fumadocs-core",
|
|
3
|
-
"version": "16.15.
|
|
3
|
+
"version": "16.15.18",
|
|
4
4
|
"description": "The React.js library for building a documentation website",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"Docs",
|
|
@@ -75,11 +75,13 @@
|
|
|
75
75
|
"./search/client/algolia": "./dist/search/client/algolia.js",
|
|
76
76
|
"./search/client/fetch": "./dist/search/client/fetch.js",
|
|
77
77
|
"./search/client/flexsearch-static": "./dist/search/client/flexsearch-static.js",
|
|
78
|
+
"./search/client/meilisearch": "./dist/search/client/meilisearch.js",
|
|
78
79
|
"./search/client/mixedbread": "./dist/search/client/mixedbread.js",
|
|
79
80
|
"./search/client/orama-cloud": "./dist/search/client/orama-cloud.js",
|
|
80
81
|
"./search/client/orama-cloud-legacy": "./dist/search/client/orama-cloud-legacy.js",
|
|
81
82
|
"./search/client/orama-static": "./dist/search/client/orama-static.js",
|
|
82
83
|
"./search/flexsearch": "./dist/search/flexsearch.js",
|
|
84
|
+
"./search/meilisearch": "./dist/search/meilisearch.js",
|
|
83
85
|
"./search/mixedbread": "./dist/search/mixedbread.js",
|
|
84
86
|
"./search/orama-cloud": "./dist/search/orama-cloud.js",
|
|
85
87
|
"./search/orama-cloud-legacy": "./dist/search/orama-cloud-legacy.js",
|
|
@@ -148,6 +150,7 @@
|
|
|
148
150
|
"algoliasearch": "5.59.0",
|
|
149
151
|
"flexsearch": "^0.8.212",
|
|
150
152
|
"lucide-react": "^1.47.0",
|
|
153
|
+
"meilisearch": "0.62.0",
|
|
151
154
|
"next": "16.3.5",
|
|
152
155
|
"path-to-regexp": "^8.4.2",
|
|
153
156
|
"react-router": "^8.4.0",
|
|
@@ -174,6 +177,7 @@
|
|
|
174
177
|
"algoliasearch": "5.x.x",
|
|
175
178
|
"flexsearch": "*",
|
|
176
179
|
"lucide-react": "*",
|
|
180
|
+
"meilisearch": ">=0.50.0 <1.0.0",
|
|
177
181
|
"next": "16.x.x",
|
|
178
182
|
"react": "^19.2.0",
|
|
179
183
|
"react-dom": "^19.2.0",
|
|
@@ -215,6 +219,9 @@
|
|
|
215
219
|
"algoliasearch": {
|
|
216
220
|
"optional": true
|
|
217
221
|
},
|
|
222
|
+
"meilisearch": {
|
|
223
|
+
"optional": true
|
|
224
|
+
},
|
|
218
225
|
"next": {
|
|
219
226
|
"optional": true
|
|
220
227
|
},
|