@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.
- package/.docu/components/Pagination.tsx +12 -1
- package/.docu/lib/build.deno.js +1 -1
- package/.docu/lib/{build.impl-BJsi28mD.js → build.impl-CT-YLyLn.js} +73 -25
- package/.docu/lib/build.impl-CT-YLyLn.js.map +1 -0
- package/.docu/lib/build.impl-cJPJeQ8r.js +2 -0
- package/.docu/lib/build.node.js +1 -1
- package/.docu/lib/clean.js +1 -1
- package/.docu/lib/deploy.deno.js +1 -1
- package/.docu/lib/deploy.node.js +1 -1
- package/.docu/lib/{deploy.shared-D3UWafa6.js → deploy.shared-CmOzm3b5.js} +3 -3
- package/.docu/lib/{deploy.shared-D3UWafa6.js.map → deploy.shared-CmOzm3b5.js.map} +1 -1
- package/.docu/lib/{html.shared-DSn-7_6t.js → html.shared-WwQnhDty.js} +269 -34
- package/.docu/lib/html.shared-WwQnhDty.js.map +1 -0
- package/.docu/lib/{logger-CycvLCrQ.js → logger-Cz0CPMi8.js} +9 -15
- package/.docu/lib/logger-Cz0CPMi8.js.map +1 -0
- package/.docu/lib/{paths-BtOIPBQ9.js → paths-Bl2cdp9E.js} +27 -3
- package/.docu/lib/paths-Bl2cdp9E.js.map +1 -0
- package/.docu/lib/preview.deno.js +1 -1
- package/.docu/lib/{preview.impl-CXJS2tQS.js → preview.impl-BaYhTRBW.js} +4 -4
- package/.docu/lib/{preview.impl-CXJS2tQS.js.map → preview.impl-BaYhTRBW.js.map} +1 -1
- package/.docu/lib/preview.node.js +1 -1
- package/.docu/lib/server.deno.js +1 -1
- package/.docu/lib/{server.impl-CJuWimfN.js → server.impl-l8hXfV_0.js} +7 -7
- package/.docu/lib/server.impl-l8hXfV_0.js.map +1 -0
- package/.docu/lib/server.node.js +1 -1
- package/.docu/lib/{utils-DA17MyQG.js → utils-B_CoyKie.js} +28 -6
- package/.docu/lib/utils-B_CoyKie.js.map +1 -0
- package/.docu/node/build.impl.ts +115 -43
- package/.docu/node/build.ts +134 -44
- package/.docu/node/cache-key.ts +311 -0
- package/.docu/node/html.shared.ts +2 -1
- package/.docu/node/html.ts +2 -1
- package/.docu/node/hydrate.node.ts +8 -11
- package/.docu/node/hydrate.ts +13 -14
- package/.docu/node/mdx.ts +14 -2
- package/.docu/node/paths.ts +27 -1
- package/.docu/node/plugin-builder.ts +10 -1
- package/.docu/node/route.ts +19 -21
- package/.docu/node/security.ts +18 -1
- package/.docu/node/server-routes.ts +3 -3
- package/.docu/node/types.ts +23 -5
- package/.docu/node/utils.ts +22 -2
- package/bin/cli.js +56 -18
- package/package.json +11 -17
- package/.docu/lib/build.impl-BJsi28mD.js.map +0 -1
- package/.docu/lib/build.impl-yVLaa1eQ.js +0 -2
- package/.docu/lib/html.shared-DSn-7_6t.js.map +0 -1
- package/.docu/lib/logger-CycvLCrQ.js.map +0 -1
- package/.docu/lib/paths-BtOIPBQ9.js.map +0 -1
- package/.docu/lib/server.impl-CJuWimfN.js.map +0 -1
- 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-
|
|
2
|
-
import {
|
|
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
|
-
|
|
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
|
|
883
|
+
/** Compute a cache key from globals.css + theme + config + toolchain. */
|
|
656
884
|
function tailwindCacheKey() {
|
|
657
|
-
const
|
|
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
|
|
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
|
|
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
|
-
|
|
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,
|
|
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-
|
|
2702
|
+
//# sourceMappingURL=html.shared-WwQnhDty.js.map
|