@docubook/flame 1.3.1 → 1.3.2

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.
@@ -7,7 +7,7 @@ import type { LucideIcon } from "lucide-react";
7
7
  */
8
8
  export function getLucideIcon(name: string): LucideIcon | null {
9
9
  if (!name) return null;
10
- const icon = (LucideIcons as Record<string, LucideIcon | undefined>)[name];
10
+ const icon = (LucideIcons as unknown as Record<string, LucideIcon | undefined>)[name];
11
11
  return icon || null;
12
12
  }
13
13
 
@@ -212,16 +212,16 @@ export default function Search({ className }: SearchProps) {
212
212
 
213
213
  <div className="border-base-300 hidden items-center gap-3 border-t px-4 py-2.5 md:flex">
214
214
  <div className="flex items-center gap-1">
215
- <Kbd size="s">
215
+ <Kbd size="sm">
216
216
  <FnKey.Down />
217
217
  </Kbd>
218
- <Kbd size="s">
218
+ <Kbd size="sm">
219
219
  <FnKey.Up />
220
220
  </Kbd>
221
221
  <span className="text-base-content/50 text-xs">navigate</span>
222
222
  </div>
223
223
  <div className="flex items-center gap-1">
224
- <Kbd size="s">
224
+ <Kbd size="sm">
225
225
  <CornerDownLeft className="h-3 w-3" />
226
226
  </Kbd>
227
227
  <span className="text-base-content/50 text-xs">select</span>
@@ -138,7 +138,8 @@ async function renderDocsPage(
138
138
  const headExtra = builder?.collectHead(ctx);
139
139
  const bodyExtra = builder?.collectBody(ctx);
140
140
 
141
- const favicon = docuConfig.meta?.favicon || "/favicon.ico";
141
+ const depth = slug ? slug.split("/").length : 1;
142
+ const favicon = docuConfig.meta?.favicon || "/docs/assets/images/favicon.ico";
142
143
  let html = htmlShell({
143
144
  title,
144
145
  description,
@@ -148,6 +149,7 @@ async function renderDocsPage(
148
149
  js: assetManifest.js,
149
150
  nonce,
150
151
  themeCss: inlineThemeCss,
152
+ depth,
151
153
  headExtra,
152
154
  bodyExtra,
153
155
  });
@@ -332,7 +334,7 @@ async function build() {
332
334
  }
333
335
 
334
336
  const landingPage = React.createElement(IndexPage);
335
- const landingFavicon = docuConfig.meta?.favicon || "/favicon.ico";
337
+ const landingFavicon = docuConfig.meta?.favicon || "/docs/assets/images/favicon.ico";
336
338
  const landingHtml = htmlShell({
337
339
  title: docuConfig.meta?.title || "DocuBook",
338
340
  description: docuConfig.meta?.description || "",
@@ -350,7 +352,7 @@ async function build() {
350
352
  { repoUrl: docuConfig.repo?.url },
351
353
  React.createElement(NotFoundPage)
352
354
  );
353
- const notFoundFavicon = docuConfig.meta?.favicon || "/favicon.ico";
355
+ const notFoundFavicon = docuConfig.meta?.favicon || "/docs/assets/images/favicon.ico";
354
356
  const notFoundHtml = htmlShell({
355
357
  title: "404 - Not Found",
356
358
  description: "",
@@ -14,6 +14,8 @@ export interface HtmlShellOptions {
14
14
  csp?: string;
15
15
  extraScripts?: string;
16
16
  themeCss?: string;
17
+ /** Depth from document root (0=root, 1=subdir, 2=sub/subdir). Used for relative asset paths. */
18
+ depth?: number;
17
19
  /** HTML strings to inject before `</head>` (from plugin `injectHead` hooks). */
18
20
  headExtra?: string[];
19
21
  /** HTML strings to inject before `</body>`, after the main script (from plugin `injectBody` hooks). */
@@ -32,6 +34,7 @@ export function htmlShell(opts: HtmlShellOptions): string {
32
34
  csp,
33
35
  extraScripts,
34
36
  themeCss,
37
+ depth = 0,
35
38
  headExtra,
36
39
  bodyExtra,
37
40
  } = opts;
@@ -39,6 +42,9 @@ export function htmlShell(opts: HtmlShellOptions): string {
39
42
  const themeStyle = themeCss ? `\n <style${nonceAttr}>${Bun.escapeHTML(themeCss)}</style>` : "";
40
43
  const headInjection = headExtra?.length ? `\n ${headExtra.join("\n ")}` : "";
41
44
  const bodyInjection = bodyExtra?.length ? `\n ${bodyExtra.join("\n ")}` : "";
45
+ const depthPrefix = depth === 0 ? "" : "../".repeat(depth);
46
+ const assetPrefix = depthPrefix + "assets/";
47
+ const resolvePath = (path: string) => (path.startsWith("/") ? depthPrefix + path.slice(1) : path);
42
48
  return `<!DOCTYPE html>
43
49
  <html lang="en">
44
50
  <head>
@@ -46,14 +52,14 @@ export function htmlShell(opts: HtmlShellOptions): string {
46
52
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
47
53
  <title>${Bun.escapeHTML(title)}</title>
48
54
  <meta name="description" content="${Bun.escapeHTML(description)}">
49
- <link rel="icon" type="image/x-icon" href="${Bun.escapeHTML(favicon)}">${themeStyle}
50
- <link rel="stylesheet" href="/assets/${Bun.escapeHTML(css)}">
55
+ ${favicon ? `<link rel="icon" type="image/x-icon" href="${Bun.escapeHTML(resolvePath(favicon))}">` : ""}${themeStyle}
56
+ <link rel="stylesheet" href="${Bun.escapeHTML(assetPrefix + css)}">
51
57
  ${csp ? `<meta http-equiv="Content-Security-Policy" content="${Bun.escapeHTML(csp)}">` : ""}
52
58
  <script${nonceAttr}>try{if(localStorage.getItem("theme")==="dark")document.documentElement.classList.add("dark")}catch(e){}</script>${headInjection}
53
59
  </head>
54
60
  <body>
55
61
  <div id="root">${body}</div>
56
- <script${nonceAttr} src="/assets/${Bun.escapeHTML(js)}"></script>${extraScripts ? `\n ${extraScripts}` : ""}${bodyInjection}
62
+ <script${nonceAttr} src="${Bun.escapeHTML(assetPrefix + js)}"></script>${extraScripts ? `\n ${extraScripts}` : ""}${bodyInjection}
57
63
  </body>
58
64
  </html>`;
59
65
  }
@@ -55,6 +55,8 @@ export interface DevServerContext {
55
55
  hostname: string;
56
56
  }
57
57
 
58
+ export type { DocuConfig };
59
+
58
60
  // ─── PluginBuilder Interface ────────────────────────────
59
61
 
60
62
  /**
@@ -19,7 +19,7 @@ import { htmlShell as createHtmlShell, hmrScript, errorHtml } from "./html";
19
19
  export interface ServerState {
20
20
  docuConfig: DocuConfig;
21
21
  assetManifest: { css: string; js: string };
22
- inlineThemeCss: string;
22
+ inlineThemeCss?: string;
23
23
  builder: BuildPluginBuilder | null;
24
24
  }
25
25
 
@@ -103,8 +103,8 @@ const server = Bun.serve({
103
103
 
104
104
  if (builder) {
105
105
  const pluginResponse = await builder.runHandleRequest(req, {
106
- port: server.port,
107
- hostname: server.hostname,
106
+ port: server.port!,
107
+ hostname: server.hostname!,
108
108
  });
109
109
  if (pluginResponse) {
110
110
  logger.request(
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@docubook/flame",
3
- "version": "1.3.1",
3
+ "version": "1.3.2",
4
4
  "description": "A blazing-fast React + MDX framework powered by Bun, built for modern documentation experiences.",
5
5
  "type": "module",
6
6
  "bin": {
@@ -49,12 +49,13 @@
49
49
  "bun-plugin-tailwind": "^0.1.2",
50
50
  "daisyui": "^5.5.19",
51
51
  "lucide-react": "^1.14.0",
52
- "react": "^19.0.0",
53
- "react-dom": "^19.0.0",
54
- "@docubook/mdx-content": "^3.2.2",
52
+ "react": "^19.2.7",
53
+ "react-dom": "^19.2.7",
54
+ "unified": "^11.0.0",
55
55
  "@docubook/core": "^1.7.2",
56
- "@docubook/themes-colors": "^0.10.2",
57
- "@docubook/ui-react": "^0.1.4"
56
+ "@docubook/mdx-content": "^3.2.2",
57
+ "@docubook/ui-react": "^0.1.4",
58
+ "@docubook/themes-colors": "^0.10.2"
58
59
  },
59
60
  "peerDependencies": {
60
61
  "@sentry/bun": "^10.0.0"