fumadocs-mdx 11.3.2 → 11.4.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.
@@ -111,19 +111,20 @@ function getDefaultMDXOptions({
111
111
  ];
112
112
  const remarkPlugins = pluginOption(
113
113
  (v) => [
114
- import_mdx_plugins.remarkGfm,
114
+ plugins.remarkGfm,
115
115
  [
116
- import_mdx_plugins.remarkHeading,
116
+ plugins.remarkHeading,
117
117
  {
118
118
  generateToc: false,
119
119
  ...remarkHeadingOptions
120
120
  }
121
121
  ],
122
- remarkImageOptions !== false && [import_mdx_plugins.remarkImage, remarkImageOptions],
123
- remarkCodeTabOptions !== false && import_mdx_plugins.remarkCodeTab,
122
+ remarkImageOptions !== false && [plugins.remarkImage, remarkImageOptions],
123
+ // Fumadocs 14 compatibility
124
+ "remarkCodeTab" in plugins && remarkCodeTabOptions !== false && plugins.remarkCodeTab,
124
125
  ...v,
125
126
  remarkStructureOptions !== false && [
126
- import_mdx_plugins.remarkStructure,
127
+ plugins.remarkStructure,
127
128
  remarkStructureOptions
128
129
  ],
129
130
  [remarkMdxExport, { values: mdxExports }]
@@ -132,9 +133,9 @@ function getDefaultMDXOptions({
132
133
  );
133
134
  const rehypePlugins = pluginOption(
134
135
  (v) => [
135
- rehypeCodeOptions !== false && [import_mdx_plugins.rehypeCode, rehypeCodeOptions],
136
+ rehypeCodeOptions !== false && [plugins.rehypeCode, rehypeCodeOptions],
136
137
  ...v,
137
- [import_mdx_plugins.rehypeToc]
138
+ [plugins.rehypeToc]
138
139
  ],
139
140
  mdxOptions.rehypePlugins
140
141
  );
@@ -144,11 +145,11 @@ function getDefaultMDXOptions({
144
145
  rehypePlugins
145
146
  };
146
147
  }
147
- var import_mdx_plugins;
148
+ var plugins;
148
149
  var init_mdx_options = __esm({
149
150
  "src/utils/mdx-options.ts"() {
150
151
  "use strict";
151
- import_mdx_plugins = require("fumadocs-core/mdx-plugins");
152
+ plugins = __toESM(require("fumadocs-core/mdx-plugins"), 1);
152
153
  init_remark_exports();
153
154
  }
154
155
  });
@@ -189,40 +190,11 @@ module.exports = __toCommonJS(next_exports);
189
190
  // src/next/create.ts
190
191
  var import_node_path2 = __toESM(require("path"), 1);
191
192
 
192
- // src/config/load.ts
193
+ // src/utils/load-config.ts
193
194
  var path = __toESM(require("path"), 1);
194
195
  var import_node_url = require("url");
195
- function findConfigFile() {
196
- return path.resolve("source.config.ts");
197
- }
198
- async function loadConfig(configPath) {
199
- const { build } = await import("esbuild");
200
- const url = (0, import_node_url.pathToFileURL)(path.resolve(".source/source.config.mjs"));
201
- const transformed = await build({
202
- entryPoints: [{ in: configPath, out: "source.config" }],
203
- bundle: true,
204
- outdir: ".source",
205
- target: "node18",
206
- write: true,
207
- platform: "node",
208
- format: "esm",
209
- packages: "external",
210
- outExtension: {
211
- ".js": ".mjs"
212
- },
213
- allowOverwrite: true
214
- });
215
- if (transformed.errors.length > 0) {
216
- throw new Error("failed to compile configuration file");
217
- }
218
- const loaded = await import(`${url.href}?hash=${Date.now().toString()}`);
219
- const [err, config] = buildConfig(
220
- // every call to `loadConfig` will cause the previous cache to be ignored
221
- loaded
222
- );
223
- if (err !== null) throw new Error(err);
224
- return config;
225
- }
196
+
197
+ // src/config/build.ts
226
198
  function buildConfig(config) {
227
199
  const collections = /* @__PURE__ */ new Map();
228
200
  let globalConfig;
@@ -270,13 +242,46 @@ function buildConfig(config) {
270
242
  ];
271
243
  }
272
244
 
245
+ // src/utils/load-config.ts
246
+ function findConfigFile() {
247
+ return path.resolve("source.config.ts");
248
+ }
249
+ async function loadConfig(configPath) {
250
+ const { build } = await import("esbuild");
251
+ const url = (0, import_node_url.pathToFileURL)(path.resolve(".source/source.config.mjs"));
252
+ const transformed = await build({
253
+ entryPoints: [{ in: configPath, out: "source.config" }],
254
+ bundle: true,
255
+ outdir: ".source",
256
+ target: "node18",
257
+ write: true,
258
+ platform: "node",
259
+ format: "esm",
260
+ packages: "external",
261
+ outExtension: {
262
+ ".js": ".mjs"
263
+ },
264
+ allowOverwrite: true
265
+ });
266
+ if (transformed.errors.length > 0) {
267
+ throw new Error("failed to compile configuration file");
268
+ }
269
+ const loaded = await import(`${url.href}?hash=${Date.now().toString()}`);
270
+ const [err, config] = buildConfig(
271
+ // every call to `loadConfig` will cause the previous cache to be ignored
272
+ loaded
273
+ );
274
+ if (err !== null) throw new Error(err);
275
+ return config;
276
+ }
277
+
273
278
  // src/map/index.ts
274
279
  var path3 = __toESM(require("path"), 1);
275
280
  var fs2 = __toESM(require("fs"), 1);
276
281
  var import_promises = require("fs/promises");
277
282
  var import_gray_matter = __toESM(require("gray-matter"), 1);
278
283
 
279
- // src/config/cached.ts
284
+ // src/utils/config-cache.ts
280
285
  var import_node_crypto = require("crypto");
281
286
  var fs = __toESM(require("fs"), 1);
282
287
  var cache = /* @__PURE__ */ new Map();
@@ -318,48 +323,62 @@ async function generateJS(configPath, config, outputPath, configHash, getFrontma
318
323
  const imports = [
319
324
  {
320
325
  type: "named",
321
- names: ["toRuntime", "toRuntimeAsync"],
326
+ names: ["toRuntime"],
322
327
  specifier: "fumadocs-mdx"
323
328
  }
324
329
  ];
325
- const importedCollections = /* @__PURE__ */ new Set();
326
- async function generateEntry(file, collectionName, collection, importId) {
327
- if (collection.type === "doc" && collection.async) {
328
- const importPath = `${toImportPath(file.absolutePath, outDir2)}?hash=${configHash}&collection=${collectionName}`;
329
- const frontmatter = await getFrontmatter(file.absolutePath);
330
- return `toRuntimeAsync(${JSON.stringify(frontmatter)}, () => import(${JSON.stringify(importPath)}), ${JSON.stringify(file)})`;
331
- }
332
- imports.push({
333
- type: "namespace",
334
- name: importId,
335
- specifier: `${toImportPath(file.absolutePath, outDir2)}?collection=${collectionName}&hash=${configHash}`
336
- });
337
- return `toRuntime("${collection.type}", ${importId}, ${JSON.stringify(file)})`;
338
- }
330
+ let asyncInit = false;
331
+ const lines = [];
339
332
  config._runtime.files.clear();
340
333
  const entries = Array.from(config.collections.entries());
341
334
  const declares = entries.map(async ([k, collection]) => {
342
335
  const files = await getCollectionFiles(collection);
336
+ if (collection.type === "doc" && collection.async) {
337
+ if (!asyncInit) {
338
+ imports.push(
339
+ {
340
+ type: "namespace",
341
+ specifier: toImportPath(configPath, outDir2),
342
+ name: "_source"
343
+ },
344
+ {
345
+ type: "named",
346
+ specifier: "fumadocs-mdx/runtime/async",
347
+ names: ["asyncFiles", "buildConfig"]
348
+ }
349
+ );
350
+ lines.unshift(
351
+ "const [err, _sourceConfig] = buildConfig(_source)",
352
+ "if (err) throw new Error(err)"
353
+ );
354
+ asyncInit = true;
355
+ }
356
+ const entries2 = files.map(async (file) => {
357
+ const frontmatter = await getFrontmatter(file.absolutePath);
358
+ return JSON.stringify({
359
+ frontmatter,
360
+ file
361
+ });
362
+ });
363
+ return `export const ${k} = asyncFiles([${(await Promise.all(entries2)).join(", ")}], "${k}", _sourceConfig)`;
364
+ }
343
365
  const items = files.map(async (file, i) => {
344
366
  config._runtime.files.set(file.absolutePath, k);
345
- return generateEntry(file, k, collection, `${k}_${i}`);
367
+ const importId = `${k}_${i}`;
368
+ imports.push({
369
+ type: "namespace",
370
+ name: importId,
371
+ specifier: `${toImportPath(file.absolutePath, outDir2)}?collection=${k}&hash=${configHash}`
372
+ });
373
+ return `toRuntime("${collection.type}", ${importId}, ${JSON.stringify(file)})`;
346
374
  });
347
375
  const resolvedItems = await Promise.all(items);
348
- if (collection.transform) {
349
- if (config.global) importedCollections.add("default");
350
- importedCollections.add(k);
351
- }
352
- return collection.transform ? `export const ${k} = await Promise.all([${resolvedItems.join(", ")}].map(v => c_${k}.transform(v, ${config.global ? "c_default" : "undefined"})));` : `export const ${k} = [${resolvedItems.join(", ")}];`;
376
+ return `export const ${k} = [${resolvedItems.join(", ")}];`;
353
377
  });
354
378
  const resolvedDeclares = await Promise.all(declares);
355
- if (importedCollections.size > 0) {
356
- imports.push({
357
- type: "named",
358
- names: Array.from(importedCollections.values()).sort().map((v) => [v, `c_${v}`]),
359
- specifier: toImportPath(configPath, outDir2)
360
- });
361
- }
362
- return [...imports.map(getImportCode), ...resolvedDeclares].join("\n");
379
+ return [...imports.map(getImportCode), ...lines, ...resolvedDeclares].join(
380
+ "\n"
381
+ );
363
382
  }
364
383
  async function getCollectionFiles(collection) {
365
384
  const files = /* @__PURE__ */ new Map();
@@ -424,14 +443,41 @@ async function start(dev, configPath, outDir2) {
424
443
  const typeOut = path3.resolve(outDir2, `index.d.ts`);
425
444
  const frontmatterCache = /* @__PURE__ */ new Map();
426
445
  let hookUpdate = false;
427
- const readFrontmatter = async (file) => {
446
+ async function readFrontmatter(file) {
447
+ hookUpdate = true;
428
448
  const cached = frontmatterCache.get(file);
429
449
  if (cached) return cached;
430
- hookUpdate = true;
431
- return (0, import_gray_matter.default)({
432
- content: await (0, import_promises.readFile)(file).then((res) => res.toString())
433
- }).data;
434
- };
450
+ const readStream = fs2.createReadStream(file, {
451
+ highWaterMark: 250
452
+ });
453
+ return new Promise((res, rej) => {
454
+ let idx = 0;
455
+ let str = "";
456
+ readStream.on("data", (_chunk) => {
457
+ const chunk = _chunk.toString();
458
+ if (idx === 0 && !chunk.startsWith("---")) {
459
+ res({});
460
+ readStream.close();
461
+ return;
462
+ }
463
+ str += chunk;
464
+ idx++;
465
+ if (str.includes("\n---")) {
466
+ res(
467
+ (0, import_gray_matter.default)({
468
+ content: str
469
+ }).data
470
+ );
471
+ readStream.close();
472
+ }
473
+ });
474
+ readStream.on("end", () => res({}));
475
+ readStream.on("error", (e) => rej(e));
476
+ }).then((res) => {
477
+ frontmatterCache.set(file, res);
478
+ return res;
479
+ });
480
+ }
435
481
  fs2.mkdirSync(outDir2, { recursive: true });
436
482
  fs2.writeFileSync(
437
483
  jsOut,
@@ -3,7 +3,8 @@ import {
3
3
  getConfigHash,
4
4
  loadConfig,
5
5
  loadConfigCached
6
- } from "../chunk-HPKXUFKR.js";
6
+ } from "../chunk-IU4D6M3A.js";
7
+ import "../chunk-2DJQ3DOD.js";
7
8
 
8
9
  // src/next/create.ts
9
10
  import path3 from "node:path";
@@ -11,7 +12,7 @@ import path3 from "node:path";
11
12
  // src/map/index.ts
12
13
  import * as path2 from "node:path";
13
14
  import * as fs from "node:fs";
14
- import { readFile, writeFile } from "node:fs/promises";
15
+ import { writeFile } from "node:fs/promises";
15
16
  import grayMatter from "gray-matter";
16
17
 
17
18
  // src/map/generate.ts
@@ -34,48 +35,62 @@ async function generateJS(configPath, config, outputPath, configHash, getFrontma
34
35
  const imports = [
35
36
  {
36
37
  type: "named",
37
- names: ["toRuntime", "toRuntimeAsync"],
38
+ names: ["toRuntime"],
38
39
  specifier: "fumadocs-mdx"
39
40
  }
40
41
  ];
41
- const importedCollections = /* @__PURE__ */ new Set();
42
- async function generateEntry(file, collectionName, collection, importId) {
43
- if (collection.type === "doc" && collection.async) {
44
- const importPath = `${toImportPath(file.absolutePath, outDir2)}?hash=${configHash}&collection=${collectionName}`;
45
- const frontmatter = await getFrontmatter(file.absolutePath);
46
- return `toRuntimeAsync(${JSON.stringify(frontmatter)}, () => import(${JSON.stringify(importPath)}), ${JSON.stringify(file)})`;
47
- }
48
- imports.push({
49
- type: "namespace",
50
- name: importId,
51
- specifier: `${toImportPath(file.absolutePath, outDir2)}?collection=${collectionName}&hash=${configHash}`
52
- });
53
- return `toRuntime("${collection.type}", ${importId}, ${JSON.stringify(file)})`;
54
- }
42
+ let asyncInit = false;
43
+ const lines = [];
55
44
  config._runtime.files.clear();
56
45
  const entries = Array.from(config.collections.entries());
57
46
  const declares = entries.map(async ([k, collection]) => {
58
47
  const files = await getCollectionFiles(collection);
48
+ if (collection.type === "doc" && collection.async) {
49
+ if (!asyncInit) {
50
+ imports.push(
51
+ {
52
+ type: "namespace",
53
+ specifier: toImportPath(configPath, outDir2),
54
+ name: "_source"
55
+ },
56
+ {
57
+ type: "named",
58
+ specifier: "fumadocs-mdx/runtime/async",
59
+ names: ["asyncFiles", "buildConfig"]
60
+ }
61
+ );
62
+ lines.unshift(
63
+ "const [err, _sourceConfig] = buildConfig(_source)",
64
+ "if (err) throw new Error(err)"
65
+ );
66
+ asyncInit = true;
67
+ }
68
+ const entries2 = files.map(async (file) => {
69
+ const frontmatter = await getFrontmatter(file.absolutePath);
70
+ return JSON.stringify({
71
+ frontmatter,
72
+ file
73
+ });
74
+ });
75
+ return `export const ${k} = asyncFiles([${(await Promise.all(entries2)).join(", ")}], "${k}", _sourceConfig)`;
76
+ }
59
77
  const items = files.map(async (file, i) => {
60
78
  config._runtime.files.set(file.absolutePath, k);
61
- return generateEntry(file, k, collection, `${k}_${i}`);
79
+ const importId = `${k}_${i}`;
80
+ imports.push({
81
+ type: "namespace",
82
+ name: importId,
83
+ specifier: `${toImportPath(file.absolutePath, outDir2)}?collection=${k}&hash=${configHash}`
84
+ });
85
+ return `toRuntime("${collection.type}", ${importId}, ${JSON.stringify(file)})`;
62
86
  });
63
87
  const resolvedItems = await Promise.all(items);
64
- if (collection.transform) {
65
- if (config.global) importedCollections.add("default");
66
- importedCollections.add(k);
67
- }
68
- return collection.transform ? `export const ${k} = await Promise.all([${resolvedItems.join(", ")}].map(v => c_${k}.transform(v, ${config.global ? "c_default" : "undefined"})));` : `export const ${k} = [${resolvedItems.join(", ")}];`;
88
+ return `export const ${k} = [${resolvedItems.join(", ")}];`;
69
89
  });
70
90
  const resolvedDeclares = await Promise.all(declares);
71
- if (importedCollections.size > 0) {
72
- imports.push({
73
- type: "named",
74
- names: Array.from(importedCollections.values()).sort().map((v) => [v, `c_${v}`]),
75
- specifier: toImportPath(configPath, outDir2)
76
- });
77
- }
78
- return [...imports.map(getImportCode), ...resolvedDeclares].join("\n");
91
+ return [...imports.map(getImportCode), ...lines, ...resolvedDeclares].join(
92
+ "\n"
93
+ );
79
94
  }
80
95
  async function getCollectionFiles(collection) {
81
96
  const files = /* @__PURE__ */ new Map();
@@ -140,14 +155,41 @@ async function start(dev, configPath, outDir2) {
140
155
  const typeOut = path2.resolve(outDir2, `index.d.ts`);
141
156
  const frontmatterCache = /* @__PURE__ */ new Map();
142
157
  let hookUpdate = false;
143
- const readFrontmatter = async (file) => {
158
+ async function readFrontmatter(file) {
159
+ hookUpdate = true;
144
160
  const cached = frontmatterCache.get(file);
145
161
  if (cached) return cached;
146
- hookUpdate = true;
147
- return grayMatter({
148
- content: await readFile(file).then((res) => res.toString())
149
- }).data;
150
- };
162
+ const readStream = fs.createReadStream(file, {
163
+ highWaterMark: 250
164
+ });
165
+ return new Promise((res, rej) => {
166
+ let idx = 0;
167
+ let str = "";
168
+ readStream.on("data", (_chunk) => {
169
+ const chunk = _chunk.toString();
170
+ if (idx === 0 && !chunk.startsWith("---")) {
171
+ res({});
172
+ readStream.close();
173
+ return;
174
+ }
175
+ str += chunk;
176
+ idx++;
177
+ if (str.includes("\n---")) {
178
+ res(
179
+ grayMatter({
180
+ content: str
181
+ }).data
182
+ );
183
+ readStream.close();
184
+ }
185
+ });
186
+ readStream.on("end", () => res({}));
187
+ readStream.on("error", (e) => rej(e));
188
+ }).then((res) => {
189
+ frontmatterCache.set(file, res);
190
+ return res;
191
+ });
192
+ }
151
193
  fs.mkdirSync(outDir2, { recursive: true });
152
194
  fs.writeFileSync(
153
195
  jsOut,