fumadocs-core 15.2.8 → 16.0.3

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.
Files changed (92) hide show
  1. package/README.md +1 -1
  2. package/dist/algolia-IZEDLPHE.js +58 -0
  3. package/dist/breadcrumb.d.ts +7 -5
  4. package/dist/breadcrumb.js +46 -52
  5. package/dist/builder-feW_xVjc.d.ts +296 -0
  6. package/dist/{chunk-FVY6EZ3N.js → chunk-BBP7MIO4.js} +12 -14
  7. package/dist/{chunk-ORHEEQVY.js → chunk-EMWGTXSW.js} +0 -7
  8. package/dist/chunk-FAEPKD7U.js +20 -0
  9. package/dist/{chunk-NNKVN7WA.js → chunk-H2GMUTQG.js} +4 -2
  10. package/dist/chunk-IZPLHEX4.js +113 -0
  11. package/dist/chunk-OTD7MV33.js +53 -0
  12. package/dist/chunk-PFNP6PEB.js +11 -0
  13. package/dist/{chunk-Y2774T3B.js → chunk-QMATWJ5F.js} +6 -7
  14. package/dist/chunk-U67V476Y.js +35 -0
  15. package/dist/{chunk-BUCUQ3WX.js → chunk-XN2LKXFZ.js} +39 -34
  16. package/dist/{chunk-WFUH5VBX.js → chunk-XOFXGHS4.js} +26 -10
  17. package/dist/chunk-XZSI7AHE.js +67 -0
  18. package/dist/chunk-YVVDKJ2H.js +34 -0
  19. package/dist/chunk-ZMWYLUDP.js +21 -0
  20. package/dist/content/github.d.ts +34 -0
  21. package/dist/content/github.js +43 -0
  22. package/dist/content/index.d.ts +16 -0
  23. package/dist/content/index.js +30 -0
  24. package/dist/{get-toc-Cr2URuiP.d.ts → content/toc.d.ts} +6 -10
  25. package/dist/content/toc.js +21 -0
  26. package/dist/{page-tree-BG3wP0gU.d.ts → definitions-BRsJlZ6m.d.ts} +10 -15
  27. package/dist/dynamic-link.js +3 -3
  28. package/dist/fetch-2XFMBLBA.js +22 -0
  29. package/dist/framework/index.d.ts +1 -1
  30. package/dist/framework/index.js +2 -2
  31. package/dist/framework/next.js +2 -2
  32. package/dist/framework/react-router.js +2 -2
  33. package/dist/framework/tanstack.js +2 -2
  34. package/dist/framework/waku.d.ts +8 -0
  35. package/dist/framework/waku.js +51 -0
  36. package/dist/hide-if-empty.d.ts +18 -0
  37. package/dist/hide-if-empty.js +83 -0
  38. package/dist/highlight/client.d.ts +8 -5
  39. package/dist/highlight/client.js +9 -93
  40. package/dist/highlight/index.d.ts +20 -5
  41. package/dist/highlight/index.js +10 -6
  42. package/dist/i18n/index.d.ts +35 -8
  43. package/dist/i18n/index.js +5 -69
  44. package/dist/i18n/middleware.d.ts +12 -0
  45. package/dist/i18n/middleware.js +63 -0
  46. package/dist/link.js +3 -3
  47. package/dist/mdx-plugins/index.d.ts +124 -18
  48. package/dist/mdx-plugins/index.js +605 -203
  49. package/dist/mixedbread-RAHDVXGJ.js +118 -0
  50. package/dist/negotiation/index.d.ts +19 -0
  51. package/dist/negotiation/index.js +11 -0
  52. package/dist/{orama-cloud-USLSOSXS.js → orama-cloud-WEGQE5A6.js} +37 -27
  53. package/dist/page-tree/index.d.ts +32 -0
  54. package/dist/page-tree/index.js +15 -0
  55. package/dist/remark-code-tab-DmyIyi6m.d.ts +57 -0
  56. package/dist/{remark-structure-FIjTA11P.d.ts → remark-structure-DkCXCzpD.d.ts} +13 -2
  57. package/dist/search/algolia.d.ts +9 -7
  58. package/dist/search/algolia.js +31 -17
  59. package/dist/search/client.d.ts +88 -17
  60. package/dist/search/client.js +71 -50
  61. package/dist/search/index.d.ts +26 -0
  62. package/dist/search/index.js +7 -0
  63. package/dist/search/orama-cloud.d.ts +7 -5
  64. package/dist/search/orama-cloud.js +18 -10
  65. package/dist/search/server.d.ts +33 -25
  66. package/dist/search/server.js +109 -47
  67. package/dist/source/index.d.ts +33 -254
  68. package/dist/source/index.js +532 -353
  69. package/dist/source/plugins/lucide-icons.d.ts +14 -0
  70. package/dist/source/plugins/lucide-icons.js +23 -0
  71. package/dist/static-A2YJ5TXV.js +62 -0
  72. package/dist/toc.d.ts +11 -7
  73. package/dist/toc.js +6 -5
  74. package/dist/utils/use-effect-event.d.ts +4 -3
  75. package/dist/utils/use-effect-event.js +9 -6
  76. package/dist/utils/use-media-query.d.ts +3 -0
  77. package/dist/utils/use-media-query.js +23 -0
  78. package/dist/utils/use-on-change.js +2 -2
  79. package/package.json +92 -40
  80. package/dist/algolia-NTWLS6J3.js +0 -49
  81. package/dist/chunk-KAOEMCTI.js +0 -17
  82. package/dist/chunk-MLKGABMK.js +0 -9
  83. package/dist/chunk-XMCPKVJQ.js +0 -34
  84. package/dist/config-inq6kP6y.d.ts +0 -26
  85. package/dist/fetch-W5EHIBOE.js +0 -21
  86. package/dist/remark-heading-BPCoYwjn.d.ts +0 -31
  87. package/dist/server/index.d.ts +0 -117
  88. package/dist/server/index.js +0 -202
  89. package/dist/sidebar.d.ts +0 -33
  90. package/dist/sidebar.js +0 -89
  91. package/dist/static-VESU2S64.js +0 -61
  92. package/dist/types-Ch8gnVgO.d.ts +0 -8
@@ -0,0 +1,118 @@
1
+ import {
2
+ __commonJS,
3
+ __toESM
4
+ } from "./chunk-U67V476Y.js";
5
+
6
+ // ../../node_modules/.pnpm/remove-markdown@0.6.2/node_modules/remove-markdown/index.js
7
+ var require_remove_markdown = __commonJS({
8
+ "../../node_modules/.pnpm/remove-markdown@0.6.2/node_modules/remove-markdown/index.js"(exports, module) {
9
+ "use strict";
10
+ module.exports = function(md, options) {
11
+ options = options || {};
12
+ options.listUnicodeChar = options.hasOwnProperty("listUnicodeChar") ? options.listUnicodeChar : false;
13
+ options.stripListLeaders = options.hasOwnProperty("stripListLeaders") ? options.stripListLeaders : true;
14
+ options.gfm = options.hasOwnProperty("gfm") ? options.gfm : true;
15
+ options.useImgAltText = options.hasOwnProperty("useImgAltText") ? options.useImgAltText : true;
16
+ options.abbr = options.hasOwnProperty("abbr") ? options.abbr : false;
17
+ options.replaceLinksWithURL = options.hasOwnProperty("replaceLinksWithURL") ? options.replaceLinksWithURL : false;
18
+ options.htmlTagsToSkip = options.hasOwnProperty("htmlTagsToSkip") ? options.htmlTagsToSkip : [];
19
+ options.throwError = options.hasOwnProperty("throwError") ? options.throwError : false;
20
+ var output = md || "";
21
+ output = output.replace(/^ {0,3}((?:-[\t ]*){3,}|(?:_[ \t]*){3,}|(?:\*[ \t]*){3,})(?:\n+|$)/gm, "");
22
+ try {
23
+ if (options.stripListLeaders) {
24
+ if (options.listUnicodeChar)
25
+ output = output.replace(/^([\s\t]*)([\*\-\+]|\d+\.)\s+/gm, options.listUnicodeChar + " $1");
26
+ else
27
+ output = output.replace(/^([\s\t]*)([\*\-\+]|\d+\.)\s+/gm, "$1");
28
+ }
29
+ if (options.gfm) {
30
+ output = output.replace(/\n={2,}/g, "\n").replace(/~{3}.*\n/g, "").replace(/~~/g, "").replace(/```(?:.*)\n([\s\S]*?)```/g, (_, code) => code.trim());
31
+ }
32
+ if (options.abbr) {
33
+ output = output.replace(/\*\[.*\]:.*\n/, "");
34
+ }
35
+ let htmlReplaceRegex = /<[^>]*>/g;
36
+ if (options.htmlTagsToSkip && options.htmlTagsToSkip.length > 0) {
37
+ const joinedHtmlTagsToSkip = options.htmlTagsToSkip.join("|");
38
+ htmlReplaceRegex = new RegExp(
39
+ `<(?!/?(${joinedHtmlTagsToSkip})(?=>|s[^>]*>))[^>]*>`,
40
+ "g"
41
+ );
42
+ }
43
+ output = output.replace(htmlReplaceRegex, "").replace(/^[=\-]{2,}\s*$/g, "").replace(/\[\^.+?\](\: .*?$)?/g, "").replace(/\s{0,2}\[.*?\]: .*?$/g, "").replace(/\!\[(.*?)\][\[\(].*?[\]\)]/g, options.useImgAltText ? "$1" : "").replace(/\[([\s\S]*?)\]\s*[\(\[].*?[\)\]]/g, options.replaceLinksWithURL ? "$2" : "$1").replace(/^(\n)?\s{0,3}>\s?/gm, "$1").replace(/^\s{1,2}\[(.*?)\]: (\S+)( ".*?")?\s*$/g, "").replace(/^(\n)?\s{0,}#{1,6}\s*( (.+))? +#+$|^(\n)?\s{0,}#{1,6}\s*( (.+))?$/gm, "$1$3$4$6").replace(/([\*]+)(\S)(.*?\S)??\1/g, "$2$3").replace(/(^|\W)([_]+)(\S)(.*?\S)??\2($|\W)/g, "$1$3$4$5").replace(/(`{3,})(.*?)\1/gm, "$2").replace(/`(.+?)`/g, "$1").replace(/~(.*?)~/g, "$1");
44
+ } catch (e) {
45
+ if (options.throwError) throw e;
46
+ console.error("remove-markdown encountered error: %s", e);
47
+ return md;
48
+ }
49
+ return output;
50
+ };
51
+ }
52
+ });
53
+
54
+ // src/search/client/mixedbread.ts
55
+ var import_remove_markdown = __toESM(require_remove_markdown(), 1);
56
+ import Slugger from "github-slugger";
57
+ var slugger = new Slugger();
58
+ function extractHeadingTitle(text) {
59
+ const trimmedText = text.trim();
60
+ if (!trimmedText.startsWith("#")) {
61
+ return "";
62
+ }
63
+ const lines = trimmedText.split("\n");
64
+ const firstLine = lines[0]?.trim();
65
+ if (firstLine) {
66
+ const plainText = (0, import_remove_markdown.default)(firstLine, {
67
+ useImgAltText: false
68
+ });
69
+ return plainText;
70
+ }
71
+ return "";
72
+ }
73
+ async function search(query, options) {
74
+ const { client, vectorStoreId, tag } = options;
75
+ if (!query.trim()) {
76
+ return [];
77
+ }
78
+ const res = await client.vectorStores.search({
79
+ query,
80
+ vector_store_identifiers: [vectorStoreId],
81
+ top_k: 10,
82
+ filters: {
83
+ key: "generated_metadata.tag",
84
+ operator: "eq",
85
+ value: tag
86
+ },
87
+ search_options: {
88
+ return_metadata: true
89
+ }
90
+ });
91
+ return res.data.flatMap((item) => {
92
+ const metadata = item.generated_metadata;
93
+ const url = metadata.url || "#";
94
+ const title = metadata.title || "Untitled";
95
+ const chunkResults = [
96
+ {
97
+ id: `${item.file_id}-${item.chunk_index}-page`,
98
+ type: "page",
99
+ content: title,
100
+ url
101
+ }
102
+ ];
103
+ const headingTitle = item.type === "text" ? extractHeadingTitle(item.text) : "";
104
+ if (headingTitle) {
105
+ slugger.reset();
106
+ chunkResults.push({
107
+ id: `${item.file_id}-${item.chunk_index}-heading`,
108
+ type: "heading",
109
+ content: headingTitle,
110
+ url: `${url}#${slugger.slug(headingTitle)}`
111
+ });
112
+ }
113
+ return chunkResults;
114
+ });
115
+ }
116
+ export {
117
+ search
118
+ };
@@ -0,0 +1,19 @@
1
+ import Negotiator from 'negotiator';
2
+
3
+ declare function getNegotiator(request: Request): Negotiator;
4
+ /**
5
+ * Rewrite incoming path matching the `source` pattern into the `destination` pattern.
6
+ *
7
+ * See [`path-to-regexp`](https://github.com/pillarjs/path-to-regexp) for accepted pattern formats.
8
+ *
9
+ * @param source - the original pattern of incoming paths
10
+ * @param destination - the target pattern to convert into
11
+ */
12
+ declare function rewritePath(source: string, destination: string): {
13
+ rewrite(pathname: string): string | false;
14
+ };
15
+ declare function isMarkdownPreferred(request: Request, options?: {
16
+ markdownMediaTypes?: string[];
17
+ }): boolean;
18
+
19
+ export { getNegotiator, isMarkdownPreferred, rewritePath };
@@ -0,0 +1,11 @@
1
+ import {
2
+ getNegotiator,
3
+ isMarkdownPreferred,
4
+ rewritePath
5
+ } from "../chunk-YVVDKJ2H.js";
6
+ import "../chunk-U67V476Y.js";
7
+ export {
8
+ getNegotiator,
9
+ isMarkdownPreferred,
10
+ rewritePath
11
+ };
@@ -1,57 +1,64 @@
1
1
  import {
2
2
  removeUndefined
3
- } from "./chunk-KAOEMCTI.js";
4
- import "./chunk-MLKGABMK.js";
3
+ } from "./chunk-ZMWYLUDP.js";
4
+ import {
5
+ createContentHighlighter
6
+ } from "./chunk-OTD7MV33.js";
7
+ import "./chunk-U67V476Y.js";
5
8
 
6
9
  // src/search/client/orama-cloud.ts
7
- async function searchDocs(query, tag, options) {
10
+ async function searchDocs(query, options) {
11
+ const highlighter = createContentHighlighter(query);
8
12
  const list = [];
9
- const { index = "default", client, params: extraParams = {} } = options;
13
+ const { index = "default", client, params: extraParams, tag } = options;
10
14
  if (index === "crawler") {
11
15
  const result2 = await client.search({
16
+ datasources: [],
12
17
  ...extraParams,
13
18
  term: query,
14
19
  where: {
15
20
  category: tag ? {
16
21
  eq: tag.slice(0, 1).toUpperCase() + tag.slice(1)
17
22
  } : void 0,
18
- ...extraParams.where
23
+ ...extraParams?.where
19
24
  },
20
25
  limit: 10
21
26
  });
22
27
  if (!result2) return list;
23
- if (index === "crawler") {
24
- for (const hit of result2.hits) {
25
- const doc = hit.document;
26
- list.push(
27
- {
28
- id: hit.id,
29
- type: "page",
30
- content: doc.title,
31
- url: doc.path
32
- },
33
- {
34
- id: "page" + hit.id,
35
- type: "text",
36
- content: doc.content,
37
- url: doc.path
38
- }
39
- );
40
- }
41
- return list;
28
+ for (const hit of result2.hits) {
29
+ const doc = hit.document;
30
+ list.push(
31
+ {
32
+ id: hit.id,
33
+ type: "page",
34
+ content: doc.title,
35
+ contentWithHighlights: highlighter.highlight(doc.title),
36
+ url: doc.path
37
+ },
38
+ {
39
+ id: "page" + hit.id,
40
+ type: "text",
41
+ content: doc.content,
42
+ contentWithHighlights: highlighter.highlight(doc.content),
43
+ url: doc.path
44
+ }
45
+ );
42
46
  }
47
+ return list;
43
48
  }
44
49
  const params = {
50
+ datasources: [],
45
51
  ...extraParams,
46
52
  term: query,
47
53
  where: removeUndefined({
48
54
  tag,
49
- ...extraParams.where
55
+ ...extraParams?.where
50
56
  }),
51
57
  groupBy: {
58
+ // TODO: this was causing error on number of group variants
52
59
  properties: ["page_id"],
53
- maxResult: 7,
54
- ...extraParams.groupBy
60
+ max_results: 7,
61
+ ...extraParams?.groupBy
55
62
  }
56
63
  };
57
64
  const result = await client.search(params);
@@ -65,6 +72,8 @@ async function searchDocs(query, tag, options) {
65
72
  id: doc.page_id,
66
73
  type: "page",
67
74
  content: doc.title,
75
+ breadcrumbs: doc.breadcrumbs,
76
+ contentWithHighlights: highlighter.highlight(doc.title),
68
77
  url: doc.url
69
78
  });
70
79
  addedHead = true;
@@ -72,6 +81,7 @@ async function searchDocs(query, tag, options) {
72
81
  list.push({
73
82
  id: doc.id,
74
83
  content: doc.content,
84
+ contentWithHighlights: highlighter.highlight(doc.content),
75
85
  type: doc.content === doc.section ? "heading" : "text",
76
86
  url: doc.section_id ? `${doc.url}#${doc.section_id}` : doc.url
77
87
  });
@@ -0,0 +1,32 @@
1
+ import { N as Node, I as Item, R as Root, F as Folder } from '../definitions-BRsJlZ6m.js';
2
+ export { S as Separator } from '../definitions-BRsJlZ6m.js';
3
+ import 'react';
4
+
5
+ /**
6
+ * Flatten tree to an array of page nodes
7
+ */
8
+ declare function flattenTree(nodes: Node[]): Item[];
9
+ /**
10
+ * Get neighbours of a page, useful for implementing "previous & next" buttons
11
+ */
12
+ declare function findNeighbour(tree: Root, url: string, options?: {
13
+ separateRoot?: boolean;
14
+ }): {
15
+ previous?: Item;
16
+ next?: Item;
17
+ };
18
+ declare function getPageTreeRoots(pageTree: Root | Folder): (Root | Folder)[];
19
+ /**
20
+ * Get other page tree nodes that lives under the same parent
21
+ */
22
+ declare function getPageTreePeers(treeOrTrees: Root | Record<string, Root>, url: string): Item[];
23
+ /**
24
+ * Search the path of a node in the tree matched by the matcher.
25
+ *
26
+ * @returns The path to the target node (from starting root), or null if the page doesn't exist
27
+ */
28
+ declare function findPath(nodes: Node[], matcher: (node: Node) => boolean, options?: {
29
+ includeSeparator?: boolean;
30
+ }): Node[] | null;
31
+
32
+ export { Folder, Item, Node, Root, findNeighbour, findPath, flattenTree, getPageTreePeers, getPageTreeRoots };
@@ -0,0 +1,15 @@
1
+ import {
2
+ findNeighbour,
3
+ findPath,
4
+ flattenTree,
5
+ getPageTreePeers,
6
+ getPageTreeRoots
7
+ } from "../chunk-IZPLHEX4.js";
8
+ import "../chunk-U67V476Y.js";
9
+ export {
10
+ findNeighbour,
11
+ findPath,
12
+ flattenTree,
13
+ getPageTreePeers,
14
+ getPageTreeRoots
15
+ };
@@ -0,0 +1,57 @@
1
+ import { Root, Heading, Code } from 'mdast';
2
+ import { Transformer, Processor } from 'unified';
3
+ import { MdxJsxFlowElement } from 'mdast-util-mdx-jsx';
4
+
5
+ declare module 'mdast' {
6
+ interface HeadingData extends Data {
7
+ hProperties?: {
8
+ id?: string;
9
+ };
10
+ }
11
+ }
12
+ interface RemarkHeadingOptions {
13
+ slug?: (root: Root, heading: Heading, text: string) => string;
14
+ /**
15
+ * Allow custom headings ids
16
+ *
17
+ * @defaultValue true
18
+ */
19
+ customId?: boolean;
20
+ /**
21
+ * Attach an array of `TOCItemType` to `file.data.toc`
22
+ *
23
+ * @defaultValue true
24
+ */
25
+ generateToc?: boolean;
26
+ }
27
+ /**
28
+ * Add heading ids and extract TOC
29
+ */
30
+ declare function remarkHeading({ slug: defaultSlug, customId, generateToc, }?: RemarkHeadingOptions): Transformer<Root, Root>;
31
+
32
+ type TabType = keyof typeof Types;
33
+ interface RemarkCodeTabOptions {
34
+ Tabs?: TabType;
35
+ /**
36
+ * Parse MDX in tab values
37
+ *
38
+ * @defaultValue false
39
+ */
40
+ parseMdx?: boolean;
41
+ }
42
+ declare module 'mdast' {
43
+ interface CodeData {
44
+ tab?: string;
45
+ }
46
+ }
47
+ declare const Types: {
48
+ CodeBlockTabs: {
49
+ convert(processor: Processor, nodes: Code[], withMdx?: boolean, withParent?: boolean): MdxJsxFlowElement;
50
+ };
51
+ Tabs: {
52
+ convert(processor: Processor, nodes: Code[], withMdx?: boolean, withParent?: boolean): MdxJsxFlowElement;
53
+ };
54
+ };
55
+ declare function remarkCodeTab(this: Processor, options?: RemarkCodeTabOptions): Transformer<Root, Root>;
56
+
57
+ export { type RemarkHeadingOptions as R, type RemarkCodeTabOptions as a, remarkCodeTab as b, remarkHeading as r };
@@ -1,6 +1,6 @@
1
1
  import { Nodes, Root } from 'mdast';
2
2
  import { Transformer, PluggableList } from 'unified';
3
- import { MdxJsxAttribute, MdxJsxExpressionAttribute } from 'mdast-util-mdx-jsx';
3
+ import { MdxJsxFlowElement, MdxJsxAttribute, MdxJsxExpressionAttribute } from 'mdast-util-mdx-jsx';
4
4
 
5
5
  interface Heading {
6
6
  id: string;
@@ -24,7 +24,13 @@ interface StructureOptions {
24
24
  * @defaultValue ['heading', 'paragraph', 'blockquote', 'tableCell', 'mdxJsxFlowElement']
25
25
  */
26
26
  types?: string[] | ((node: Nodes) => boolean);
27
- allowedMdxAttributes?: string[] | ((node: Nodes, attribute: MdxJsxAttribute | MdxJsxExpressionAttribute) => boolean);
27
+ /**
28
+ * A list of indexable MDX attributes, either:
29
+ *
30
+ * - an array of attribute names.
31
+ * - a function that determines if attribute should be indexed.
32
+ */
33
+ allowedMdxAttributes?: string[] | ((node: MdxJsxFlowElement, attribute: MdxJsxAttribute | MdxJsxExpressionAttribute) => boolean);
28
34
  }
29
35
  declare module 'mdast' {
30
36
  interface Data {
@@ -36,6 +42,11 @@ declare module 'mdast' {
36
42
  _string?: string[];
37
43
  }
38
44
  }
45
+ declare module 'vfile' {
46
+ interface DataMap {
47
+ structuredData: StructuredData;
48
+ }
49
+ }
39
50
  /**
40
51
  * Attach structured data to VFile, you can access via `vfile.data.structuredData`.
41
52
  */
@@ -1,5 +1,5 @@
1
- import { SearchClient, SearchIndex } from 'algoliasearch';
2
- import { S as StructuredData } from '../remark-structure-FIjTA11P.js';
1
+ import { Algoliasearch } from 'algoliasearch';
2
+ import { S as StructuredData } from '../remark-structure-DkCXCzpD.js';
3
3
  import 'mdast';
4
4
  import 'unified';
5
5
  import 'mdast-util-mdx-jsx';
@@ -11,6 +11,7 @@ interface DocumentRecord {
11
11
  _id: string;
12
12
  title: string;
13
13
  description?: string;
14
+ breadcrumbs?: string[];
14
15
  /**
15
16
  * URL to the page
16
17
  */
@@ -27,9 +28,9 @@ interface DocumentRecord {
27
28
  }
28
29
  interface SyncOptions {
29
30
  /**
30
- * Index Name for documents
31
+ * Index Name for documents.
31
32
  */
32
- document?: string;
33
+ indexName?: string;
33
34
  /**
34
35
  * Search indexes
35
36
  */
@@ -41,9 +42,9 @@ interface SyncOptions {
41
42
  * @param client - Algolia Admin Client
42
43
  * @param options - Index Options
43
44
  */
44
- declare function sync(client: SearchClient, options: SyncOptions): Promise<void>;
45
- declare function setIndexSettings(index: SearchIndex): Promise<void>;
46
- declare function updateDocuments(index: SearchIndex, documents: DocumentRecord[]): Promise<void>;
45
+ declare function sync(client: Algoliasearch, options: SyncOptions): Promise<void>;
46
+ declare function setIndexSettings(client: Algoliasearch, indexName: string): Promise<void>;
47
+ declare function updateDocuments(client: Algoliasearch, indexName: string, documents: DocumentRecord[]): Promise<void>;
47
48
  interface BaseIndex {
48
49
  objectID: string;
49
50
  title: string;
@@ -61,6 +62,7 @@ interface BaseIndex {
61
62
  * Heading (anchor) id
62
63
  */
63
64
  section_id?: string;
65
+ breadcrumbs?: string[];
64
66
  content: string;
65
67
  }
66
68
 
@@ -1,19 +1,28 @@
1
- import "../chunk-MLKGABMK.js";
1
+ import "../chunk-U67V476Y.js";
2
2
 
3
3
  // src/search/algolia.ts
4
4
  async function sync(client, options) {
5
- const { document = "document", documents } = options;
6
- const index = client.initIndex(document);
7
- await setIndexSettings(index);
8
- await updateDocuments(index, documents);
5
+ const { indexName = "document", documents } = options;
6
+ await setIndexSettings(client, indexName);
7
+ await updateDocuments(client, indexName, documents);
9
8
  }
10
- async function setIndexSettings(index) {
11
- await index.setSettings({
12
- attributeForDistinct: "page_id",
13
- attributesToRetrieve: ["title", "section", "content", "url", "section_id"],
14
- searchableAttributes: ["title", "section", "content"],
15
- attributesToSnippet: [],
16
- attributesForFaceting: ["tag"]
9
+ async function setIndexSettings(client, indexName) {
10
+ await client.setSettings({
11
+ indexName,
12
+ indexSettings: {
13
+ attributeForDistinct: "page_id",
14
+ attributesToRetrieve: [
15
+ "title",
16
+ "section",
17
+ "content",
18
+ "url",
19
+ "section_id",
20
+ "breadcrumbs"
21
+ ],
22
+ searchableAttributes: ["title", "section", "content"],
23
+ attributesToSnippet: [],
24
+ attributesForFaceting: ["tag"]
25
+ }
17
26
  });
18
27
  }
19
28
  function toIndex(page) {
@@ -23,6 +32,7 @@ function toIndex(page) {
23
32
  function createIndex(section, sectionId, content) {
24
33
  return {
25
34
  objectID: `${page._id}-${(id++).toString()}`,
35
+ breadcrumbs: page.breadcrumbs,
26
36
  title: page.title,
27
37
  url: page.url,
28
38
  page_id: page._id,
@@ -35,20 +45,24 @@ function toIndex(page) {
35
45
  }
36
46
  if (page.description)
37
47
  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;
48
+ const { headings, contents } = page.structured;
49
+ for (const p of contents) {
50
+ const heading = p.heading ? headings.find((h) => p.heading === h.id) : null;
40
51
  const index = createIndex(heading?.content, heading?.id, p.content);
41
52
  if (heading && !scannedHeadings.has(heading.id)) {
42
53
  scannedHeadings.add(heading.id);
43
54
  indexes.push(createIndex(heading.content, heading.id, heading.content));
44
55
  }
45
56
  indexes.push(index);
46
- });
57
+ }
47
58
  return indexes;
48
59
  }
49
- async function updateDocuments(index, documents) {
60
+ async function updateDocuments(client, indexName, documents) {
50
61
  const objects = documents.flatMap(toIndex);
51
- await index.replaceAllObjects(objects);
62
+ await client.replaceAllObjects({
63
+ indexName,
64
+ objects
65
+ });
52
66
  }
53
67
  export {
54
68
  setIndexSettings,
@@ -1,41 +1,100 @@
1
- import { S as SortedResult } from '../types-Ch8gnVgO.js';
2
1
  import { AnyOrama } from '@orama/orama';
3
- import { SearchOptions } from '@algolia/client-search';
4
- import { SearchIndex } from 'algoliasearch/lite';
5
- import '../remark-structure-FIjTA11P.js';
6
- import { OramaClient, ClientSearchParams } from '@oramacloud/client';
2
+ import '../remark-structure-DkCXCzpD.js';
3
+ import { BaseIndex } from './algolia.js';
4
+ import { LiteClient, SearchResponse } from 'algoliasearch/lite';
5
+ import { OramaCloud, OramaCloudSearchParams } from '@orama/core';
6
+ import Mixedbread from '@mixedbread/sdk';
7
+ import { SortedResult } from './index.js';
7
8
  import 'mdast';
8
9
  import 'unified';
9
10
  import 'mdast-util-mdx-jsx';
11
+ import 'algoliasearch';
12
+ import 'react';
10
13
 
11
14
  interface FetchOptions {
12
15
  /**
13
16
  * API route for search endpoint
17
+ *
18
+ * @defaultValue '/api/search'
14
19
  */
15
20
  api?: string;
21
+ /**
22
+ * Filter results with specific tag(s).
23
+ */
24
+ tag?: string | string[];
25
+ /**
26
+ * Filter by locale
27
+ */
28
+ locale?: string;
16
29
  }
17
30
 
18
31
  interface StaticOptions {
19
32
  /**
20
33
  * Where to download exported search indexes (URL)
34
+ *
35
+ * @defaultValue '/api/search'
21
36
  */
22
37
  from?: string;
23
38
  initOrama?: (locale?: string) => AnyOrama | Promise<AnyOrama>;
39
+ /**
40
+ * Filter results with specific tag(s).
41
+ */
42
+ tag?: string | string[];
43
+ /**
44
+ * Filter by locale (unsupported at the moment)
45
+ */
46
+ locale?: string;
24
47
  }
25
48
 
26
- interface AlgoliaOptions extends SearchOptions {
27
- index: SearchIndex;
49
+ interface AlgoliaOptions {
50
+ indexName: string;
51
+ client: LiteClient;
52
+ /**
53
+ * Filter results with specific tag.
54
+ */
55
+ tag?: string;
56
+ locale?: string;
57
+ onSearch?: (query: string, tag?: string, locale?: string) => Promise<{
58
+ results: SearchResponse<BaseIndex>[];
59
+ }>;
28
60
  }
29
61
 
30
62
  interface OramaCloudOptions {
31
- client: OramaClient;
63
+ client: OramaCloud;
32
64
  /**
33
65
  * The type of your index.
34
66
  *
35
67
  * You can set it to `crawler` if you use crawler instead of the JSON index with schema provided by Fumadocs
36
68
  */
37
69
  index?: 'default' | 'crawler';
38
- params?: ClientSearchParams;
70
+ params?: Partial<OramaCloudSearchParams>;
71
+ /**
72
+ * Filter results with specific tag.
73
+ */
74
+ tag?: string;
75
+ /**
76
+ * Filter by locale (unsupported at the moment)
77
+ */
78
+ locale?: string;
79
+ }
80
+
81
+ interface MixedbreadOptions {
82
+ /**
83
+ * The ID of the vector store to search in
84
+ */
85
+ vectorStoreId: string;
86
+ /**
87
+ * The Mixedbread SDK client instance
88
+ */
89
+ client: Mixedbread;
90
+ /**
91
+ * Filter results with specific tag.
92
+ */
93
+ tag?: string;
94
+ /**
95
+ * Filter by locale (unsupported at the moment)
96
+ */
97
+ locale?: string;
39
98
  }
40
99
 
41
100
  interface UseDocsSearch {
@@ -55,15 +114,27 @@ type Client = ({
55
114
  type: 'algolia';
56
115
  } & AlgoliaOptions) | ({
57
116
  type: 'orama-cloud';
58
- } & OramaCloudOptions);
117
+ } & OramaCloudOptions) | ({
118
+ type: 'mixedbread';
119
+ } & MixedbreadOptions);
59
120
  /**
60
- * @param client - search client
61
- * @param locale - Filter with locale
62
- * @param tag - Filter with specific tag
63
- * @param delayMs - The debounced delay for performing a search.
64
- * @param allowEmpty - still perform search even if query is empty
65
- * @param key - cache key
121
+ * Provide a hook to query different official search clients.
122
+ *
123
+ * Note: it will re-query when its parameters changed, make sure to use `useCallback()` on functions passed to this hook.
66
124
  */
67
- declare function useDocsSearch(client: Client, locale?: string, tag?: string, delayMs?: number, allowEmpty?: boolean, key?: string): UseDocsSearch;
125
+ declare function useDocsSearch(clientOptions: Client & {
126
+ /**
127
+ * The debounced delay for performing a search (in ms).
128
+ * .
129
+ * @defaultValue 100
130
+ */
131
+ delayMs?: number;
132
+ /**
133
+ * still perform search even if query is empty.
134
+ *
135
+ * @defaultValue false
136
+ */
137
+ allowEmpty?: boolean;
138
+ }): UseDocsSearch;
68
139
 
69
140
  export { type AlgoliaOptions, type Client, type FetchOptions, type OramaCloudOptions, type StaticOptions, useDocsSearch };