@docubook/flame 2.0.0-alpha.0 → 2.0.0-alpha.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.
Files changed (35) hide show
  1. package/.docu/components/Menu.tsx +38 -32
  2. package/.docu/components/Pagination.tsx +9 -1
  3. package/.docu/components/Sublink.tsx +72 -9
  4. package/.docu/components/Toc.tsx +3 -3
  5. package/.docu/lib/build.deno.js +3 -3
  6. package/.docu/lib/{build.impl-WR24HDUT.js → build.impl-AZBZN66Q.js} +3 -3
  7. package/.docu/lib/build.node.js +3 -3
  8. package/.docu/lib/{chunk-2EYRWRDP.js → chunk-3LRUTZZD.js} +6 -3
  9. package/.docu/lib/{chunk-QPF4DPZQ.js → chunk-42JQLAKP.js} +100 -20
  10. package/.docu/lib/{chunk-VPV7KP7K.js → chunk-HF3KKRQL.js} +7 -3
  11. package/.docu/lib/{chunk-AJV2GEDF.js → chunk-IN2QAGDZ.js} +1 -1
  12. package/.docu/lib/{chunk-KEWRVASF.js → chunk-PGIHPW5L.js} +1 -1
  13. package/.docu/lib/{chunk-X7KPVCDN.js → chunk-PJVCY4FK.js} +1 -1
  14. package/.docu/lib/clean.js +1 -1
  15. package/.docu/lib/deploy.deno.js +1 -1
  16. package/.docu/lib/deploy.node.js +1 -1
  17. package/.docu/lib/preview.deno.js +2 -2
  18. package/.docu/lib/preview.node.js +2 -2
  19. package/.docu/lib/server.deno.js +3 -3
  20. package/.docu/lib/server.node.js +3 -3
  21. package/.docu/node/build.impl.ts +3 -0
  22. package/.docu/node/build.ts +3 -0
  23. package/.docu/node/html.shared.ts +7 -2
  24. package/.docu/node/html.ts +4 -2
  25. package/.docu/node/route.ts +57 -1
  26. package/.docu/node/server-routes.ts +4 -0
  27. package/.docu/styles/globals.css +9 -0
  28. package/package.json +5 -5
  29. package/template/README.md +1 -1
  30. package/template/docs/getting-started/configuration.mdx +16 -4
  31. package/template/docs/getting-started/overview.mdx +34 -42
  32. package/template/docs/guide/components.mdx +46 -228
  33. package/template/docs/guide/routing.mdx +8 -6
  34. package/template/docs/index.mdx +9 -8
  35. package/template/docu.json +4 -4
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  runDeploy
3
- } from "./chunk-X7KPVCDN.js";
3
+ } from "./chunk-PJVCY4FK.js";
4
4
  import "./chunk-4IQXHHPF.js";
5
5
 
6
6
  // .docu/node/deploy.node.ts
@@ -1,11 +1,11 @@
1
1
  import {
2
2
  runPreview
3
- } from "./chunk-KEWRVASF.js";
3
+ } from "./chunk-PGIHPW5L.js";
4
4
  import {
5
5
  denoAdapter
6
6
  } from "./chunk-UISOJ4RW.js";
7
7
  import "./chunk-EOK6KATZ.js";
8
- import "./chunk-AJV2GEDF.js";
8
+ import "./chunk-IN2QAGDZ.js";
9
9
  import "./chunk-4IQXHHPF.js";
10
10
 
11
11
  // .docu/node/preview.deno.ts
@@ -1,11 +1,11 @@
1
1
  import {
2
2
  runPreview
3
- } from "./chunk-KEWRVASF.js";
3
+ } from "./chunk-PGIHPW5L.js";
4
4
  import {
5
5
  nodeAdapter
6
6
  } from "./chunk-UISOJ4RW.js";
7
7
  import "./chunk-EOK6KATZ.js";
8
- import "./chunk-AJV2GEDF.js";
8
+ import "./chunk-IN2QAGDZ.js";
9
9
  import "./chunk-4IQXHHPF.js";
10
10
 
11
11
  // .docu/node/preview.node.ts
@@ -1,12 +1,12 @@
1
1
  import {
2
2
  runServer
3
- } from "./chunk-VPV7KP7K.js";
4
- import "./chunk-QPF4DPZQ.js";
3
+ } from "./chunk-HF3KKRQL.js";
4
+ import "./chunk-42JQLAKP.js";
5
5
  import {
6
6
  denoAdapter
7
7
  } from "./chunk-UISOJ4RW.js";
8
8
  import "./chunk-EOK6KATZ.js";
9
- import "./chunk-AJV2GEDF.js";
9
+ import "./chunk-IN2QAGDZ.js";
10
10
  import "./chunk-4IQXHHPF.js";
11
11
 
12
12
  // .docu/node/server.deno.ts
@@ -1,12 +1,12 @@
1
1
  import {
2
2
  runServer
3
- } from "./chunk-VPV7KP7K.js";
4
- import "./chunk-QPF4DPZQ.js";
3
+ } from "./chunk-HF3KKRQL.js";
4
+ import "./chunk-42JQLAKP.js";
5
5
  import {
6
6
  nodeAdapter
7
7
  } from "./chunk-UISOJ4RW.js";
8
8
  import "./chunk-EOK6KATZ.js";
9
- import "./chunk-AJV2GEDF.js";
9
+ import "./chunk-IN2QAGDZ.js";
10
10
  import "./chunk-4IQXHHPF.js";
11
11
 
12
12
  // .docu/node/server.node.ts
@@ -436,6 +436,9 @@ export async function runBuild(): Promise<void> {
436
436
  js: assetManifest.js,
437
437
  nonce: notFoundNonce,
438
438
  themeCss: inlineThemeCss,
439
+ // Served as the static-host fallback at ANY requested path — relative
440
+ // depth can never be right there, so use root-absolute asset URLs.
441
+ absoluteAssets: true,
439
442
  });
440
443
  await writeFile(join(DIST_DIR, "404.html"), notFoundHtml);
441
444
 
@@ -418,6 +418,9 @@ async function build() {
418
418
  js: assetManifest.js,
419
419
  nonce: generateNonce(),
420
420
  themeCss: inlineThemeCss,
421
+ // Served as the static-host fallback at ANY requested path — relative
422
+ // depth can never be right there, so use root-absolute asset URLs.
423
+ absoluteAssets: true,
421
424
  });
422
425
  await writeFile(join(DIST_DIR, "404.html"), notFoundHtml);
423
426
 
@@ -34,6 +34,9 @@ export interface HtmlShellOptions {
34
34
  bodyExtra?: string[];
35
35
  /** SEO meta tags derived from config + frontmatter */
36
36
  seo?: SeoMeta;
37
+ /** Root-absolute asset URLs (`/assets/...`). Required for pages served at
38
+ * arbitrary paths (404 fallback) — relative depth is wrong there. */
39
+ absoluteAssets?: boolean;
37
40
  }
38
41
 
39
42
  export function htmlShell(opts: HtmlShellOptions): string {
@@ -51,14 +54,16 @@ export function htmlShell(opts: HtmlShellOptions): string {
51
54
  depth = 0,
52
55
  headExtra,
53
56
  bodyExtra,
57
+ absoluteAssets = false,
54
58
  } = opts;
55
59
  const nonceAttr = nonce ? ` nonce="${escapeHtml(nonce)}"` : "";
56
60
  const themeStyle = themeCss ? `\n <style${nonceAttr}>${escapeHtml(themeCss)}</style>` : "";
57
61
  const headInjection = headExtra?.length ? `\n ${headExtra.join("\n ")}` : "";
58
62
  const bodyInjection = bodyExtra?.length ? `\n ${bodyExtra.join("\n ")}` : "";
59
63
  const depthPrefix = depth === 0 ? "" : "../".repeat(depth);
60
- const assetPrefix = depthPrefix + "assets/";
61
- const resolvePath = (path: string) => (path.startsWith("/") ? depthPrefix + path.slice(1) : path);
64
+ const assetPrefix = absoluteAssets ? "/assets/" : depthPrefix + "assets/";
65
+ const resolvePath = (path: string) =>
66
+ absoluteAssets ? path : path.startsWith("/") ? depthPrefix + path.slice(1) : path;
62
67
 
63
68
  // Build SEO meta tags (OG, Twitter, canonical)
64
69
  let seoTags = "";
@@ -16,14 +16,16 @@ export function htmlShell(opts: HtmlShellOptions): string {
16
16
  depth = 0,
17
17
  headExtra,
18
18
  bodyExtra,
19
+ absoluteAssets = false,
19
20
  } = opts;
20
21
  const nonceAttr = nonce ? ` nonce="${Bun.escapeHTML(nonce)}"` : "";
21
22
  const themeStyle = themeCss ? `\n <style${nonceAttr}>${Bun.escapeHTML(themeCss)}</style>` : "";
22
23
  const headInjection = headExtra?.length ? `\n ${headExtra.join("\n ")}` : "";
23
24
  const bodyInjection = bodyExtra?.length ? `\n ${bodyExtra.join("\n ")}` : "";
24
25
  const depthPrefix = depth === 0 ? "" : "../".repeat(depth);
25
- const assetPrefix = depthPrefix + "assets/";
26
- const resolvePath = (path: string) => (path.startsWith("/") ? depthPrefix + path.slice(1) : path);
26
+ const assetPrefix = absoluteAssets ? "/assets/" : depthPrefix + "assets/";
27
+ const resolvePath = (path: string) =>
28
+ absoluteAssets ? path : path.startsWith("/") ? depthPrefix + path.slice(1) : path;
27
29
 
28
30
  // Build SEO meta tags (OG, Twitter, canonical)
29
31
  let seoTags = "";
@@ -1,6 +1,11 @@
1
1
  import { loadDocuConfig } from "./paths";
2
2
  import type { DocuRoute } from "./types";
3
3
  import { resolveRoutes } from "./fs-scanner";
4
+ import { DOCS_DIR } from "./paths";
5
+ import { readFileSync } from "node:fs";
6
+ import { join } from "node:path";
7
+ import { extractFrontmatter } from "@docubook/core";
8
+ import type { Frontmatter } from "./mdx";
4
9
 
5
10
  const docuConfig = loadDocuConfig();
6
11
  export const routes: DocuRoute[] = resolveRoutes(docuConfig.routes);
@@ -41,8 +46,53 @@ export function getRouteMap(): Map<string, string> {
41
46
  return map;
42
47
  }
43
48
 
49
+ /** Build-time cache of href → frontmatter description (docs content is static). */
50
+ const descriptionCache = new Map<string, string>();
51
+
52
+ function readDescription(href: string): string {
53
+ const cached = descriptionCache.get(href);
54
+ if (cached !== undefined) return cached;
55
+
56
+ let description = "";
57
+ const rel = href.replace(/^\/|$/g, "");
58
+ for (const ext of [".mdx", ".md"]) {
59
+ for (const file of [join(DOCS_DIR, `${rel}${ext}`), join(DOCS_DIR, `${rel}/index${ext}`)]) {
60
+ try {
61
+ const fm = extractFrontmatter<Frontmatter>(readFileSync(file, "utf-8"));
62
+ description = typeof fm.description === "string" ? fm.description : "";
63
+ if (description) break;
64
+ } catch {
65
+ // not this file — try the next candidate
66
+ }
67
+ }
68
+ if (description) break;
69
+ }
70
+ descriptionCache.set(href, description);
71
+ return description;
72
+ }
73
+
44
74
  export function getPreviousNext(pathname: string) {
45
75
  const normalizedPath = pathname.replace(/^\/|$/g, "");
76
+
77
+ // Docs index (/docs — DocsPage renders with pathname "" from slug []):
78
+ // next-only navigation into the first docs page — never read the route
79
+ // backward from the index, so prev stays null even if a page sits before
80
+ // it in the route list.
81
+ if (normalizedPath === "docs" || normalizedPath === "") {
82
+ const paths = flattenRoutes();
83
+ const routeMap = getRouteMap();
84
+ const first = paths[0];
85
+ if (!first) return { prev: null, next: null };
86
+ return {
87
+ prev: null,
88
+ next: {
89
+ href: first,
90
+ title: routeMap.get(first) || "",
91
+ description: readDescription(first),
92
+ },
93
+ };
94
+ }
95
+
46
96
  const paths = flattenRoutes();
47
97
 
48
98
  const index = paths.findIndex((href) => href === `/${normalizedPath}` || href === normalizedPath);
@@ -57,7 +107,13 @@ export function getPreviousNext(pathname: string) {
57
107
 
58
108
  return {
59
109
  prev: prevHref ? { href: prevHref, title: routeMap.get(prevHref) || "" } : null,
60
- next: nextHref ? { href: nextHref, title: routeMap.get(nextHref) || "" } : null,
110
+ next: nextHref
111
+ ? {
112
+ href: nextHref,
113
+ title: routeMap.get(nextHref) || "",
114
+ description: readDescription(nextHref),
115
+ }
116
+ : null,
61
117
  };
62
118
  }
63
119
 
@@ -44,6 +44,10 @@ function createHtmlResponse(
44
44
  extraScripts: hmrScript(nonce),
45
45
  themeCss: state.inlineThemeCss,
46
46
  depth,
47
+ // 404 pages can be requested at arbitrary depths (e.g. a noLink section
48
+ // path typed in the address bar) — relative asset paths would resolve
49
+ // against the wrong directory and break CSS/JS.
50
+ absoluteAssets: status === 404,
47
51
  });
48
52
  /** Dev-only: serves compiledSource → MDXRemote eval path (no CSP in production). */
49
53
  return htmlResponse(html, nonce, status, true);
@@ -9,6 +9,15 @@
9
9
  @plugin "@tailwindcss/typography";
10
10
  @source "../../.docu/components";
11
11
  @source "../../.docu/pages";
12
+ @import "@docubook/ui-react/styles.css";
13
+
14
+ /* daisyUI breadcrumbs underline every li child on hover (including plain
15
+ spans) — crumbs are not links, so strip the underline (and pointer cursor)
16
+ for non-anchor items; real anchors keep daisyUI's hover feedback. */
17
+ .breadcrumbs > ul > li > :not(a):hover {
18
+ text-decoration-line: none;
19
+ cursor: default;
20
+ }
12
21
  @source inline(
13
22
  "breadcrumbs collapse collapse-open collapse-close collapse-arrow collapse-plus collapse-title collapse-content"
14
23
  );
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@docubook/flame",
3
- "version": "2.0.0-alpha.0",
3
+ "version": "2.0.0-alpha.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": {
@@ -56,10 +56,10 @@
56
56
  "react-dom": "^19.2.7",
57
57
  "unified": "^11.0.0",
58
58
  "zod": "^4.4.3",
59
- "@docubook/core": "^2.0.0-alpha.0",
60
- "@docubook/themes-colors": "^2.0.0-alpha.0",
61
- "@docubook/ui-react": "^2.0.0-alpha.0",
62
- "@docubook/markdown": "^2.0.0-alpha.0"
59
+ "@docubook/markdown": "^2.0.0-alpha.2",
60
+ "@docubook/ui-react": "^2.0.0-alpha.2",
61
+ "@docubook/themes-colors": "^2.0.0-alpha.2",
62
+ "@docubook/core": "^2.0.0-alpha.2"
63
63
  },
64
64
  "peerDependencies": {
65
65
  "@sentry/bun": "^10.0.0"
@@ -42,7 +42,7 @@ deno task dev
42
42
 
43
43
  ## Documentation
44
44
 
45
- For the full documentation, please visit **[packages/flame/docs](https://github.com/DocuBook/docubook/tree/main/packages/flame/docs)** or read the official site [docubook.pro](https://docubook.pro)
45
+ For the full documentation, visit **[www.docubook.pro](https://www.docubook.pro/)**
46
46
 
47
47
  ---
48
48
 
@@ -3,16 +3,28 @@ title: Configuration
3
3
  description: docu.json reference — meta, navbar, themes, routes, and plugins.
4
4
  ---
5
5
 
6
- `docu.json` in your project root controls the site. Key sections:
6
+ `docu.json` in the project root controls the whole site. It is validated against `docu.schema.json`.
7
+
8
+ ## First edits
9
+
10
+ | What | Where |
11
+ |---|---|
12
+ | Site name & tagline | `meta.title`, `meta.description` |
13
+ | Brand in the header | `navbar.logoText` |
14
+ | Landing copy | `home.hero` — headline, description, actions |
15
+ | Colour preset | `themes.colors` — `default`, `freshlime`, `coffee` |
16
+ | Footer links | `footer.social` |
17
+
18
+ ## Reference
7
19
 
8
20
  | Field | Description |
9
21
  |---|---|
10
22
  | `meta` | Site title, description, favicon, base URL |
11
23
  | `navbar` | Logo, navigation menu links |
12
- | `home.hero` | Landing page hero with tagline, headline, actions |
13
- | `home.features` | Feature cards with icon, title, description |
24
+ | `home.hero` | Landing page hero — tagline, headline, actions |
25
+ | `home.features` | Feature cards — icon, title, description |
14
26
  | `routes` | Sidebar navigation (auto-detected from `docs/` when empty) |
15
27
  | `themes` | Colour preset or custom palette |
16
28
  | `plugins` | Build/dev pipeline extensions |
17
29
 
18
- See this site's `docu.json` for a complete example, or refer to `docu.schema.json` in the package root.
30
+ This project's `docu.json` is a complete working example — edit it and the dev server applies the changes live.
@@ -1,50 +1,42 @@
1
1
  ---
2
2
  title: Quick Start
3
- description: Get your first documentation site running on Bun, Node.js, or Deno.
3
+ description: The Flame workflow — dev server, first edit, authoring, and build.
4
4
  ---
5
5
 
6
- ## Prerequisites
7
-
8
- Choose **one** runtime:
9
-
10
- - **Bun** >= 1.1: `curl -fsSL https://bun.sh/install | bash`
11
- - **Node.js** >= 20.11: [nodejs.org](https://nodejs.org)
12
- - **Deno** >= 2.x: `curl -fsSL https://deno.land/install.sh | sh`
13
-
14
- ## Create a project
15
-
16
- <Tabs>
17
- <Tab title="Bun">
18
- ```bash
19
- mkdir my-docs && cd my-docs
20
- bun add @docubook/flame
21
- bunx flame init
22
- bun run dev
23
- ```
24
- </Tab>
25
- <Tab title="Node.js">
26
- ```bash
27
- mkdir my-docs && cd my-docs
28
- npm install @docubook/flame
29
- npx flame init
30
- npm run dev
31
- ```
32
- </Tab>
33
- <Tab title="Deno">
34
- ```bash
35
- mkdir my-docs && cd my-docs
36
- deno run -A npm:@docubook/flame init
37
- deno task dev
38
- ```
39
- </Tab>
40
- </Tabs>
41
-
42
- Open http://localhost:3000 — changes to `docs/` or `docu.json` hot-reload.
43
-
44
- ## Build for production
6
+ Your Flame project is ready — this is the workflow to make it yours.
7
+
8
+ ## 1. Run the dev server
9
+
10
+ ```bash
11
+ bun run dev # or: npm run dev / deno task dev
12
+ ```
13
+
14
+ Open http://localhost:3000 — edits to `docs/` and `docu.json` hot-reload instantly.
15
+
16
+ ## 2. Make your first edit
17
+
18
+ Open `docs/getting-started/overview.mdx` (this file):
19
+
20
+ 1. Change `title` and `description` in the frontmatter — the browser updates live
21
+ 2. Add a heading below and save
22
+ 3. New pages appear in the sidebar and search automatically
23
+
24
+ ## 3. Author with directives
25
+
26
+ Content is plain markdown — components are directives, no JSX:
27
+
28
+ ```md
29
+ :::tip
30
+ A callout — no JSX needed.
31
+ :::
32
+ ```
33
+
34
+ See [Components](/docs/guide/components) for the full directive set.
35
+
36
+ ## 4. Build for production
45
37
 
46
38
  ```bash
47
- npm run build # or: bun run build / deno task build
39
+ bun run build # or: npm run build / deno task build
48
40
  ```
49
41
 
50
- Static output goes to `.docu/dist/` — deploy to any CDN or static host.
42
+ Flat static HTML lands in `.docu/dist/` — deploy anywhere ([Deployment](/docs/guide/deployment)).