fumadocs-mdx 15.2.0 → 15.2.1

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/bin.d.ts CHANGED
@@ -1 +1 @@
1
- export { };
1
+ export {}
@@ -3,7 +3,7 @@ import { t as __exportAll } from "./rolldown-runtime-D7D4PA-g.js";
3
3
  var build_exports = /* @__PURE__ */ __exportAll({ buildMDX: () => buildMDX });
4
4
  async function buildMDX(core, collection, options) {
5
5
  if ((collection ? collection.compiler : core.getConfig().global.compiler) === "satteri") {
6
- const { buildSatteriMDX } = await import("./build-satteri-oMFzrKGl.js");
6
+ const { buildSatteriMDX } = await import("./build-satteri-k0DGJ1In.js");
7
7
  return buildSatteriMDX(core, collection, options);
8
8
  }
9
9
  const { buildJSMDX } = await import("./build-default-C77dbnhG.js");
@@ -3,8 +3,9 @@ import { pathToFileURL } from "node:url";
3
3
  //#region src/loaders/mdx/build-satteri.ts
4
4
  async function buildSatteriMDX(core, collection, { filePath, frontmatter, source, _compiler, environment, isDevelopment }) {
5
5
  const satteriOptions = await getSatteriOptions(core.getConfig(), collection, environment);
6
+ const format = filePath.endsWith(".mdx") ? "mdx" : "md";
6
7
  const postprocess = {
7
- _format: filePath.endsWith(".mdx") ? "mdx" : "md",
8
+ _format: format,
8
9
  ...collection?.postprocess
9
10
  };
10
11
  const [{ compileMdx }, { remarkLlms }, { remarkInclude }] = await Promise.all([
@@ -34,6 +35,7 @@ async function buildSatteriMDX(core, collection, { filePath, frontmatter, source
34
35
  return { code: (await compileMdx({
35
36
  source,
36
37
  filePath,
38
+ format,
37
39
  frontmatter,
38
40
  isDevelopment,
39
41
  environment,
@@ -55,12 +57,12 @@ function postprocessPlugin({ extractLinkReferences = false }, lastModified) {
55
57
  link(node, ctx) {
56
58
  if (extractLinkReferences) (ctx.data.extractedReferences ??= []).push({ href: node.url });
57
59
  },
60
+ collectExports({ data, addExport }) {
61
+ if (extractLinkReferences) addExport("extractedReferences", JSON.stringify(data.extractedReferences ??= []));
62
+ if (lastModified) addExport("lastModified", `new Date(${lastModified.getTime()})`);
63
+ },
58
64
  afterToJs({ result }) {
59
- if (extractLinkReferences) {
60
- result.data.extractedReferences ??= [];
61
- result.code += `\nexport const extractedReferences = ${JSON.stringify(result.data.extractedReferences)};`;
62
- }
63
- if (lastModified) result.code += `\nexport const lastModified = new Date(${lastModified.getTime()});`;
65
+ if (extractLinkReferences) result.data.extractedReferences ??= [];
64
66
  }
65
67
  };
66
68
  }
package/dist/bun/index.js CHANGED
@@ -1,4 +1,4 @@
1
- import { t as createMdxLoader } from "../mdx-Bcb4tkWn.js";
1
+ import { t as createMdxLoader } from "../mdx-3XO-apdE.js";
2
2
  import { i as buildConfig, t as createCore } from "../core-BPlsDtvN.js";
3
3
  import { r as slash } from "../codegen-ESdi9CDJ.js";
4
4
  import { a as createIntegratedConfigLoader, t as toBun } from "../adapter-DvWJNDHu.js";
@@ -19,10 +19,10 @@ async function readJson(pkgJsonPath) {
19
19
  var generated_default = {
20
20
  optimizeDeps: {
21
21
  "include": [
22
+ "@fumadocs/local-md > @fumadocs/local-content > picomatch",
22
23
  "@fumadocs/local-md > estree-util-to-js > source-map",
23
24
  "@fumadocs/local-md > hast-util-to-jsx-runtime > mdast-util-mdx-expression > mdast-util-from-markdown > micromark > debug",
24
25
  "@fumadocs/local-md > hast-util-to-jsx-runtime > style-to-js",
25
- "@fumadocs/local-md > picomatch",
26
26
  "@fumadocs/local-md > remark > unified > extend",
27
27
  "@fumadocs/mdx-remote > @mdx-js/mdx > hast-util-to-jsx-runtime > style-to-js",
28
28
  "@fumadocs/mdx-remote > @mdx-js/mdx > remark-parse > mdast-util-from-markdown > micromark > debug",
@@ -48,6 +48,7 @@ var generated_default = {
48
48
  ],
49
49
  "exclude": [
50
50
  "@fumadocs/basehub",
51
+ "@fumadocs/local-content",
51
52
  "@fumadocs/local-md",
52
53
  "@fumadocs/mdx-remote",
53
54
  "@fumadocs/sanity",
@@ -62,6 +63,7 @@ var generated_default = {
62
63
  },
63
64
  ssr: { "noExternal": [
64
65
  "@fumadocs/basehub",
66
+ "@fumadocs/local-content",
65
67
  "@fumadocs/local-md",
66
68
  "@fumadocs/mdx-remote",
67
69
  "@fumadocs/sanity",
@@ -74,6 +76,21 @@ var generated_default = {
74
76
  "fumadocs-ui"
75
77
  ] }
76
78
  };
79
+ /**
80
+ * `use-sync-external-store` is a CommonJS package Base UI depends on for React 17, where
81
+ * `useSyncExternalStore` wasn't built into React yet.
82
+ *
83
+ * When it is bundled for SSR, its `require('react')` stays a runtime require, so it ends up with a
84
+ * different React instance than the bundled one the renderer installs its hook dispatcher on.
85
+ * Calling a hook then reads a null dispatcher and every component using a Base UI store (dialogs,
86
+ * navigation menu, scroll area) throws during SSR.
87
+ *
88
+ * We require React 19, where the shim only forwards to React's own `useSyncExternalStore`.
89
+ */
90
+ const alias = [{
91
+ find: /^use-sync-external-store\/shim$/,
92
+ replacement: "react"
93
+ }];
77
94
  async function getConfig(options) {
78
95
  const pkgJsonPath = await findClosestPkgJsonPath(options.root);
79
96
  if (!pkgJsonPath) return {
@@ -81,7 +98,8 @@ async function getConfig(options) {
81
98
  include: [],
82
99
  exclude: []
83
100
  },
84
- ssr: { noExternal: [] }
101
+ ssr: { noExternal: [] },
102
+ resolve: { alias }
85
103
  };
86
104
  const pkgJson = await readJson(pkgJsonPath).catch((e) => {
87
105
  throw new Error(`Unable to read ${pkgJsonPath}`, { cause: e });
@@ -96,7 +114,10 @@ async function getConfig(options) {
96
114
  });
97
115
  out.optimizeDeps.exclude = out.optimizeDeps.exclude.filter((item) => deps.has(item));
98
116
  out.ssr.noExternal = out.ssr.noExternal.filter((item) => deps.has(item));
99
- return out;
117
+ return {
118
+ ...out,
119
+ resolve: { alias }
120
+ };
100
121
  }
101
122
  //#endregion
102
123
  export { getConfig };
@@ -1,9 +1,9 @@
1
1
  import { A as SatteriOptionsInput, N as ExtractedReference, P as PostprocessOptions, h as BuildEnvironment, v as CollectionSchema } from "../core-BmvJhZxm.js";
2
2
  import { MacroAsyncDocCollection, MacroAsyncDocsCollection, MacroDocCollection, MacroDocsCollection, MacroMetaCollection } from "../runtime/macro.js";
3
3
  import { metaSchema, pageSchema } from "fumadocs-core/source/schema";
4
+ import { MetaData, PageData } from "fumadocs-core/source";
4
5
  import { ProcessorOptions } from "@mdx-js/mdx";
5
6
  import { StandardJSONSchemaV1, StandardSchemaV1 } from "@standard-schema/spec";
6
- import { MetaData, PageData } from "fumadocs-core/source";
7
7
  //#region src/macro/index.d.ts
8
8
  interface MacroSchemaContext {
9
9
  path: string;
@@ -121,4 +121,4 @@ declare function defineCollections<DocSchema extends StandardSchemaV1 = Standard
121
121
  lastModified: LastModified;
122
122
  }>>;
123
123
  //#endregion
124
- export { DefineDocCollectionsOptions, DefineDocsOptions, DefineMetaCollectionsOptions, DocMacroOptions, MacroSchemaContext, MetaMacroOptions, defineCollections, defineDocs };
124
+ export { DefineDocCollectionsOptions, DefineDocsOptions, DefineMetaCollectionsOptions, DocMacroOptions, type ExtractedReference, MacroSchemaContext, MetaMacroOptions, defineCollections, defineDocs };
@@ -65,7 +65,7 @@ function createMdxLoader({ getCore }) {
65
65
  code: `export const frontmatter = ${JSON.stringify(matter.data)}`,
66
66
  map: null
67
67
  };
68
- const { buildMDX } = await import("./build-CMzB9h0Y.js").then((n) => n.n);
68
+ const { buildMDX } = await import("./build-DINFMoNj.js").then((n) => n.n);
69
69
  const compiled = await buildMDX(core, docCollection, {
70
70
  isDevelopment,
71
71
  source: "\n".repeat(countLines(matter.matter)) + matter.content,
@@ -1,4 +1,4 @@
1
- import { t as createMdxLoader } from "../mdx-Bcb4tkWn.js";
1
+ import { t as createMdxLoader } from "../mdx-3XO-apdE.js";
2
2
  import { t as createCore } from "../core-BPlsDtvN.js";
3
3
  import { r as slash } from "../codegen-ESdi9CDJ.js";
4
4
  import { n as toNode, o as createStandaloneConfigLoader } from "../adapter-DvWJNDHu.js";
@@ -1,4 +1,4 @@
1
- import { t as createMdxLoader } from "../mdx-Bcb4tkWn.js";
1
+ import { t as createMdxLoader } from "../mdx-3XO-apdE.js";
2
2
  import { t as createCore } from "../core-BPlsDtvN.js";
3
3
  import { n as toNode, o as createStandaloneConfigLoader } from "../adapter-DvWJNDHu.js";
4
4
  import { t as createMetaLoader } from "../meta-DWvKGgBH.js";
@@ -1,4 +1,4 @@
1
- import { t as createMdxLoader } from "../mdx-Bcb4tkWn.js";
1
+ import { t as createMdxLoader } from "../mdx-3XO-apdE.js";
2
2
  import { i as buildConfig, t as createCore } from "../core-BPlsDtvN.js";
3
3
  import { r as slash } from "../codegen-ESdi9CDJ.js";
4
4
  import { a as createIntegratedConfigLoader, r as toVite } from "../adapter-DvWJNDHu.js";
@@ -1,5 +1,5 @@
1
1
  import { i as buildConfig, t as createCore } from "../core-BPlsDtvN.js";
2
- import { t as buildMDX } from "../build-CMzB9h0Y.js";
2
+ import { t as buildMDX } from "../build-DINFMoNj.js";
3
3
  import { server } from "./server.js";
4
4
  import { frontmatter } from "fumadocs-core/content/md/frontmatter";
5
5
  import fs from "node:fs/promises";
@@ -1,12 +1,34 @@
1
1
  import { a as MetaMethods, n as DocMethods, t as DocData } from "../types-DWoea9Sq.js";
2
2
  import { MetaData, PageData, Source } from "fumadocs-core/source";
3
+ import { MDXContent } from "mdx/types";
3
4
  import { StructuredData } from "fumadocs-core/mdx-plugins/remark-structure";
4
5
  //#region src/runtime/macro.d.ts
5
- type MacroDocEntry<Frontmatter = unknown, Extra = unknown> = DocData & DocMethods & Frontmatter & Extra;
6
+ interface BrowserDocMethods {
7
+ /**
8
+ * Preload the content, so it can be rendered synchronously afterwards.
9
+ *
10
+ * In non-RSC apps, call it in your route loader such that `body` doesn't suspend on render.
11
+ *
12
+ * No-op on eagerly loaded (non-`async`) collections.
13
+ */
14
+ preload: () => Promise<void>;
15
+ }
16
+ type MacroDocEntry<Frontmatter = unknown, Extra = unknown> = DocData & DocMethods & BrowserDocMethods & Frontmatter & Extra;
6
17
  type MacroAsyncDocEntry<Frontmatter = unknown, Extra = unknown> = {
18
+ /**
19
+ * Load the compiled content.
20
+ *
21
+ * The promise is memoized, it's safe to call in render (e.g. `use(entry.load())`).
22
+ */
7
23
  load: () => Promise<DocData & Extra>;
8
24
  structuredData: () => Promise<StructuredData>;
9
- } & DocMethods & Frontmatter;
25
+ /**
26
+ * Component rendering the compiled content.
27
+ *
28
+ * It loads the content lazily and suspends (React `use()`) until available, call `preload()` beforehand to render synchronously.
29
+ */
30
+ body: MDXContent;
31
+ } & DocMethods & BrowserDocMethods & Frontmatter;
10
32
  type MacroMetaEntry<Data = unknown> = MetaMethods & Data;
11
33
  interface MacroDocCollection<Frontmatter = unknown, Extra = unknown> {
12
34
  entries: MacroDocEntry<Frontmatter, Extra>[];
@@ -86,4 +108,4 @@ declare function docsAsync(args: BaseArgs & {
86
108
  meta: GlobEntries;
87
109
  }): Promise<MacroAsyncDocsCollection>;
88
110
  //#endregion
89
- export { MacroAsyncDocCollection, MacroAsyncDocEntry, MacroAsyncDocsCollection, MacroDocCollection, MacroDocEntry, MacroDocsCollection, MacroMetaCollection, MacroMetaEntry, doc, docAsync, docs, docsAsync, meta };
111
+ export { BrowserDocMethods, MacroAsyncDocCollection, MacroAsyncDocEntry, MacroAsyncDocsCollection, MacroDocCollection, MacroDocEntry, MacroDocsCollection, MacroMetaCollection, MacroMetaEntry, doc, docAsync, docs, docsAsync, meta };
@@ -1,4 +1,5 @@
1
1
  import { server, toFumadocsSource } from "./server.js";
2
+ import { createElement, use } from "react";
2
3
  //#region src/runtime/macro.ts
3
4
  function create() {
4
5
  return server();
@@ -16,8 +17,48 @@ function accessor(entries) {
16
17
  }
17
18
  };
18
19
  }
20
+ /**
21
+ * annotate promise state in the convention understood by React `use()`, so settled promises are unwrapped without suspending.
22
+ */
23
+ function track(promise) {
24
+ const tracked = promise;
25
+ tracked.status = "pending";
26
+ promise.then((value) => {
27
+ tracked.status = "fulfilled";
28
+ tracked.value = value;
29
+ }, (reason) => {
30
+ tracked.status = "rejected";
31
+ tracked.reason = reason;
32
+ });
33
+ return tracked;
34
+ }
35
+ const eagerPreload = async () => {};
36
+ function withPreload(entries) {
37
+ return entries.map((entry) => ({
38
+ ...entry,
39
+ preload: eagerPreload
40
+ }));
41
+ }
42
+ function asyncEntries(raw) {
43
+ return raw.map((entry) => {
44
+ let promise;
45
+ const load = () => promise ??= track(entry.load());
46
+ function Body(props) {
47
+ const loaded = load();
48
+ return createElement((loaded.status === "fulfilled" ? loaded.value : use(loaded)).body, props);
49
+ }
50
+ return {
51
+ ...entry,
52
+ load,
53
+ async preload() {
54
+ await load();
55
+ },
56
+ body: Body
57
+ };
58
+ });
59
+ }
19
60
  async function doc(args) {
20
- const entries = await create().doc("doc", args.base, args.entries);
61
+ const entries = withPreload(await create().doc("doc", args.base, args.entries));
21
62
  return {
22
63
  ...accessor(entries),
23
64
  toFumadocsSource(options) {
@@ -26,7 +67,7 @@ async function doc(args) {
26
67
  };
27
68
  }
28
69
  async function docAsync(args) {
29
- const entries = await create().docLazy("doc", args.base, args.head, args.body);
70
+ const entries = asyncEntries(await create().docLazy("doc", args.base, args.head, args.body));
30
71
  return {
31
72
  ...accessor(entries),
32
73
  toFumadocsSource(options) {
@@ -39,7 +80,8 @@ async function meta(args) {
39
80
  }
40
81
  async function docs(args) {
41
82
  const instance = create();
42
- const [docEntries, metaEntries] = await Promise.all([instance.doc("doc", args.base, args.entries), instance.meta("meta", args.base, args.meta)]);
83
+ const [rawDocEntries, metaEntries] = await Promise.all([instance.doc("doc", args.base, args.entries), instance.meta("meta", args.base, args.meta)]);
84
+ const docEntries = withPreload(rawDocEntries);
43
85
  const getDoc = accessor(docEntries);
44
86
  const getMeta = accessor(metaEntries);
45
87
  return {
@@ -54,7 +96,8 @@ async function docs(args) {
54
96
  }
55
97
  async function docsAsync(args) {
56
98
  const instance = create();
57
- const [docEntries, metaEntries] = await Promise.all([instance.docLazy("doc", args.base, args.head, args.body), instance.meta("meta", args.base, args.meta)]);
99
+ const [rawDocEntries, metaEntries] = await Promise.all([instance.docLazy("doc", args.base, args.head, args.body), instance.meta("meta", args.base, args.meta)]);
100
+ const docEntries = asyncEntries(rawDocEntries);
58
101
  const getDoc = accessor(docEntries);
59
102
  const getMeta = accessor(metaEntries);
60
103
  return {
@@ -1,8 +1,8 @@
1
1
  import { C as DocsCollection, T as MetaCollection, y as DocCollection } from "../core-BmvJhZxm.js";
2
2
  import "../index-BN7EkING.js";
3
3
  import { a as MetaMethods, i as InternalTypeConfig, n as DocMethods, t as DocData } from "../types-DWoea9Sq.js";
4
- import { StandardSchemaV1 } from "@standard-schema/spec";
5
4
  import { MetaData, PageData, Source } from "fumadocs-core/source";
5
+ import { StandardSchemaV1 } from "@standard-schema/spec";
6
6
  import { StructuredData } from "fumadocs-core/mdx-plugins/remark-structure";
7
7
  //#region src/runtime/server.d.ts
8
8
  type MetaCollectionEntry<Data> = Data & MetaMethods;
@@ -1,11 +1,11 @@
1
- import * as path$1 from "node:path";
1
+ import { PathUtils } from "fumadocs-core/source";
2
2
  //#region src/runtime/server.ts
3
3
  function server() {
4
4
  function fileInfo(file, base) {
5
5
  if (file.startsWith("./")) file = file.slice(2);
6
6
  return {
7
7
  path: file,
8
- fullPath: path$1.join(base, file)
8
+ fullPath: PathUtils.joinPath(base, file)
9
9
  };
10
10
  }
11
11
  function mapDocData(entry) {
@@ -79,13 +79,13 @@ function toFumadocsSource(pages, metas, options) {
79
79
  const files = [];
80
80
  for (const entry of pages) files.push({
81
81
  type: "page",
82
- path: baseDir ? path$1.join(baseDir, entry.info.path) : entry.info.path,
82
+ path: baseDir ? PathUtils.joinPath(baseDir, entry.info.path) : entry.info.path,
83
83
  absolutePath: entry.info.fullPath,
84
84
  data: entry
85
85
  });
86
86
  for (const entry of metas) files.push({
87
87
  type: "meta",
88
- path: baseDir ? path$1.join(baseDir, entry.info.path) : entry.info.path,
88
+ path: baseDir ? PathUtils.joinPath(baseDir, entry.info.path) : entry.info.path,
89
89
  absolutePath: entry.info.fullPath,
90
90
  data: entry
91
91
  });
@@ -1,5 +1,6 @@
1
- import { p as IndexFilePluginOptions, r as CoreOptions } from "../core-BmvJhZxm.js";
1
+ import { p as IndexFilePluginOptions, r as CoreOptions, w as GlobalConfig } from "../core-BmvJhZxm.js";
2
2
  import { t as MacroPluginOption } from "../options-aB6xV-d7.js";
3
+ import "../index-BN7EkING.js";
3
4
  import { Plugin } from "vite";
4
5
  //#region src/vite/index.d.ts
5
6
  interface PluginOptions extends Pick<CoreOptions, 'configPath' | 'outDir' | 'plugins'> {
@@ -22,8 +23,15 @@ interface PluginOptions extends Pick<CoreOptions, 'configPath' | 'outDir' | 'plu
22
23
  * @defaultValue true
23
24
  */
24
25
  updateViteConfig?: boolean;
26
+ /** extra global options, will be shallow-merged if another global config is specified in the main config file. */
27
+ globalOptions?: GlobalConfig;
25
28
  }
29
+ interface FumadocsMdxOptions extends PluginOptions {
30
+ /** force a config module object instead of importing from config path. */
31
+ forcedConfig?: Record<string, unknown> | Promise<Record<string, unknown>>;
32
+ }
33
+ declare function fumadocsMdx(options?: FumadocsMdxOptions): Plugin<any>[];
26
34
  declare function mdx(forcedConfig?: Record<string, unknown> | Promise<Record<string, unknown>> | undefined, pluginOptions?: PluginOptions): Plugin[];
27
35
  declare function postInstall(pluginOptions?: PluginOptions): Promise<void>;
28
36
  //#endregion
29
- export { PluginOptions, mdx as default, postInstall };
37
+ export { FumadocsMdxOptions, PluginOptions, mdx as default, fumadocsMdx, postInstall };
@@ -1,4 +1,4 @@
1
- import { t as createMdxLoader } from "../mdx-Bcb4tkWn.js";
1
+ import { t as createMdxLoader } from "../mdx-3XO-apdE.js";
2
2
  import { i as buildConfig, t as createCore } from "../core-BPlsDtvN.js";
3
3
  import { a as createIntegratedConfigLoader, r as toVite } from "../adapter-DvWJNDHu.js";
4
4
  import { t as createMetaLoader } from "../meta-DWvKGgBH.js";
@@ -33,9 +33,12 @@ function createMacroEvaluator(root) {
33
33
  return { inputs: Array.from(inputs) };
34
34
  };
35
35
  }
36
+ function fumadocsMdx(options) {
37
+ return mdx(options?.forcedConfig, options);
38
+ }
36
39
  function mdx(forcedConfig, pluginOptions = {}) {
37
40
  const { updateViteConfig = true } = pluginOptions;
38
- let core;
41
+ let managed;
39
42
  const metaPlugin = { name: "fumadocs-mdx:meta" };
40
43
  const mdxPlugin = { name: "fumadocs-mdx:mdx" };
41
44
  const macroPlugin = { name: "fumadocs-mdx:macro" };
@@ -43,7 +46,8 @@ function mdx(forcedConfig, pluginOptions = {}) {
43
46
  {
44
47
  name: "fumadocs-mdx",
45
48
  async config(config, env) {
46
- core = createViteCore(config.root ?? process.cwd(), pluginOptions);
49
+ managed = createManagedCore(config.root ?? process.cwd(), forcedConfig, pluginOptions);
50
+ const core = managed.core;
47
51
  const macroOptions = resolveMacroOptions(pluginOptions.macro);
48
52
  if (macroOptions) {
49
53
  const { MacroCollector } = await import("../eval-z3HV4VJp.js").then((n) => n.r);
@@ -54,7 +58,7 @@ function mdx(forcedConfig, pluginOptions = {}) {
54
58
  evaluator: createMacroEvaluator(core.root)
55
59
  });
56
60
  }
57
- await core.init({ config: buildConfig(forcedConfig ? await forcedConfig : await importConfigFile(core.configPath), core.root) });
61
+ await managed.reload();
58
62
  const configLoader = createIntegratedConfigLoader(core);
59
63
  const mdxLoader = toVite(createMdxLoader(configLoader));
60
64
  const metaLoader = toVite(createMetaLoader(configLoader, { json: "json" }));
@@ -63,7 +67,7 @@ function mdx(forcedConfig, pluginOptions = {}) {
63
67
  order: "pre",
64
68
  handler(code, id) {
65
69
  if (id.includes("virtual:vite-rsc")) return null;
66
- if (!forcedConfig) this.addWatchFile(core.configPath);
70
+ if (managed.watchConfig) this.addWatchFile(core.configPath);
67
71
  return mdxLoader.transform.call(this, code, id);
68
72
  }
69
73
  };
@@ -71,7 +75,7 @@ function mdx(forcedConfig, pluginOptions = {}) {
71
75
  filter: { id: metaLoaderGlob },
72
76
  order: "pre",
73
77
  handler(code, id) {
74
- if (!forcedConfig) this.addWatchFile(core.configPath);
78
+ if (managed.watchConfig) this.addWatchFile(core.configPath);
75
79
  return metaLoader.transform.call(this, code, id);
76
80
  }
77
81
  };
@@ -105,20 +109,23 @@ function mdx(forcedConfig, pluginOptions = {}) {
105
109
  }
106
110
  if ("_fumadocs_skipViteConfig" in config && config._fumadocs_skipViteConfig) return;
107
111
  if (!updateViteConfig) return;
108
- const { getConfig } = await import("../dist-CQ17lmpt.js");
112
+ const { getConfig } = await import("../dist-Dm0fXCC7.js");
109
113
  return getConfig({ root: core.root });
110
114
  },
111
115
  async buildStart() {
112
- await core.emit({ write: true });
116
+ await managed.core.emit({ write: true });
113
117
  },
114
118
  async configureServer(server) {
119
+ const core = managed.core;
115
120
  await core.initServer({ watcher: server.watcher });
116
- if (!forcedConfig) server.watcher.on("change", async (file) => {
117
- if (path.resolve(file) === core.configPath) {
118
- await core.init({ config: buildConfig(await importConfigFile(core.configPath), core.root) });
119
- await core.emit({ write: true });
120
- }
121
- });
121
+ if (forcedConfig) return;
122
+ const onChange = async (file) => {
123
+ if (path.resolve(file) !== core.configPath) return;
124
+ await managed.reload();
125
+ await core.emit({ write: true });
126
+ };
127
+ server.watcher.on("change", onChange);
128
+ server.watcher.on("add", onChange);
122
129
  }
123
130
  },
124
131
  macroPlugin,
@@ -126,14 +133,42 @@ function mdx(forcedConfig, pluginOptions = {}) {
126
133
  metaPlugin
127
134
  ];
128
135
  }
129
- async function importConfigFile(configPath) {
130
- if (!await fs.access(configPath).then(() => true, () => false)) return {};
131
- return (await runnerImport(configPath)).module;
136
+ function createManagedCore(root, forcedConfig, pluginOptions) {
137
+ const managed = {
138
+ core: createViteCore(root, pluginOptions),
139
+ watchConfig: false,
140
+ async reload() {
141
+ const { config, fromFile } = await loadCoreConfig(managed.core, forcedConfig, pluginOptions);
142
+ managed.watchConfig = fromFile;
143
+ await managed.core.init({ config });
144
+ }
145
+ };
146
+ return managed;
147
+ }
148
+ async function loadCoreConfig(core, forcedConfig, { globalOptions } = {}) {
149
+ let v;
150
+ let fromFile = false;
151
+ if (forcedConfig) v = await forcedConfig;
152
+ else {
153
+ const exists = await fs.access(core.configPath).then(() => true, () => false);
154
+ v = exists ? (await runnerImport(core.configPath)).module : {};
155
+ fromFile = exists;
156
+ }
157
+ return {
158
+ config: await buildConfig(globalOptions ? {
159
+ ...v,
160
+ default: {
161
+ ...typeof v.default === "object" ? v.default : void 0,
162
+ ...globalOptions
163
+ }
164
+ } : v, core.root),
165
+ fromFile
166
+ };
132
167
  }
133
168
  async function postInstall(pluginOptions = {}) {
134
- const core = createViteCore(process.cwd(), pluginOptions);
135
- await core.init({ config: buildConfig(await importConfigFile(core.configPath), process.cwd()) });
136
- await core.emit({ write: true });
169
+ const managed = createManagedCore(process.cwd(), void 0, pluginOptions);
170
+ await managed.reload();
171
+ await managed.core.emit({ write: true });
137
172
  }
138
173
  function createViteCore(root, { index = true, configPath, outDir }) {
139
174
  if (index === true) index = {};
@@ -149,4 +184,4 @@ function createViteCore(root, { index = true, configPath, outDir }) {
149
184
  });
150
185
  }
151
186
  //#endregion
152
- export { mdx as default, postInstall };
187
+ export { mdx as default, fumadocsMdx, postInstall };
@@ -1,4 +1,4 @@
1
- import { t as createMdxLoader } from "../mdx-Bcb4tkWn.js";
1
+ import { t as createMdxLoader } from "../mdx-3XO-apdE.js";
2
2
  import { i as toWebpack, o as createStandaloneConfigLoader } from "../adapter-DvWJNDHu.js";
3
3
  import { t as getCore } from "../webpack-BSog6pml.js";
4
4
  //#region src/webpack/mdx.ts
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "fumadocs-mdx",
3
- "version": "15.2.0",
3
+ "version": "15.2.1",
4
4
  "description": "The built-in source for Fumadocs",
5
5
  "keywords": [
6
6
  "Docs",
@@ -59,7 +59,7 @@
59
59
  "esbuild": "^0.28.1",
60
60
  "estree-util-value-to-estree": "^3.5.0",
61
61
  "github-slugger": "^2.0.0",
62
- "magic-string": "^0.30.21",
62
+ "magic-string": "^1.1.0",
63
63
  "mdast-util-mdx": "^3.0.0",
64
64
  "picocolors": "^1.1.1",
65
65
  "picomatch": "^4.0.5",
@@ -70,31 +70,31 @@
70
70
  "unist-util-visit": "^5.1.0",
71
71
  "vfile": "^6.0.3",
72
72
  "yaml": "^2.9.0",
73
- "yuku-analyzer": "^0.6.3",
73
+ "yuku-analyzer": "^0.8.1",
74
74
  "zod": "^4.4.3"
75
75
  },
76
76
  "devDependencies": {
77
77
  "@types/bun": "^1.3.14",
78
78
  "@types/mdast": "^4.0.4",
79
79
  "@types/mdx": "^2.0.14",
80
- "@types/node": "^26.1.1",
80
+ "@types/node": "^26.1.2",
81
81
  "@types/picomatch": "^4.0.3",
82
82
  "@types/react": "^19.2.17",
83
83
  "mdast-util-directive": "^3.1.0",
84
- "next": "^16.2.10",
85
- "react": "^19.2.7",
84
+ "next": "^16.2.12",
85
+ "react": "^19.2.8",
86
86
  "remark": "^15.0.1",
87
87
  "remark-directive": "^4.0.0",
88
88
  "remark-mdx": "^3.1.1",
89
- "rolldown": "^1.1.5",
89
+ "rolldown": "^1.2.0",
90
90
  "satteri": "^0.9.5",
91
- "tsdown": "0.22.5",
92
- "vite": "^8.1.4",
93
- "webpack": "^5.108.4",
94
- "@fumadocs/satteri": "0.2.2",
91
+ "tsdown": "0.22.14",
92
+ "vite": "^8.1.5",
93
+ "webpack": "^5.109.2",
95
94
  "@fumadocs/vite": "0.1.0",
96
- "fumadocs-core": "16.11.5",
97
- "tsconfig": "0.0.0"
95
+ "tsconfig": "0.0.0",
96
+ "fumadocs-core": "16.14.0",
97
+ "@fumadocs/satteri": "0.3.1"
98
98
  },
99
99
  "peerDependencies": {
100
100
  "@fumadocs/satteri": "0.x.x",