fumadocs-core 15.0.13 → 15.0.15

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.
@@ -4,6 +4,13 @@ function isDifferent(a, b) {
4
4
  if (Array.isArray(a) && Array.isArray(b)) {
5
5
  return b.length !== a.length || a.some((v, i) => isDifferent(v, b[i]));
6
6
  }
7
+ if (typeof a === "object" && a && typeof b === "object" && b) {
8
+ const aKeys = Object.keys(a);
9
+ const bKeys = Object.keys(b);
10
+ return aKeys.length !== bKeys.length || aKeys.some(
11
+ (key) => isDifferent(a[key], b[key])
12
+ );
13
+ }
7
14
  return a !== b;
8
15
  }
9
16
  function useOnChange(value, onChange, isUpdated = isDifferent) {
@@ -1,16 +1,20 @@
1
1
  import "./chunk-MLKGABMK.js";
2
2
 
3
3
  // src/search/client/fetch.ts
4
+ var cache = /* @__PURE__ */ new Map();
4
5
  async function fetchDocs(query, locale, tag, options) {
5
6
  const params = new URLSearchParams();
6
7
  params.set("query", query);
7
8
  if (locale) params.set("locale", locale);
8
9
  if (tag) params.set("tag", tag);
9
- const res = await fetch(
10
- `${options.api ?? "/api/search"}?${params.toString()}`
11
- );
10
+ const key = `${options.api ?? "/api/search"}?${params}`;
11
+ const cached = cache.get(key);
12
+ if (cached) return cached;
13
+ const res = await fetch(key);
12
14
  if (!res.ok) throw new Error(await res.text());
13
- return await res.json();
15
+ const result = await res.json();
16
+ cache.set(key, result);
17
+ return result;
14
18
  }
15
19
  export {
16
20
  fetchDocs
@@ -4,9 +4,8 @@ import { RehypeShikiOptions } from '@shikijs/rehype';
4
4
  import { Processor, Transformer } from 'unified';
5
5
  import { ShikiTransformer } from 'shiki';
6
6
  import { Root as Root$1 } from 'mdast';
7
- export { a as StructureOptions, S as StructuredData, r as remarkStructure, s as structure } from '../remark-structure-mP51W1AN.js';
7
+ export { a as StructureOptions, S as StructuredData, r as remarkStructure, s as structure } from '../remark-structure-1kvQbrfH.js';
8
8
  export { R as RemarkHeadingOptions, r as remarkHeading } from '../remark-heading-BPCoYwjn.js';
9
- import 'unist-util-visit';
10
9
 
11
10
  interface CodeBlockIcon {
12
11
  viewBox: string;
@@ -292,7 +292,8 @@ function transformerTab() {
292
292
  // src/mdx-plugins/remark-image.ts
293
293
  import * as path from "node:path";
294
294
  import { visit } from "unist-util-visit";
295
- import sizeOf from "image-size";
295
+ import { imageSize } from "image-size";
296
+ import { imageSizeFromFile } from "image-size/fromFile";
296
297
  var VALID_BLUR_EXT = [".jpeg", ".png", ".webp", ".avif", ".jpg"];
297
298
  var EXTERNAL_URL_REGEX = /^https?:\/\//;
298
299
  function remarkImage({
@@ -346,10 +347,11 @@ function remarkImage({
346
347
  }
347
348
  ]
348
349
  });
349
- }).catch(() => {
350
+ }).catch((e) => {
350
351
  console.error(
351
352
  `[Remark Image] Failed obtain image size for ${url} with public directory ${publicDir}`
352
353
  );
354
+ throw e;
353
355
  });
354
356
  promises.push(task);
355
357
  } else if (!isExternal) {
@@ -431,10 +433,10 @@ async function getImageSize(src, dir) {
431
433
  base.pathname = resolvePath(base.pathname, src);
432
434
  url = base.toString();
433
435
  } else {
434
- return sizeOf(isRelative ? path.join(dir, src) : src);
436
+ return imageSizeFromFile(isRelative ? path.join(dir, src) : src);
435
437
  }
436
438
  const buffer = await fetch(url).then((res) => res.arrayBuffer());
437
- return sizeOf(new Uint8Array(buffer));
439
+ return imageSize(new Uint8Array(buffer));
438
440
  }
439
441
 
440
442
  // src/mdx-plugins/remark-structure.ts
@@ -457,13 +459,13 @@ function remarkStructure({
457
459
  data.contents.push(...frontmatter._openapi.structuredData.contents);
458
460
  }
459
461
  }
460
- visit2(node, types, (element) => {
462
+ visit2(node, (element) => {
461
463
  if (element.type === "root") return;
462
- const content = flattenNode(element).trim();
463
464
  if (element.type === "heading") {
464
465
  element.data ||= {};
465
466
  element.data.hProperties ||= {};
466
467
  const properties = element.data.hProperties;
468
+ const content = flattenNode(element).trim();
467
469
  const id = properties.id ?? slugger.slug(content);
468
470
  data.headings.push({
469
471
  id,
@@ -472,7 +474,18 @@ function remarkStructure({
472
474
  lastHeading = id;
473
475
  return "skip";
474
476
  }
475
- if (content.length > 0) {
477
+ if (element.data?._string) {
478
+ for (const content of element.data._string) {
479
+ data.contents.push({
480
+ heading: lastHeading,
481
+ content
482
+ });
483
+ }
484
+ return "skip";
485
+ }
486
+ if (types.includes(element.type)) {
487
+ const content = flattenNode(element).trim();
488
+ if (content.length === 0) return;
476
489
  data.contents.push({
477
490
  heading: lastHeading,
478
491
  content
@@ -1,6 +1,5 @@
1
1
  import { Root } from 'mdast';
2
2
  import { Transformer, PluggableList } from 'unified';
3
- import { Test } from 'unist-util-visit';
4
3
 
5
4
  interface Heading {
6
5
  id: string;
@@ -19,11 +18,21 @@ interface StructuredData {
19
18
  }
20
19
  interface StructureOptions {
21
20
  /**
22
- * Types to be scanned.
21
+ * Types to be scanned as content.
23
22
  *
24
- * @defaultValue ['paragraph', 'blockquote', 'heading', 'tableCell']
23
+ * @defaultValue ['paragraph', 'blockquote', 'tableCell']
25
24
  */
26
- types?: Test;
25
+ types?: string[];
26
+ }
27
+ declare module 'mdast' {
28
+ interface Data {
29
+ /**
30
+ * Get content of unserializable element
31
+ *
32
+ * Needed for `remarkStructure` to generate search index
33
+ */
34
+ _string?: string[];
35
+ }
27
36
  }
28
37
  /**
29
38
  * Attach structured data to VFile, you can access via `vfile.data.structuredData`.
@@ -1,8 +1,7 @@
1
1
  import { SearchClient, SearchIndex } from 'algoliasearch';
2
- import { S as StructuredData } from '../remark-structure-mP51W1AN.js';
2
+ import { S as StructuredData } from '../remark-structure-1kvQbrfH.js';
3
3
  import 'mdast';
4
4
  import 'unified';
5
- import 'unist-util-visit';
6
5
 
7
6
  interface DocumentRecord {
8
7
  /**
@@ -1,8 +1,11 @@
1
1
  import { S as SortedResult } from '../types-Ch8gnVgO.js';
2
- import { Orama } from '@orama/orama';
2
+ import { AnyOrama } from '@orama/orama';
3
3
  import { SearchOptions } from '@algolia/client-search';
4
4
  import { SearchIndex } from 'algoliasearch/lite';
5
+ import '../remark-structure-1kvQbrfH.js';
5
6
  import { OramaClient, ClientSearchParams } from '@oramacloud/client';
7
+ import 'mdast';
8
+ import 'unified';
6
9
 
7
10
  interface FetchOptions {
8
11
  /**
@@ -16,7 +19,7 @@ interface StaticOptions {
16
19
  * Where to download exported search indexes (URL)
17
20
  */
18
21
  from?: string;
19
- initOrama?: (locale?: string) => Promise<Orama<unknown, never, never, never>>;
22
+ initOrama?: (locale?: string) => AnyOrama | Promise<AnyOrama>;
20
23
  }
21
24
 
22
25
  interface AlgoliaOptions extends SearchOptions {
@@ -1,10 +1,10 @@
1
1
  import {
2
2
  useOnChange
3
- } from "../chunk-EMWGTXSW.js";
3
+ } from "../chunk-ORHEEQVY.js";
4
4
  import "../chunk-MLKGABMK.js";
5
5
 
6
6
  // src/search/client.ts
7
- import { useMemo, useRef as useRef2, useState as useState2 } from "react";
7
+ import { useRef as useRef2, useState as useState2 } from "react";
8
8
 
9
9
  // src/utils/use-debounce.ts
10
10
  import { useRef, useState } from "react";
@@ -23,7 +23,6 @@ function useDebounce(value, delayMs = 1e3) {
23
23
  }
24
24
 
25
25
  // src/search/client.ts
26
- var cache = /* @__PURE__ */ new Map();
27
26
  var staticClient;
28
27
  function useDocsSearch(client, locale, tag, delayMs = 100, allowEmpty = false, key) {
29
28
  const [search, setSearch] = useState2("");
@@ -32,21 +31,11 @@ function useDocsSearch(client, locale, tag, delayMs = 100, allowEmpty = false, k
32
31
  const [isLoading, setIsLoading] = useState2(false);
33
32
  const debouncedValue = useDebounce(search, delayMs);
34
33
  const onStart = useRef2(void 0);
35
- const cacheKey = useMemo(() => {
36
- return key ?? JSON.stringify([client.type, debouncedValue, locale, tag]);
37
- }, [client.type, debouncedValue, locale, tag, key]);
38
- useOnChange(cacheKey, () => {
39
- const cached = cache.get(cacheKey);
34
+ useOnChange(key ?? [client, debouncedValue, locale, tag], () => {
40
35
  if (onStart.current) {
41
36
  onStart.current();
42
37
  onStart.current = void 0;
43
38
  }
44
- if (cached) {
45
- setIsLoading(false);
46
- setError(void 0);
47
- setResults(cached);
48
- return;
49
- }
50
39
  setIsLoading(true);
51
40
  let interrupt = false;
52
41
  onStart.current = () => {
@@ -55,7 +44,7 @@ function useDocsSearch(client, locale, tag, delayMs = 100, allowEmpty = false, k
55
44
  async function run() {
56
45
  if (debouncedValue.length === 0 && !allowEmpty) return "empty";
57
46
  if (client.type === "fetch") {
58
- const { fetchDocs } = await import("../fetch-4K7QOPFM.js");
47
+ const { fetchDocs } = await import("../fetch-W5EHIBOE.js");
59
48
  return fetchDocs(debouncedValue, locale, tag, client);
60
49
  }
61
50
  if (client.type === "algolia") {
@@ -67,12 +56,11 @@ function useDocsSearch(client, locale, tag, delayMs = 100, allowEmpty = false, k
67
56
  const { searchDocs } = await import("../orama-cloud-NHMXDFR2.js");
68
57
  return searchDocs(debouncedValue, tag, client);
69
58
  }
70
- const { createStaticClient } = await import("../static-JUVZRRCD.js");
59
+ const { createStaticClient } = await import("../static-VESU2S64.js");
71
60
  if (!staticClient) staticClient = createStaticClient(client);
72
61
  return staticClient.search(debouncedValue, locale, tag);
73
62
  }
74
63
  void run().then((res) => {
75
- cache.set(cacheKey, res);
76
64
  if (interrupt) return;
77
65
  setError(void 0);
78
66
  setResults(res);
@@ -1,9 +1,8 @@
1
1
  import { CloudManager } from '@oramacloud/client';
2
- import { S as StructuredData } from '../remark-structure-mP51W1AN.js';
2
+ import { S as StructuredData } from '../remark-structure-1kvQbrfH.js';
3
3
  import '../remark-heading-BPCoYwjn.js';
4
4
  import 'mdast';
5
5
  import 'unified';
6
- import 'unist-util-visit';
7
6
 
8
7
  interface SyncOptions {
9
8
  /**
@@ -1,12 +1,11 @@
1
1
  import { TypedDocument, Orama, Language, RawData, create, SearchParams } from '@orama/orama';
2
2
  import { NextRequest } from 'next/server';
3
- import { S as StructuredData } from '../remark-structure-mP51W1AN.js';
3
+ import { S as StructuredData } from '../remark-structure-1kvQbrfH.js';
4
4
  import { S as SortedResult } from '../types-Ch8gnVgO.js';
5
5
  import { I as I18nConfig } from '../config-inq6kP6y.js';
6
6
  import { LoaderOutput, LoaderConfig, InferPageType } from '../source/index.js';
7
7
  import 'mdast';
8
8
  import 'unified';
9
- import 'unist-util-visit';
10
9
  import 'react';
11
10
  import '../page-tree-CfT5zlWh.js';
12
11
 
@@ -51,7 +51,7 @@ async function createDB({
51
51
  ...rest
52
52
  }) {
53
53
  const items = typeof indexes === "function" ? await indexes() : indexes;
54
- const db = await create({
54
+ const db = create({
55
55
  schema: advancedSchema,
56
56
  ...rest,
57
57
  components: {
@@ -119,7 +119,7 @@ async function createDBSimple({
119
119
  ...rest
120
120
  }) {
121
121
  const items = typeof indexes === "function" ? await indexes() : indexes;
122
- const db = await create({
122
+ const db = create({
123
123
  schema: simpleSchema,
124
124
  ...rest,
125
125
  components: {
@@ -184,6 +184,7 @@ var STEMMERS = {
184
184
  arabic: "ar",
185
185
  armenian: "am",
186
186
  bulgarian: "bg",
187
+ czech: "cz",
187
188
  danish: "dk",
188
189
  dutch: "nl",
189
190
  english: "en",
@@ -303,7 +304,7 @@ function initSimpleSearch(options) {
303
304
  async export() {
304
305
  return {
305
306
  type: "simple",
306
- ...await save(await doc)
307
+ ...save(await doc)
307
308
  };
308
309
  },
309
310
  async search(query) {
@@ -318,7 +319,7 @@ function initAdvancedSearch(options) {
318
319
  async export() {
319
320
  return {
320
321
  type: "advanced",
321
- ...await save(await get)
322
+ ...save(await get)
322
323
  };
323
324
  },
324
325
  async search(query, searchOptions) {
@@ -22,7 +22,7 @@ function createStaticClient({
22
22
  if (data.type === "i18n") {
23
23
  for (const [k, v] of Object.entries(data.data)) {
24
24
  const db = await initOrama(k);
25
- await load(db, v);
25
+ load(db, v);
26
26
  dbs.set(k, {
27
27
  type: v.type,
28
28
  db
@@ -30,7 +30,7 @@ function createStaticClient({
30
30
  }
31
31
  } else {
32
32
  const db = await initOrama();
33
- await load(db, data);
33
+ load(db, data);
34
34
  dbs.set("", {
35
35
  type: data.type,
36
36
  db
package/dist/toc.js CHANGED
@@ -1,7 +1,7 @@
1
1
  "use client";
2
2
  import {
3
3
  useOnChange
4
- } from "./chunk-EMWGTXSW.js";
4
+ } from "./chunk-ORHEEQVY.js";
5
5
  import "./chunk-MLKGABMK.js";
6
6
 
7
7
  // src/toc.tsx
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  useOnChange
3
- } from "../chunk-EMWGTXSW.js";
3
+ } from "../chunk-ORHEEQVY.js";
4
4
  import "../chunk-MLKGABMK.js";
5
5
  export {
6
6
  useOnChange
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "fumadocs-core",
3
- "version": "15.0.13",
3
+ "version": "15.0.15",
4
4
  "description": "The library for building a documentation website in Next.js",
5
5
  "keywords": [
6
6
  "NextJs",
@@ -90,47 +90,45 @@
90
90
  ],
91
91
  "dependencies": {
92
92
  "@formatjs/intl-localematcher": "^0.6.0",
93
- "@orama/orama": "^2.1.1",
94
- "@shikijs/rehype": "^3.0.0",
95
- "@shikijs/transformers": "^3.0.0",
93
+ "@orama/orama": "^3.1.1",
94
+ "@shikijs/rehype": "^3.1.0",
95
+ "@shikijs/transformers": "^3.1.0",
96
96
  "github-slugger": "^2.0.0",
97
97
  "hast-util-to-estree": "^3.1.2",
98
- "hast-util-to-jsx-runtime": "^2.3.3",
99
- "image-size": "^1.2.0",
98
+ "hast-util-to-jsx-runtime": "^2.3.5",
99
+ "image-size": "^2.0.0",
100
100
  "negotiator": "^1.0.0",
101
101
  "react-remove-scroll": "^2.6.3",
102
102
  "remark": "^15.0.0",
103
103
  "remark-gfm": "^4.0.1",
104
104
  "scroll-into-view-if-needed": "^3.1.0",
105
- "shiki": "^3.0.0",
105
+ "shiki": "^3.1.0",
106
106
  "unist-util-visit": "^5.0.0"
107
107
  },
108
108
  "devDependencies": {
109
109
  "@algolia/client-search": "4.24.0",
110
110
  "@mdx-js/mdx": "^3.1.0",
111
- "@orama/tokenizers": "^2.1.1",
112
111
  "@oramacloud/client": "^2.1.4",
113
112
  "@types/estree-jsx": "^1.0.5",
114
113
  "@types/hast": "^3.0.4",
115
114
  "@types/mdast": "^4.0.3",
116
115
  "@types/negotiator": "^0.6.3",
117
- "@types/node": "22.13.4",
116
+ "@types/node": "22.13.8",
118
117
  "@types/react": "^19.0.10",
119
118
  "@types/react-dom": "^19.0.4",
120
119
  "algoliasearch": "4.24.0",
121
120
  "mdast-util-mdx-jsx": "^3.2.0",
122
121
  "mdast-util-mdxjs-esm": "^2.0.1",
123
- "next": "^15.1.7",
122
+ "next": "^15.2.0",
124
123
  "remark-mdx": "^3.1.0",
125
124
  "remark-rehype": "^11.1.1",
126
- "typescript": "^5.7.3",
125
+ "typescript": "^5.8.2",
127
126
  "unified": "^11.0.5",
128
127
  "vfile": "^6.0.3",
129
128
  "eslint-config-custom": "0.0.0",
130
129
  "tsconfig": "0.0.0"
131
130
  },
132
131
  "peerDependencies": {
133
- "@orama/tokenizers": "2.x.x",
134
132
  "@oramacloud/client": "1.x.x || 2.x.x",
135
133
  "algoliasearch": "4.24.0",
136
134
  "next": "14.x.x || 15.x.x",
@@ -138,9 +136,6 @@
138
136
  "react-dom": "18.x.x || 19.x.x"
139
137
  },
140
138
  "peerDependenciesMeta": {
141
- "@orama/tokenizers": {
142
- "optional": true
143
- },
144
139
  "@oramacloud/client": {
145
140
  "optional": true
146
141
  },