@docubook/flame 2.0.0-beta.2 → 2.0.0-beta.4

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 (51) hide show
  1. package/.docu/components/Pagination.tsx +12 -1
  2. package/.docu/lib/build.deno.js +1 -1
  3. package/.docu/lib/{build.impl-BJsi28mD.js → build.impl-CT-YLyLn.js} +73 -25
  4. package/.docu/lib/build.impl-CT-YLyLn.js.map +1 -0
  5. package/.docu/lib/build.impl-cJPJeQ8r.js +2 -0
  6. package/.docu/lib/build.node.js +1 -1
  7. package/.docu/lib/clean.js +1 -1
  8. package/.docu/lib/deploy.deno.js +1 -1
  9. package/.docu/lib/deploy.node.js +1 -1
  10. package/.docu/lib/{deploy.shared-D3UWafa6.js → deploy.shared-CmOzm3b5.js} +3 -3
  11. package/.docu/lib/{deploy.shared-D3UWafa6.js.map → deploy.shared-CmOzm3b5.js.map} +1 -1
  12. package/.docu/lib/{html.shared-DSn-7_6t.js → html.shared-WwQnhDty.js} +269 -34
  13. package/.docu/lib/html.shared-WwQnhDty.js.map +1 -0
  14. package/.docu/lib/{logger-CycvLCrQ.js → logger-Cz0CPMi8.js} +9 -15
  15. package/.docu/lib/logger-Cz0CPMi8.js.map +1 -0
  16. package/.docu/lib/{paths-BtOIPBQ9.js → paths-Bl2cdp9E.js} +27 -3
  17. package/.docu/lib/paths-Bl2cdp9E.js.map +1 -0
  18. package/.docu/lib/preview.deno.js +1 -1
  19. package/.docu/lib/{preview.impl-CXJS2tQS.js → preview.impl-BaYhTRBW.js} +4 -4
  20. package/.docu/lib/{preview.impl-CXJS2tQS.js.map → preview.impl-BaYhTRBW.js.map} +1 -1
  21. package/.docu/lib/preview.node.js +1 -1
  22. package/.docu/lib/server.deno.js +1 -1
  23. package/.docu/lib/{server.impl-CJuWimfN.js → server.impl-l8hXfV_0.js} +7 -7
  24. package/.docu/lib/server.impl-l8hXfV_0.js.map +1 -0
  25. package/.docu/lib/server.node.js +1 -1
  26. package/.docu/lib/{utils-DA17MyQG.js → utils-B_CoyKie.js} +28 -6
  27. package/.docu/lib/utils-B_CoyKie.js.map +1 -0
  28. package/.docu/node/build.impl.ts +115 -43
  29. package/.docu/node/build.ts +134 -44
  30. package/.docu/node/cache-key.ts +311 -0
  31. package/.docu/node/html.shared.ts +2 -1
  32. package/.docu/node/html.ts +2 -1
  33. package/.docu/node/hydrate.node.ts +8 -11
  34. package/.docu/node/hydrate.ts +13 -14
  35. package/.docu/node/mdx.ts +14 -2
  36. package/.docu/node/paths.ts +27 -1
  37. package/.docu/node/plugin-builder.ts +10 -1
  38. package/.docu/node/route.ts +19 -21
  39. package/.docu/node/security.ts +18 -1
  40. package/.docu/node/server-routes.ts +3 -3
  41. package/.docu/node/types.ts +23 -5
  42. package/.docu/node/utils.ts +22 -2
  43. package/bin/cli.js +56 -18
  44. package/package.json +11 -17
  45. package/.docu/lib/build.impl-BJsi28mD.js.map +0 -1
  46. package/.docu/lib/build.impl-yVLaa1eQ.js +0 -2
  47. package/.docu/lib/html.shared-DSn-7_6t.js.map +0 -1
  48. package/.docu/lib/logger-CycvLCrQ.js.map +0 -1
  49. package/.docu/lib/paths-BtOIPBQ9.js.map +0 -1
  50. package/.docu/lib/server.impl-CJuWimfN.js.map +0 -1
  51. package/.docu/lib/utils-DA17MyQG.js.map +0 -1
@@ -1,14 +1,14 @@
1
- import { a as DOCS_DIR, c as PROJECT_ROOT, d as loadDocuConfig, l as STYLES_DIR, o as FRAMEWORK_ROOT, s as LIB_DIR, t as ASSETS_DIR, u as cleanOldBundles } from "./paths-BtOIPBQ9.js";
2
- import { a as isExternalUrl, h as normalizeImporterPath, n as docsHtmlHref, o as scanMdxFiles, r as formatDate2, t as cn } from "./utils-DA17MyQG.js";
1
+ import { a as DOCS_DIR, c as PROJECT_ROOT, d as loadDocuConfig, f as resolveProjectFile, l as STYLES_DIR, o as FRAMEWORK_ROOT, s as LIB_DIR, t as ASSETS_DIR, u as cleanOldBundles } from "./paths-Bl2cdp9E.js";
2
+ import { c as scanMdxFiles, f as cspMeta, i as formatDate2, n as cn, o as isExternalUrl, r as docsHtmlHref, v as normalizeImporterPath } from "./utils-B_CoyKie.js";
3
3
  import { builtinModules, createRequire } from "node:module";
4
4
  import { existsSync, readFileSync, readdirSync, statSync } from "node:fs";
5
5
  import { basename, dirname, extname, join, relative, resolve, sep } from "node:path";
6
- import { mkdir, readFile, stat, unlink, writeFile } from "node:fs/promises";
6
+ import { mkdir, readFile, rename, stat, unlink, writeFile } from "node:fs/promises";
7
7
  import { execFile } from "node:child_process";
8
8
  import { promisify } from "node:util";
9
- import { createHash } from "node:crypto";
10
9
  import { build } from "vite";
11
10
  import { generateThemeCss, presetRegistry, resolveTheme } from "@docubook/themes-colors";
11
+ import { createHash } from "node:crypto";
12
12
  import React, { createContext, useCallback, useContext, useEffect, useRef, useState } from "react";
13
13
  import { z } from "zod";
14
14
  import { MDXRemote, createDefaultRehypePlugins, createDefaultRemarkPlugins, extractFrontmatter, extractFrontmatterWithContent, extractTocsFromRawMdx, serialize } from "@docubook/core";
@@ -402,6 +402,8 @@ var BuildPluginBuilder = class {
402
402
  * Execute the transformHtml chain in pipeline pattern.
403
403
  * Each callback receives the **previous** callback's return value (or the
404
404
  * original HTML for the first). Every callback **must** return a string.
405
+ * Callbacks returning a non-string (e.g. `undefined`) are skipped with a
406
+ * warning — the current HTML passes through unchanged for that step.
405
407
  * Errors inside individual callbacks are caught and logged — the current
406
408
  * HTML passes through unchanged for that step.
407
409
  *
@@ -412,7 +414,9 @@ var BuildPluginBuilder = class {
412
414
  async runTransformHtmlChain(html, context) {
413
415
  let result = html;
414
416
  for (let i = 0; i < this._transformHtml.length; i++) try {
415
- result = await this._transformHtml[i](result, context);
417
+ const next = await this._transformHtml[i](result, context);
418
+ if (typeof next === "string") result = next;
419
+ else console.warn(`[plugin] transformHtml callback #${i + 1} returned invalid type (expected a string), keeping previous HTML`);
416
420
  } catch (err) {
417
421
  console.error(`[plugin] transformHtml callback #${i + 1} error: ${err instanceof Error ? err.message : String(err)}`);
418
422
  }
@@ -464,6 +468,230 @@ var BuildPluginBuilder = class {
464
468
  else console.warn(`[plugin] ${hookName} callback returned unexpected type (got ${typeof result}), expected string or string[], skipping`);
465
469
  }
466
470
  };
471
+ /** Toolchain fingerprint: Bun version on Bun, Deno version on Deno, Node elsewhere. */
472
+ function runtimeStamp() {
473
+ const g = globalThis;
474
+ const bun = g.Bun;
475
+ if (typeof bun?.version === "string" && bun.version.length > 0) return `bun-${bun.version}`;
476
+ const deno = g.Deno;
477
+ if (typeof deno?.version?.deno === "string" && deno.version.deno.length > 0) return `deno-${deno.version.deno}`;
478
+ const proc = g.process;
479
+ if (typeof proc?.version === "string" && proc.version.length > 0) return `node-${proc.version}`;
480
+ return "node-unknown";
481
+ }
482
+ /**
483
+ * True when a CSS file can change Tailwind v4 output.
484
+ * v4 is CSS-first: `@theme`, `@source`, `@plugin`, `@custom-variant`,
485
+ * `@utility`, `@config`, `@apply`/`@variant`, and `@import "tailwindcss"`
486
+ * all live in CSS. Plain CSS without these cannot affect the CLI output,
487
+ * so it is excluded to avoid false cache busts. Broad match deliberate:
488
+ * false positive busts safe, false negative serves stale CSS.
489
+ */
490
+ function isTailwindRelevantCss(content) {
491
+ return content.includes("@theme") || content.includes("@source") || content.includes("@plugin") || content.includes("@custom-variant") || content.includes("@utility") || content.includes("@config") || content.includes("@apply") || content.includes("@variant") || content.includes("@layer") || content.includes("tailwindcss");
492
+ }
493
+ var IMPORT_RE = /@import\s+(?:url\()?["']([^"']+)["']/g;
494
+ var MAX_IMPORT_DEPTH = 10;
495
+ /** Resolve `./` + `../` imports only — bare specifiers are version-pinned deps. */
496
+ function resolveRelativeImport(spec, fromDir) {
497
+ if (!spec.startsWith(".")) return void 0;
498
+ const clean = spec.split("?")[0].split("#")[0];
499
+ if (clean.length === 0) return void 0;
500
+ return join(fromDir, clean);
501
+ }
502
+ /**
503
+ * Read a CSS file plus transitively imported relative files.
504
+ * Non-relevant files contribute "" themselves, but their imports are still
505
+ * followed (nested file may carry `@theme`). `visited` breaks import cycles.
506
+ * Missing/unreadable files resolve to "" — never throws.
507
+ */
508
+ function readCssWithImports(path, visited, depth = 0) {
509
+ if (depth > MAX_IMPORT_DEPTH || visited.has(path)) return "";
510
+ visited.add(path);
511
+ let content = "";
512
+ try {
513
+ if (!existsSync(path)) return "";
514
+ content = readFileSync(path, "utf-8");
515
+ } catch {
516
+ return "";
517
+ }
518
+ let out = isTailwindRelevantCss(content) ? content : "";
519
+ try {
520
+ const dir = join(path, "..");
521
+ for (const m of content.matchAll(IMPORT_RE)) {
522
+ const resolved = resolveRelativeImport(m[1] ?? "", dir);
523
+ if (resolved) out += readCssWithImports(resolved, visited, depth + 1);
524
+ }
525
+ } catch {}
526
+ return out;
527
+ }
528
+ function scanCssDir(dir, visited) {
529
+ let out = "";
530
+ try {
531
+ const entries = readdirSync(dir, { withFileTypes: true });
532
+ for (const e of entries) {
533
+ const full = join(dir, e.name);
534
+ if (e.isDirectory()) {
535
+ if (e.name === "assets" || e.name.startsWith(".") || e.name === "node_modules") continue;
536
+ out += scanCssDir(full, visited);
537
+ } else if (e.name.endsWith(".css")) out += readCssWithImports(full, visited);
538
+ }
539
+ } catch {}
540
+ return out;
541
+ }
542
+ function scanRootCss(root, visited) {
543
+ let out = "";
544
+ try {
545
+ const entries = readdirSync(root, { withFileTypes: true });
546
+ for (const e of entries) if (e.isFile() && e.name.endsWith(".css")) out += readCssWithImports(join(root, e.name), visited);
547
+ } catch {}
548
+ return out;
549
+ }
550
+ /** Hash @theme/@source/@plugin-bearing CSS in project docs/ + root *.css. */
551
+ function tailwindCssThemeInputs(root) {
552
+ const visited = /* @__PURE__ */ new Set();
553
+ return scanCssDir(join(root, "docs"), visited) + scanRootCss(root, visited);
554
+ }
555
+ var TAILWIND_CONFIG_FILES = [
556
+ "tailwind.config.ts",
557
+ "tailwind.config.js",
558
+ "tailwind.config.mjs",
559
+ "tailwind.config.cjs",
560
+ "tailwind.config.mts",
561
+ "tailwind.config.cts",
562
+ "postcss.config.js",
563
+ "postcss.config.mjs",
564
+ "postcss.config.cjs"
565
+ ];
566
+ /**
567
+ * JS config still affects v4 when referenced via `@config`
568
+ * (plus PostCSS pipeline config). Content hashed when present.
569
+ */
570
+ function tailwindJsConfigInputs(root) {
571
+ let out = "";
572
+ for (const name of TAILWIND_CONFIG_FILES) try {
573
+ const p = join(root, name);
574
+ if (existsSync(p)) out += readFileSync(p, "utf-8") + "\0";
575
+ } catch {}
576
+ return out;
577
+ }
578
+ function readInstalledVersion(pkg, roots) {
579
+ for (const root of roots) try {
580
+ const p = join(root, "node_modules", ...pkg.split("/"), "package.json");
581
+ if (existsSync(p)) {
582
+ const parsed = JSON.parse(readFileSync(p, "utf-8"));
583
+ if (typeof parsed.version === "string" && parsed.version.length > 0) return parsed.version;
584
+ }
585
+ } catch {}
586
+ return "";
587
+ }
588
+ /** Pin resolved CSS-affecting deps into the key (installed version wins). */
589
+ function tailwindVersionPins(root) {
590
+ const names = [
591
+ "tailwindcss",
592
+ "@tailwindcss/cli",
593
+ "@tailwindcss/typography",
594
+ "daisyui"
595
+ ];
596
+ let extra = "";
597
+ const roots = [root, FRAMEWORK_ROOT];
598
+ for (const name of names) {
599
+ const installed = readInstalledVersion(name, roots);
600
+ if (installed) extra += `${name}@${installed}\0`;
601
+ }
602
+ try {
603
+ const pkgPath = join(root, "package.json");
604
+ if (existsSync(pkgPath)) {
605
+ const pkg = JSON.parse(readFileSync(pkgPath, "utf-8"));
606
+ for (const name of names) {
607
+ const range = pkg.dependencies?.[name] ?? pkg.devDependencies?.[name] ?? "";
608
+ if (range) extra += `${name}:${range}\0`;
609
+ }
610
+ }
611
+ } catch {}
612
+ return extra;
613
+ }
614
+ /**
615
+ * Extra Tailwind inputs beyond globals.css + theme.
616
+ * v4 is CSS-first: user overrides live in `@theme`/`@source`/`@plugin`
617
+ * blocks inside CSS files under the project root (e.g. docs slash star dot css),
618
+ * plus JS config referenced via `@config` and installed plugin versions.
619
+ * Missing files resolve to "" — never throws.
620
+ */
621
+ function tailwindExtraInputs(root = resolveProjectFile()) {
622
+ return tailwindCssThemeInputs(root) + "\0" + tailwindJsConfigInputs(root) + tailwindVersionPins(root);
623
+ }
624
+ /**
625
+ * Shared Tailwind cache key: globals.css + theme + tailwind config +
626
+ * toolchain version. Used by both hydrate.ts (Bun) and hydrate.node.ts
627
+ * (Vite) so the two runtimes agree on filenames. Segments joined with NUL
628
+ * so `("ab","c")` and `("a","bc")` hash differently.
629
+ */
630
+ function computeTailwindCacheKey(globals, themeSuffix, projectRoot = resolveProjectFile()) {
631
+ const h = createHash("sha256");
632
+ h.update(globals);
633
+ h.update("\0");
634
+ h.update(themeSuffix);
635
+ h.update("\0");
636
+ h.update(tailwindExtraInputs(projectRoot));
637
+ h.update("\0");
638
+ h.update(runtimeStamp());
639
+ h.update("\0");
640
+ h.update(`v4`);
641
+ return h.digest("hex").slice(0, 16);
642
+ }
643
+ /** Read globals.css content ("" when missing). Shared by both hydrators. */
644
+ function readGlobalsCss() {
645
+ const globalsPath = join(STYLES_DIR, "globals.css");
646
+ return existsSync(globalsPath) ? readFileSync(globalsPath, "utf-8") : "";
647
+ }
648
+ /**
649
+ * Atomic file write: tmp + rename so a crash mid-write never leaves a
650
+ * half-written cache/CSS behind. Tmp name includes pid so parallel
651
+ * builds (`bun run --parallel`) do not clobber each other.
652
+ */
653
+ async function atomicWriteFile(writeFile, rename, unlink, target, data) {
654
+ const proc = globalThis.process;
655
+ const tmp = `${target}.tmp-${typeof proc?.pid === "number" ? proc.pid : Math.floor(Math.random() * 1e9)}-${Date.now()}`;
656
+ try {
657
+ await writeFile(tmp, data);
658
+ await rename(tmp, target);
659
+ } catch (err) {
660
+ try {
661
+ await unlink(tmp);
662
+ } catch {}
663
+ throw err;
664
+ }
665
+ }
666
+ /** Wire memory-pressure hook once: OS low-memory → drop parsed page maps. */
667
+ var memoryPressureHooked = false;
668
+ function hookMemoryPressure(clear) {
669
+ if (memoryPressureHooked) return;
670
+ memoryPressureHooked = true;
671
+ try {
672
+ globalThis.process?.on?.("memoryPressure", () => {
673
+ try {
674
+ clear();
675
+ } catch {}
676
+ });
677
+ } catch {}
678
+ }
679
+ /**
680
+ * Hash of compiled MDX module sources (sorted keys + content).
681
+ * Used to skip the JS bundle rebuild when no page content changed.
682
+ */
683
+ function hashMdxSources(mdxSources) {
684
+ const h = createHash("sha256");
685
+ const slugs = Object.keys(mdxSources).sort();
686
+ h.update(`v4:${runtimeStamp()}:`);
687
+ for (const slug of slugs) {
688
+ h.update(slug);
689
+ h.update("\0");
690
+ h.update(mdxSources[slug]);
691
+ h.update("\0");
692
+ }
693
+ return h.digest("hex").slice(0, 16);
694
+ }
467
695
  //#endregion
468
696
  //#region .docu/node/fs-scanner.ts
469
697
  function toTitleCase$1(str) {
@@ -652,16 +880,15 @@ function resolveTailwindBin() {
652
880
  const binRel = typeof pkg.bin === "string" ? pkg.bin : pkg.bin.tailwindcss;
653
881
  return join(dirname(pkgPath), binRel);
654
882
  }
655
- /** Compute a cache key from globals.css + theme config content. */
883
+ /** Compute a cache key from globals.css + theme + config + toolchain. */
656
884
  function tailwindCacheKey() {
657
- const globalsPath = join(STYLES_DIR, "globals.css");
658
- const globalsContent = existsSync(globalsPath) ? readFileSync(globalsPath, "utf-8") : "";
885
+ const globalsContent = readGlobalsCss();
659
886
  let themeSuffix = "";
660
887
  try {
661
888
  const themeColors = getThemeConfig();
662
889
  if (themeColors) themeSuffix = JSON.stringify(themeColors);
663
890
  } catch {}
664
- return createHash("sha256").update(globalsContent + themeSuffix).digest("hex").slice(0, 16);
891
+ return computeTailwindCacheKey(globalsContent, themeSuffix);
665
892
  }
666
893
  /**
667
894
  * Build Tailwind CSS with content-based caching.
@@ -697,7 +924,7 @@ async function buildTailwindCss(key) {
697
924
  throw new Error(`Tailwind CSS build failed:\n${stderr}`, { cause: err });
698
925
  }
699
926
  let cssContent = await readFile(tmpCss, "utf-8");
700
- await unlink(tmpCss);
927
+ await unlink(tmpCss).catch(() => {});
701
928
  try {
702
929
  const themeColors = getThemeConfig();
703
930
  if (themeColors) cssContent = buildThemeCss(cssContent, themeColors);
@@ -706,7 +933,7 @@ async function buildTailwindCss(key) {
706
933
  }
707
934
  const cssFile = `client-${key}.css`;
708
935
  const outPath = join(ASSETS_DIR, cssFile);
709
- if (!existsSync(outPath)) await writeFile(outPath, cssContent);
936
+ if (!existsSync(outPath)) await atomicWriteFile(writeFile, rename, unlink, outPath, cssContent);
710
937
  return {
711
938
  file: cssFile,
712
939
  content: cssContent
@@ -1053,7 +1280,7 @@ function frontmatterField(frontmatter, key) {
1053
1280
  * (defaults + .html link fixes + user plugins) and runs `serialize()`.
1054
1281
  */
1055
1282
  async function serializeWithDocPlugins(rawMdx, opts = {}, pre) {
1056
- const { strippedContent, frontmatter } = pre ?? extractFrontmatterWithContent(rawMdx, opts.frontmatterSchema);
1283
+ const { strippedContent, frontmatter } = pre ?? (opts.frontmatterSchema ? extractFrontmatterWithContent(rawMdx, opts.frontmatterSchema) : extractFrontmatterWithContent(rawMdx));
1057
1284
  const defaultRemark = createDefaultRemarkPlugins();
1058
1285
  const defaultRehype = createDefaultRehypePlugins();
1059
1286
  const finalRemark = [
@@ -1091,7 +1318,7 @@ async function serializeWithDocPlugins(rawMdx, opts = {}, pre) {
1091
1318
  */
1092
1319
  async function compileMdx(rawMdx, filePath, gitDates, remarkPlugins, rehypePlugins, frontmatterSchema, pre) {
1093
1320
  const tocs = extractTocsFromRawMdx(rawMdx);
1094
- const frontmatter = pre?.frontmatter ?? extractFrontmatterWithContent(rawMdx, frontmatterSchema).frontmatter;
1321
+ const frontmatter = pre?.frontmatter ?? (frontmatterSchema ? extractFrontmatterWithContent(rawMdx, frontmatterSchema).frontmatter : extractFrontmatterWithContent(rawMdx).frontmatter);
1095
1322
  const serialized = await serializeWithDocPlugins(rawMdx, {
1096
1323
  remarkPlugins,
1097
1324
  rehypePlugins,
@@ -1159,6 +1386,12 @@ function registerPageContent(href, raw) {
1159
1386
  function getPageContent(href) {
1160
1387
  return pageContent.get(href);
1161
1388
  }
1389
+ /** Drop derived page maps under OS memory pressure (Bun 1.4 `memoryPressure`). */
1390
+ function clearDerivedPageCaches() {
1391
+ pageContent.clear();
1392
+ pageStripped.clear();
1393
+ pageFrontmatter.clear();
1394
+ }
1162
1395
  async function compileMdxModule(rawMdx, remarkPlugins, rehypePlugins, href) {
1163
1396
  const serialized = await serializeWithDocPlugins(rawMdx, {
1164
1397
  outputFormat: "program",
@@ -1367,6 +1600,21 @@ function getRouteMap() {
1367
1600
  return map;
1368
1601
  }
1369
1602
  /**
1603
+ * Single pagination entry builder (DRY) — one `readPageFrontmatter` call
1604
+ * serves both prev + next from the parse-once registry, so no file is
1605
+ * re-read or re-parsed. `description` rides along on prev too; the UI
1606
+ * keeps the paired prev minimal by design and only renders the rich
1607
+ * title + description when prev stands alone (last page, no next).
1608
+ */
1609
+ function toPaginationEntry(href, routeMap) {
1610
+ const fm = readPageFrontmatter(href);
1611
+ return {
1612
+ href,
1613
+ title: fm.title || routeMap.get(href) || "",
1614
+ description: fm.description || ""
1615
+ };
1616
+ }
1617
+ /**
1370
1618
  * Frontmatter for a page — read from the parse-once registry (populated
1371
1619
  * during compilation) instead of re-reading + re-parsing the file. Falls
1372
1620
  * back to a direct read only for pages the dev server has not compiled yet,
@@ -1397,14 +1645,9 @@ function getPreviousNext(pathname) {
1397
1645
  prev: null,
1398
1646
  next: null
1399
1647
  };
1400
- const fm = readPageFrontmatter(first);
1401
1648
  return {
1402
1649
  prev: null,
1403
- next: {
1404
- href: first,
1405
- title: fm.title || routeMap.get(first) || "",
1406
- description: fm.description || ""
1407
- }
1650
+ next: toPaginationEntry(first, routeMap)
1408
1651
  };
1409
1652
  }
1410
1653
  const paths = flattenRoutes();
@@ -1416,18 +1659,9 @@ function getPreviousNext(pathname) {
1416
1659
  const routeMap = getRouteMap();
1417
1660
  const prevHref = index > 0 ? paths[index - 1] : null;
1418
1661
  const nextHref = index < paths.length - 1 ? paths[index + 1] : null;
1419
- const prevFm = prevHref ? readPageFrontmatter(prevHref) : null;
1420
- const nextFm = nextHref ? readPageFrontmatter(nextHref) : null;
1421
1662
  return {
1422
- prev: prevHref ? {
1423
- href: prevHref,
1424
- title: prevFm?.title || routeMap.get(prevHref) || ""
1425
- } : null,
1426
- next: nextHref ? {
1427
- href: nextHref,
1428
- title: nextFm?.title || routeMap.get(nextHref) || "",
1429
- description: nextFm?.description || ""
1430
- } : null
1663
+ prev: prevHref ? toPaginationEntry(prevHref, routeMap) : null,
1664
+ next: nextHref ? toPaginationEntry(nextHref, routeMap) : null
1431
1665
  };
1432
1666
  }
1433
1667
  //#endregion
@@ -1438,7 +1672,8 @@ function Pagination({ pathname, className, prevIcon, nextIcon, linkClassName })
1438
1672
  return /* @__PURE__ */ jsx(PaginationDocs, {
1439
1673
  prev: prev ? {
1440
1674
  href: docsHtmlHref(`/docs${prev.href}`),
1441
- title: prev.title
1675
+ title: prev.title,
1676
+ description: prev.description
1442
1677
  } : void 0,
1443
1678
  next: next ? {
1444
1679
  href: docsHtmlHref(`/docs${next.href}`),
@@ -2417,7 +2652,7 @@ function htmlShell(opts) {
2417
2652
  ${favicon ? `<link rel="icon" type="image/x-icon" href="${escapeHtml(resolvePath(favicon))}">` : ""}${themeStyle}
2418
2653
  <link rel="preload" href="${escapeHtml(assetPrefix + css)}" as="style">
2419
2654
  <link rel="stylesheet" href="${escapeHtml(assetPrefix + css)}">
2420
- ${csp ? `<meta http-equiv="Content-Security-Policy" content="${escapeHtml(csp)}">` : ""}
2655
+ ${csp ? `<meta http-equiv="Content-Security-Policy" content="${escapeHtml(cspMeta(csp))}">` : ""}
2421
2656
  ${seoTags}
2422
2657
  <script${nonceAttr}>try{if(localStorage.getItem("theme")==="dark")document.documentElement.classList.add("dark")}catch(e){}<\/script>${headInjection}
2423
2658
  </head>
@@ -2462,6 +2697,6 @@ function hmrScript(nonce) {
2462
2697
  <\/script>`;
2463
2698
  }
2464
2699
  //#endregion
2465
- export { loadPlugins as S, registerPageContent as _, IndexPage as a, computeInlineThemeCss as b, captureException as c, compileMdx as d, compileMdxModule as f, getPageStripped as g, getPageFrontmatter as h, DocsLayout as i, initSentry as l, getPageContent as m, hmrScript as n, NotFoundPage as o, frontmatterField as p, htmlShell as r, DocsPage as s, errorHtml as t, generateSearchIndex as u, getGitLastModifiedBatch as v, BuildPluginBuilder as x, buildClientBundle as y };
2700
+ export { hashMdxSources as C, loadPlugins as D, BuildPluginBuilder as E, atomicWriteFile as S, runtimeStamp as T, getPageStripped as _, IndexPage as a, buildClientBundle as b, captureException as c, clearDerivedPageCaches as d, compileMdx as f, getPageFrontmatter as g, getPageContent as h, DocsLayout as i, initSentry as l, frontmatterField as m, hmrScript as n, NotFoundPage as o, compileMdxModule as p, htmlShell as r, DocsPage as s, errorHtml as t, generateSearchIndex as u, registerPageContent as v, hookMemoryPressure as w, computeInlineThemeCss as x, getGitLastModifiedBatch as y };
2466
2701
 
2467
- //# sourceMappingURL=html.shared-DSn-7_6t.js.map
2702
+ //# sourceMappingURL=html.shared-WwQnhDty.js.map