boltdocs 1.10.2 → 2.0.0
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/CHANGELOG.md +7 -0
- package/LICENSE +21 -0
- package/dist/cache-7G6D532T.mjs +1 -0
- package/dist/chunk-A4HQPEPU.mjs +1 -0
- package/dist/chunk-BA5NH5HU.mjs +1 -0
- package/dist/chunk-BQCD3DWG.mjs +1 -0
- package/dist/chunk-H63UMKYF.mjs +1 -0
- package/dist/chunk-IWHRQHS7.mjs +1 -0
- package/dist/chunk-JZXLCA2E.mjs +1 -0
- package/dist/chunk-MFU7Q6WF.mjs +1 -0
- package/dist/chunk-QYPNX5UN.mjs +1 -0
- package/dist/chunk-XEAPSFMB.mjs +1 -0
- package/dist/client/components/mdx/index.d.mts +209 -0
- package/dist/client/components/mdx/index.d.ts +209 -0
- package/dist/client/components/mdx/index.js +1 -0
- package/dist/client/components/mdx/index.mjs +1 -0
- package/dist/client/hooks/index.d.mts +133 -0
- package/dist/client/hooks/index.d.ts +133 -0
- package/dist/client/hooks/index.js +1 -0
- package/dist/client/hooks/index.mjs +1 -0
- package/dist/client/index.d.mts +138 -298
- package/dist/client/index.d.ts +138 -298
- package/dist/client/index.js +1 -3630
- package/dist/client/index.mjs +1 -697
- package/dist/client/ssr.d.mts +7 -3
- package/dist/client/ssr.d.ts +7 -3
- package/dist/client/ssr.js +1 -2928
- package/dist/client/ssr.mjs +1 -33
- package/dist/{config-BsFQ-ErD.d.ts → config-CX4l-ZNp.d.mts} +42 -35
- package/dist/{config-BsFQ-ErD.d.mts → config-CX4l-ZNp.d.ts} +42 -35
- package/dist/node/index.d.mts +2 -4
- package/dist/node/index.d.ts +2 -4
- package/dist/node/index.js +31 -1161
- package/dist/node/index.mjs +31 -736
- package/dist/search-dialog-EB3N4TYM.mjs +1 -0
- package/dist/types-BuZWFT7r.d.ts +159 -0
- package/dist/types-CvT-SGbK.d.mts +159 -0
- package/dist/use-routes-5bAtAAYX.d.mts +30 -0
- package/dist/use-routes-BefRXY3v.d.ts +30 -0
- package/package.json +34 -12
- package/src/client/app/config-context.tsx +18 -0
- package/src/client/app/docs-layout.tsx +14 -0
- package/src/client/app/index.tsx +137 -262
- package/src/client/app/mdx-component.tsx +52 -0
- package/src/client/app/mdx-components-context.tsx +23 -0
- package/src/client/app/mdx-page.tsx +20 -0
- package/src/client/app/preload.tsx +38 -30
- package/src/client/app/router.tsx +30 -0
- package/src/client/app/scroll-handler.tsx +40 -0
- package/src/client/app/theme-context.tsx +75 -0
- package/src/client/components/default-layout.tsx +80 -0
- package/src/client/components/docs-layout.tsx +105 -0
- package/src/client/components/icons-dev.tsx +74 -0
- package/src/client/components/mdx/admonition.tsx +107 -0
- package/src/client/components/mdx/badge.tsx +41 -0
- package/src/client/components/mdx/button.tsx +35 -0
- package/src/client/components/mdx/card.tsx +124 -0
- package/src/client/components/mdx/code-block.tsx +119 -0
- package/src/client/components/mdx/component-preview.tsx +47 -0
- package/src/client/components/mdx/component-props.tsx +83 -0
- package/src/client/components/mdx/field.tsx +66 -0
- package/src/client/components/mdx/file-tree.tsx +287 -0
- package/src/client/components/mdx/hooks/use-code-block.ts +56 -0
- package/src/client/components/mdx/hooks/use-component-preview.ts +16 -0
- package/src/client/components/mdx/hooks/useTable.ts +74 -0
- package/src/client/components/mdx/hooks/useTabs.ts +68 -0
- package/src/client/components/mdx/image.tsx +23 -0
- package/src/client/components/mdx/index.ts +53 -0
- package/src/client/components/mdx/link.tsx +38 -0
- package/src/client/components/mdx/list.tsx +192 -0
- package/src/client/components/mdx/table.tsx +156 -0
- package/src/client/components/mdx/tabs.tsx +135 -0
- package/src/client/components/mdx/video.tsx +68 -0
- package/src/client/components/primitives/breadcrumbs.tsx +79 -0
- package/src/client/components/primitives/button-group.tsx +54 -0
- package/src/client/components/primitives/button.tsx +145 -0
- package/src/client/components/primitives/helpers/observer.ts +120 -0
- package/src/client/components/primitives/index.ts +17 -0
- package/src/client/components/primitives/link.tsx +122 -0
- package/src/client/components/primitives/menu.tsx +159 -0
- package/src/client/components/primitives/navbar.tsx +359 -0
- package/src/client/components/primitives/navigation-menu.tsx +116 -0
- package/src/client/components/primitives/on-this-page.tsx +461 -0
- package/src/client/components/primitives/page-nav.tsx +87 -0
- package/src/client/components/primitives/popover.tsx +47 -0
- package/src/client/components/primitives/search-dialog.tsx +183 -0
- package/src/client/components/primitives/sidebar.tsx +154 -0
- package/src/client/components/primitives/tabs.tsx +90 -0
- package/src/client/components/primitives/tooltip.tsx +83 -0
- package/src/client/components/primitives/types.ts +11 -0
- package/src/client/components/ui-base/breadcrumbs.tsx +42 -0
- package/src/client/components/ui-base/copy-markdown.tsx +112 -0
- package/src/client/components/ui-base/error-boundary.tsx +52 -0
- package/src/client/components/ui-base/github-stars.tsx +27 -0
- package/src/client/components/ui-base/head.tsx +69 -0
- package/src/client/components/ui-base/loading.tsx +87 -0
- package/src/client/components/ui-base/navbar.tsx +138 -0
- package/src/client/components/ui-base/not-found.tsx +24 -0
- package/src/client/components/ui-base/on-this-page.tsx +152 -0
- package/src/client/components/ui-base/page-nav.tsx +39 -0
- package/src/client/components/ui-base/powered-by.tsx +19 -0
- package/src/client/components/ui-base/progress-bar.tsx +67 -0
- package/src/client/components/ui-base/search-dialog.tsx +82 -0
- package/src/client/components/ui-base/sidebar.tsx +104 -0
- package/src/client/components/ui-base/tabs.tsx +65 -0
- package/src/client/components/ui-base/theme-toggle.tsx +32 -0
- package/src/client/hooks/index.ts +12 -0
- package/src/client/hooks/use-breadcrumbs.ts +22 -0
- package/src/client/hooks/use-i18n.ts +84 -0
- package/src/client/hooks/use-localized-to.ts +95 -0
- package/src/client/hooks/use-location.ts +5 -0
- package/src/client/hooks/use-navbar.ts +60 -0
- package/src/client/hooks/use-onthispage.ts +23 -0
- package/src/client/hooks/use-page-nav.ts +22 -0
- package/src/client/hooks/use-routes.ts +72 -0
- package/src/client/hooks/use-search.ts +71 -0
- package/src/client/hooks/use-sidebar.ts +49 -0
- package/src/client/hooks/use-tabs.ts +43 -0
- package/src/client/hooks/use-version.ts +78 -0
- package/src/client/index.ts +55 -17
- package/src/client/integrations/codesandbox.ts +179 -0
- package/src/client/ssr.tsx +27 -16
- package/src/client/theme/neutral.css +360 -0
- package/src/client/types.ts +131 -27
- package/src/client/utils/cn.ts +6 -0
- package/src/client/utils/copy-clipboard.ts +22 -0
- package/src/client/utils/get-base-file-path.ts +21 -0
- package/src/client/utils/github.ts +121 -0
- package/src/client/utils/use-on-change.ts +15 -0
- package/src/client/virtual.d.ts +24 -0
- package/src/node/cache.ts +156 -156
- package/src/node/config.ts +159 -103
- package/src/node/index.ts +13 -13
- package/src/node/mdx.ts +213 -61
- package/src/node/plugin/entry.ts +29 -18
- package/src/node/plugin/html.ts +11 -11
- package/src/node/plugin/index.ts +161 -84
- package/src/node/plugin/types.ts +2 -4
- package/src/node/routes/cache.ts +6 -6
- package/src/node/routes/index.ts +206 -113
- package/src/node/routes/parser.ts +102 -82
- package/src/node/routes/sorter.ts +15 -15
- package/src/node/routes/types.ts +24 -24
- package/src/node/ssg/index.ts +73 -47
- package/src/node/ssg/meta.ts +4 -4
- package/src/node/ssg/options.ts +5 -5
- package/src/node/ssg/sitemap.ts +14 -14
- package/src/node/utils.ts +54 -31
- package/tsconfig.json +25 -20
- package/tsup.config.ts +23 -14
- package/dist/PackageManagerTabs-NVT7G625.mjs +0 -99
- package/dist/SearchDialog-AGVF6JBO.mjs +0 -194
- package/dist/SearchDialog-YPDOM7Q6.css +0 -2847
- package/dist/Video-KNTY5BNO.mjs +0 -6
- package/dist/cache-KNL5B4EE.mjs +0 -12
- package/dist/chunk-7SFUJWTB.mjs +0 -211
- package/dist/chunk-FFBNU6IJ.mjs +0 -386
- package/dist/chunk-FMTOYQLO.mjs +0 -37
- package/dist/chunk-TKLQWU7H.mjs +0 -1920
- package/dist/chunk-Z7JHYNAS.mjs +0 -57
- package/dist/client/index.css +0 -2847
- package/dist/client/ssr.css +0 -2847
- package/dist/types-Dj-bfnC3.d.mts +0 -74
- package/dist/types-Dj-bfnC3.d.ts +0 -74
- package/src/client/theme/components/CodeBlock/CodeBlock.tsx +0 -61
- package/src/client/theme/components/CodeBlock/index.ts +0 -1
- package/src/client/theme/components/PackageManagerTabs/PackageManagerTabs.tsx +0 -131
- package/src/client/theme/components/PackageManagerTabs/index.ts +0 -1
- package/src/client/theme/components/PackageManagerTabs/pkg-tabs.css +0 -64
- package/src/client/theme/components/Playground/Playground.tsx +0 -180
- package/src/client/theme/components/Playground/index.ts +0 -1
- package/src/client/theme/components/Playground/playground.css +0 -238
- package/src/client/theme/components/Video/Video.tsx +0 -84
- package/src/client/theme/components/Video/index.ts +0 -1
- package/src/client/theme/components/Video/video.css +0 -41
- package/src/client/theme/components/mdx/Admonition.tsx +0 -80
- package/src/client/theme/components/mdx/Badge.tsx +0 -31
- package/src/client/theme/components/mdx/Button.tsx +0 -50
- package/src/client/theme/components/mdx/Card.tsx +0 -80
- package/src/client/theme/components/mdx/Field.tsx +0 -60
- package/src/client/theme/components/mdx/FileTree.tsx +0 -229
- package/src/client/theme/components/mdx/List.tsx +0 -57
- package/src/client/theme/components/mdx/Table.tsx +0 -151
- package/src/client/theme/components/mdx/Tabs.tsx +0 -123
- package/src/client/theme/components/mdx/index.ts +0 -27
- package/src/client/theme/components/mdx/mdx-components.css +0 -764
- package/src/client/theme/icons/bun.tsx +0 -62
- package/src/client/theme/icons/deno.tsx +0 -20
- package/src/client/theme/icons/discord.tsx +0 -12
- package/src/client/theme/icons/github.tsx +0 -15
- package/src/client/theme/icons/npm.tsx +0 -13
- package/src/client/theme/icons/pnpm.tsx +0 -72
- package/src/client/theme/icons/twitter.tsx +0 -12
- package/src/client/theme/styles/markdown.css +0 -394
- package/src/client/theme/styles/variables.css +0 -175
- package/src/client/theme/styles.css +0 -39
- package/src/client/theme/ui/Breadcrumbs/Breadcrumbs.tsx +0 -68
- package/src/client/theme/ui/Breadcrumbs/index.ts +0 -1
- package/src/client/theme/ui/CopyMarkdown/CopyMarkdown.tsx +0 -82
- package/src/client/theme/ui/CopyMarkdown/copy-markdown.css +0 -112
- package/src/client/theme/ui/CopyMarkdown/index.ts +0 -1
- package/src/client/theme/ui/ErrorBoundary/ErrorBoundary.tsx +0 -50
- package/src/client/theme/ui/ErrorBoundary/error-boundary.css +0 -55
- package/src/client/theme/ui/ErrorBoundary/index.ts +0 -1
- package/src/client/theme/ui/Footer/footer.css +0 -32
- package/src/client/theme/ui/Head/Head.tsx +0 -69
- package/src/client/theme/ui/Head/index.ts +0 -1
- package/src/client/theme/ui/LanguageSwitcher/LanguageSwitcher.tsx +0 -125
- package/src/client/theme/ui/LanguageSwitcher/index.ts +0 -1
- package/src/client/theme/ui/LanguageSwitcher/language-switcher.css +0 -98
- package/src/client/theme/ui/Layout/Layout.tsx +0 -203
- package/src/client/theme/ui/Layout/base.css +0 -106
- package/src/client/theme/ui/Layout/index.ts +0 -2
- package/src/client/theme/ui/Layout/pagination.css +0 -72
- package/src/client/theme/ui/Layout/responsive.css +0 -47
- package/src/client/theme/ui/Link/Link.tsx +0 -392
- package/src/client/theme/ui/Link/LinkPreview.tsx +0 -59
- package/src/client/theme/ui/Link/index.ts +0 -2
- package/src/client/theme/ui/Link/link-preview.css +0 -48
- package/src/client/theme/ui/Loading/Loading.tsx +0 -10
- package/src/client/theme/ui/Loading/index.ts +0 -1
- package/src/client/theme/ui/Loading/loading.css +0 -30
- package/src/client/theme/ui/Navbar/GithubStars.tsx +0 -27
- package/src/client/theme/ui/Navbar/Navbar.tsx +0 -193
- package/src/client/theme/ui/Navbar/Tabs.tsx +0 -99
- package/src/client/theme/ui/Navbar/index.ts +0 -2
- package/src/client/theme/ui/Navbar/navbar.css +0 -347
- package/src/client/theme/ui/NotFound/NotFound.tsx +0 -19
- package/src/client/theme/ui/NotFound/index.ts +0 -1
- package/src/client/theme/ui/NotFound/not-found.css +0 -64
- package/src/client/theme/ui/OnThisPage/OnThisPage.tsx +0 -244
- package/src/client/theme/ui/OnThisPage/index.ts +0 -1
- package/src/client/theme/ui/OnThisPage/toc.css +0 -152
- package/src/client/theme/ui/PoweredBy/PoweredBy.tsx +0 -18
- package/src/client/theme/ui/PoweredBy/index.ts +0 -1
- package/src/client/theme/ui/PoweredBy/powered-by.css +0 -76
- package/src/client/theme/ui/ProgressBar/ProgressBar.css +0 -17
- package/src/client/theme/ui/ProgressBar/ProgressBar.tsx +0 -51
- package/src/client/theme/ui/ProgressBar/index.ts +0 -1
- package/src/client/theme/ui/SearchDialog/SearchDialog.tsx +0 -209
- package/src/client/theme/ui/SearchDialog/index.ts +0 -1
- package/src/client/theme/ui/SearchDialog/search.css +0 -152
- package/src/client/theme/ui/Sidebar/Sidebar.tsx +0 -244
- package/src/client/theme/ui/Sidebar/index.ts +0 -1
- package/src/client/theme/ui/Sidebar/sidebar.css +0 -230
- package/src/client/theme/ui/ThemeToggle/ThemeToggle.tsx +0 -69
- package/src/client/theme/ui/ThemeToggle/index.ts +0 -1
- package/src/client/theme/ui/VersionSwitcher/VersionSwitcher.tsx +0 -136
- package/src/client/theme/ui/VersionSwitcher/index.ts +0 -1
- package/src/client/utils.ts +0 -49
package/src/node/mdx.ts
CHANGED
|
@@ -1,25 +1,183 @@
|
|
|
1
|
-
import mdxPlugin from
|
|
2
|
-
import remarkGfm from
|
|
3
|
-
import remarkFrontmatter from
|
|
4
|
-
import rehypeSlug from
|
|
5
|
-
import
|
|
6
|
-
import
|
|
7
|
-
import
|
|
1
|
+
import mdxPlugin from '@mdx-js/rollup'
|
|
2
|
+
import remarkGfm from 'remark-gfm'
|
|
3
|
+
import remarkFrontmatter from 'remark-frontmatter'
|
|
4
|
+
import rehypeSlug from 'rehype-slug'
|
|
5
|
+
import type { Plugin } from 'vite'
|
|
6
|
+
import crypto from 'crypto'
|
|
7
|
+
import { visit } from 'unist-util-visit'
|
|
8
|
+
import { createHighlighter } from 'shiki'
|
|
8
9
|
|
|
9
|
-
import type {
|
|
10
|
-
|
|
10
|
+
import type { Highlighter } from 'shiki'
|
|
11
|
+
|
|
12
|
+
import type { BoltdocsConfig } from './config'
|
|
13
|
+
import { TransformCache } from './cache'
|
|
14
|
+
|
|
15
|
+
let shikiHighlighter: Highlighter | null = null
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* Retrieves or initializes the Shiki highlighter instance.
|
|
19
|
+
* Supports dual-theme configurations (light/dark).
|
|
20
|
+
*
|
|
21
|
+
* @param codeTheme - Theme configuration (string for single, object for dual).
|
|
22
|
+
* @returns A promise resolving to the highlighter instance.
|
|
23
|
+
*/
|
|
24
|
+
async function getShikiHighlighter(codeTheme: any) {
|
|
25
|
+
if (shikiHighlighter) return shikiHighlighter
|
|
26
|
+
|
|
27
|
+
const themes =
|
|
28
|
+
typeof codeTheme === 'object'
|
|
29
|
+
? [codeTheme.light, codeTheme.dark]
|
|
30
|
+
: [codeTheme ?? 'github-dark']
|
|
31
|
+
|
|
32
|
+
// Fallbacks for standard themes
|
|
33
|
+
;['github-light', 'github-dark'].forEach((t) => {
|
|
34
|
+
if (!themes.includes(t)) themes.push(t)
|
|
35
|
+
})
|
|
36
|
+
|
|
37
|
+
// Initialize with a core set of languages first to speed up boot
|
|
38
|
+
shikiHighlighter = await createHighlighter({
|
|
39
|
+
themes,
|
|
40
|
+
langs: [
|
|
41
|
+
'tsx',
|
|
42
|
+
'jsx',
|
|
43
|
+
'ts',
|
|
44
|
+
'js',
|
|
45
|
+
'json',
|
|
46
|
+
'md',
|
|
47
|
+
'mdx',
|
|
48
|
+
'css',
|
|
49
|
+
'html',
|
|
50
|
+
'bash',
|
|
51
|
+
'sh',
|
|
52
|
+
'yaml',
|
|
53
|
+
'yml',
|
|
54
|
+
],
|
|
55
|
+
})
|
|
56
|
+
|
|
57
|
+
return shikiHighlighter
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
/**
|
|
61
|
+
* Custom remark plugin to highlight code in ComponentPreview components.
|
|
62
|
+
* This runs before rehype, ensuring that the 'highlightedHtml' prop is correctly
|
|
63
|
+
* attached to the MDX component as a JSX attribute.
|
|
64
|
+
*
|
|
65
|
+
* Supports both string literals and MDX expression values (template literals)
|
|
66
|
+
* for the 'code' attribute.
|
|
67
|
+
*
|
|
68
|
+
* @param config - The Boltdocs configuration
|
|
69
|
+
* @returns A remark plugin function
|
|
70
|
+
*/
|
|
71
|
+
export function remarkShiki(config?: BoltdocsConfig) {
|
|
72
|
+
return async (tree: any) => {
|
|
73
|
+
const codeTheme = config?.themeConfig?.codeTheme ?? {
|
|
74
|
+
light: 'github-light',
|
|
75
|
+
dark: 'github-dark',
|
|
76
|
+
}
|
|
77
|
+
const highlighter = await getShikiHighlighter(codeTheme)
|
|
78
|
+
|
|
79
|
+
visit(tree, ['mdxJsxFlowElement', 'mdxJsxTextElement'], (node: any) => {
|
|
80
|
+
if (node.name !== 'ComponentPreview') return
|
|
81
|
+
|
|
82
|
+
const codeAttr = node.attributes?.find((a: any) => a.name === 'code')
|
|
83
|
+
let code = ''
|
|
84
|
+
|
|
85
|
+
if (codeAttr) {
|
|
86
|
+
if (typeof codeAttr.value === 'string') {
|
|
87
|
+
code = codeAttr.value
|
|
88
|
+
} else if (codeAttr.value?.type === 'mdxJsxAttributeValueExpression') {
|
|
89
|
+
const expr = codeAttr.value.value ?? ''
|
|
90
|
+
code = expr.match(/^[`'"](.+)[`'"]$/)?.[1] ?? expr
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
if (!code) return
|
|
95
|
+
|
|
96
|
+
const options: any =
|
|
97
|
+
typeof codeTheme === 'object'
|
|
98
|
+
? {
|
|
99
|
+
themes: { light: codeTheme.light, dark: codeTheme.dark },
|
|
100
|
+
lang: 'tsx',
|
|
101
|
+
}
|
|
102
|
+
: { theme: codeTheme, lang: 'tsx' }
|
|
103
|
+
|
|
104
|
+
const html = highlighter.codeToHtml(code, options)
|
|
105
|
+
|
|
106
|
+
node.attributes = (node.attributes ?? []).filter(
|
|
107
|
+
(a: any) => a.name !== 'highlightedHtml',
|
|
108
|
+
)
|
|
109
|
+
node.attributes.push({
|
|
110
|
+
type: 'mdxJsxAttribute',
|
|
111
|
+
name: 'highlightedHtml',
|
|
112
|
+
value: html,
|
|
113
|
+
})
|
|
114
|
+
})
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
/**
|
|
119
|
+
* Custom rehype plugin to perform syntax highlighting at build time for
|
|
120
|
+
* standard Markdown code blocks.
|
|
121
|
+
*
|
|
122
|
+
* Injects 'data-highlighted="true"' and 'highlightedHtml' into the 'pre' tag properties,
|
|
123
|
+
* which are then consumed by the client-side CodeBlock component.
|
|
124
|
+
*
|
|
125
|
+
* @param config - The Boltdocs configuration
|
|
126
|
+
* @returns A rehype plugin function
|
|
127
|
+
*/
|
|
128
|
+
export function rehypeShiki(config?: BoltdocsConfig) {
|
|
129
|
+
return async (tree: any) => {
|
|
130
|
+
const codeTheme = config?.themeConfig?.codeTheme || {
|
|
131
|
+
light: 'github-light',
|
|
132
|
+
dark: 'github-dark',
|
|
133
|
+
}
|
|
134
|
+
const highlighter = await getShikiHighlighter(codeTheme)
|
|
135
|
+
|
|
136
|
+
visit(tree, 'element', (node: any) => {
|
|
137
|
+
// Handle standard Markdown code blocks
|
|
138
|
+
if (node.tagName === 'pre' && node.children?.[0]?.tagName === 'code') {
|
|
139
|
+
const codeNode = node.children[0]
|
|
140
|
+
const className = codeNode.properties?.className || []
|
|
141
|
+
const langMatch = className.find((c: string) =>
|
|
142
|
+
c.startsWith('language-'),
|
|
143
|
+
)
|
|
144
|
+
const lang = langMatch ? langMatch.slice(9) : 'text'
|
|
145
|
+
const code = codeNode.children[0]?.value || ''
|
|
146
|
+
|
|
147
|
+
const options: any = { lang }
|
|
148
|
+
if (typeof codeTheme === 'object') {
|
|
149
|
+
options.themes = {
|
|
150
|
+
light: codeTheme.light,
|
|
151
|
+
dark: codeTheme.dark,
|
|
152
|
+
}
|
|
153
|
+
} else {
|
|
154
|
+
options.theme = codeTheme
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
const html = highlighter.codeToHtml(code, options)
|
|
158
|
+
|
|
159
|
+
// Inject highlighted HTML and mark as highlighted for CodeBlock component
|
|
160
|
+
node.properties.dataHighlighted = 'true'
|
|
161
|
+
node.properties.highlightedHtml = html
|
|
162
|
+
node.children = []
|
|
163
|
+
}
|
|
164
|
+
})
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
const MDX_PLUGIN_VERSION = 'v3'
|
|
11
169
|
|
|
12
170
|
/**
|
|
13
171
|
* Persistent cache for MDX transformations.
|
|
14
172
|
* Saves results to `.boltdocs/transform-mdx.json.gz`.
|
|
15
173
|
*/
|
|
16
|
-
const mdxCache = new TransformCache(
|
|
17
|
-
let mdxCacheLoaded = false
|
|
174
|
+
const mdxCache = new TransformCache('mdx')
|
|
175
|
+
let mdxCacheLoaded = false
|
|
18
176
|
|
|
19
177
|
/**
|
|
20
178
|
* Configures the MDX compiler for Vite using `@mdx-js/rollup`.
|
|
21
179
|
* Includes standard remark and rehype plugins for GitHub Flavored Markdown (GFM),
|
|
22
|
-
* frontmatter extraction, auto-linking headers
|
|
180
|
+
* frontmatter extraction, and auto-linking headers.
|
|
23
181
|
*
|
|
24
182
|
* Also wraps the plugin with a persistent cache to avoid re-compiling unchanged MDX files.
|
|
25
183
|
*
|
|
@@ -32,62 +190,62 @@ export function boltdocsMdxPlugin(
|
|
|
32
190
|
compiler = mdxPlugin,
|
|
33
191
|
): Plugin {
|
|
34
192
|
const extraRemarkPlugins =
|
|
35
|
-
config?.plugins?.flatMap((p) => p.remarkPlugins || []) || []
|
|
193
|
+
config?.plugins?.flatMap((p) => p.remarkPlugins || []) || []
|
|
36
194
|
const extraRehypePlugins =
|
|
37
|
-
config?.plugins?.flatMap((p) => p.rehypePlugins || []) || []
|
|
195
|
+
config?.plugins?.flatMap((p) => p.rehypePlugins || []) || []
|
|
38
196
|
|
|
39
197
|
const baseMdxPlugin = compiler({
|
|
40
|
-
remarkPlugins: [
|
|
198
|
+
remarkPlugins: [
|
|
199
|
+
remarkGfm,
|
|
200
|
+
remarkFrontmatter,
|
|
201
|
+
[remarkShiki, config],
|
|
202
|
+
...(extraRemarkPlugins as any[]),
|
|
203
|
+
],
|
|
41
204
|
rehypePlugins: [
|
|
42
205
|
rehypeSlug,
|
|
43
|
-
|
|
44
|
-
[
|
|
45
|
-
rehypePrettyCode,
|
|
46
|
-
{
|
|
47
|
-
theme: config?.themeConfig?.codeTheme || "one-dark-pro",
|
|
48
|
-
keepBackground: false,
|
|
49
|
-
},
|
|
50
|
-
],
|
|
206
|
+
[rehypeShiki, config],
|
|
207
|
+
...(extraRehypePlugins as any[]),
|
|
51
208
|
],
|
|
52
|
-
jsxRuntime:
|
|
53
|
-
providerImportSource:
|
|
54
|
-
}) as Plugin
|
|
209
|
+
jsxRuntime: 'automatic',
|
|
210
|
+
providerImportSource: '@mdx-js/react',
|
|
211
|
+
}) as Plugin
|
|
55
212
|
|
|
56
213
|
// @ts-ignore
|
|
57
214
|
if (baseMdxPlugin.isMock) {
|
|
58
|
-
console.log(
|
|
215
|
+
console.log('MDX PLUGIN IS MOCKED')
|
|
59
216
|
}
|
|
60
217
|
|
|
61
218
|
return {
|
|
62
219
|
...baseMdxPlugin,
|
|
63
|
-
name:
|
|
220
|
+
name: 'vite-plugin-boltdocs-mdx',
|
|
64
221
|
|
|
65
222
|
async buildStart() {
|
|
66
|
-
hits = 0
|
|
67
|
-
total = 0
|
|
223
|
+
hits = 0
|
|
224
|
+
total = 0
|
|
68
225
|
if (!mdxCacheLoaded) {
|
|
69
|
-
mdxCache.load()
|
|
70
|
-
mdxCacheLoaded = true
|
|
226
|
+
mdxCache.load()
|
|
227
|
+
mdxCacheLoaded = true
|
|
71
228
|
}
|
|
72
229
|
if (baseMdxPlugin.buildStart) {
|
|
73
|
-
await (baseMdxPlugin.buildStart as any).call(this)
|
|
230
|
+
await (baseMdxPlugin.buildStart as any).call(this)
|
|
74
231
|
}
|
|
75
232
|
},
|
|
76
233
|
|
|
77
234
|
async transform(code, id, options) {
|
|
78
|
-
if (!id.endsWith(
|
|
79
|
-
return (baseMdxPlugin.transform as any)?.call(this, code, id, options)
|
|
235
|
+
if (!id.endsWith('.md') && !id.endsWith('.mdx')) {
|
|
236
|
+
return (baseMdxPlugin.transform as any)?.call(this, code, id, options)
|
|
80
237
|
}
|
|
81
238
|
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
const
|
|
239
|
+
console.log(`[boltdocs] Transforming MDX: ${id}`)
|
|
240
|
+
total++
|
|
241
|
+
// Create a cache key based on path, content, and plugin version
|
|
242
|
+
const contentHash = crypto.createHash('md5').update(code).digest('hex')
|
|
243
|
+
const cacheKey = `${id}:${contentHash}:${MDX_PLUGIN_VERSION}`
|
|
86
244
|
|
|
87
|
-
const cached = mdxCache.get(cacheKey)
|
|
245
|
+
const cached = mdxCache.get(cacheKey)
|
|
88
246
|
if (cached) {
|
|
89
|
-
hits
|
|
90
|
-
return { code: cached, map: null }
|
|
247
|
+
hits++
|
|
248
|
+
return { code: cached, map: null }
|
|
91
249
|
}
|
|
92
250
|
|
|
93
251
|
const result = await (baseMdxPlugin.transform as any).call(
|
|
@@ -95,33 +253,27 @@ export function boltdocsMdxPlugin(
|
|
|
95
253
|
code,
|
|
96
254
|
id,
|
|
97
255
|
options,
|
|
98
|
-
)
|
|
256
|
+
)
|
|
99
257
|
|
|
100
|
-
if (result && typeof result ===
|
|
101
|
-
mdxCache.set(cacheKey, result.code)
|
|
258
|
+
if (result && typeof result === 'object' && result.code) {
|
|
259
|
+
mdxCache.set(cacheKey, result.code)
|
|
102
260
|
}
|
|
103
261
|
|
|
104
|
-
return result
|
|
262
|
+
return result
|
|
105
263
|
},
|
|
106
264
|
|
|
107
265
|
async buildEnd() {
|
|
108
|
-
|
|
109
|
-
|
|
266
|
+
console.log(
|
|
267
|
+
`[boltdocs] MDX Cache Performance: ${hits}/${total} hits (${Math.round((hits / total) * 100) || 0}%)`,
|
|
268
|
+
)
|
|
269
|
+
mdxCache.save()
|
|
270
|
+
await mdxCache.flush() // Use instance flush or global flushCache
|
|
110
271
|
if (baseMdxPlugin.buildEnd) {
|
|
111
|
-
await (baseMdxPlugin.buildEnd as any).call(this)
|
|
272
|
+
await (baseMdxPlugin.buildEnd as any).call(this)
|
|
112
273
|
}
|
|
113
274
|
},
|
|
114
|
-
}
|
|
115
|
-
}
|
|
116
|
-
|
|
117
|
-
/**
|
|
118
|
-
* Returns the current MDX cache statistics.
|
|
119
|
-
* @returns An object with total and hit counts
|
|
120
|
-
* @deprecated Removed for performance
|
|
121
|
-
*/
|
|
122
|
-
export function getMdxCacheStats() {
|
|
123
|
-
return { hits: 0, total: 0 };
|
|
275
|
+
}
|
|
124
276
|
}
|
|
125
277
|
|
|
126
|
-
let hits = 0
|
|
127
|
-
let total = 0
|
|
278
|
+
let hits = 0
|
|
279
|
+
let total = 0
|
package/src/node/plugin/entry.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import { normalizePath } from
|
|
2
|
-
import type { BoltdocsConfig } from
|
|
3
|
-
import type { BoltdocsPluginOptions } from
|
|
4
|
-
import path from
|
|
1
|
+
import { normalizePath } from '../utils'
|
|
2
|
+
import type { BoltdocsConfig } from '../config'
|
|
3
|
+
import type { BoltdocsPluginOptions } from './types'
|
|
4
|
+
import path from 'path'
|
|
5
5
|
|
|
6
6
|
/**
|
|
7
7
|
* Generates the raw source code for the virtual entry file (`\0virtual:boltdocs-entry`).
|
|
@@ -17,14 +17,10 @@ export function generateEntryCode(
|
|
|
17
17
|
): string {
|
|
18
18
|
const homeImport = options.homePage
|
|
19
19
|
? `import HomePage from '${normalizePath(options.homePage)}';`
|
|
20
|
-
:
|
|
21
|
-
const homeOption = options.homePage ?
|
|
22
|
-
const customCssImport = options.customCss
|
|
23
|
-
? `import '${normalizePath(options.customCss)}';`
|
|
24
|
-
: "";
|
|
25
|
-
|
|
20
|
+
: ''
|
|
21
|
+
const homeOption = options.homePage ? 'homePage: HomePage,' : ''
|
|
26
22
|
const pluginComponents =
|
|
27
|
-
config?.plugins?.flatMap((p) => Object.entries(p.components || {})) || []
|
|
23
|
+
config?.plugins?.flatMap((p) => Object.entries(p.components || {})) || []
|
|
28
24
|
|
|
29
25
|
const componentImports = pluginComponents
|
|
30
26
|
.map(
|
|
@@ -34,19 +30,33 @@ export function generateEntryCode(
|
|
|
34
30
|
]) => `import * as _comp_${name} from '${normalizePath(path)}';
|
|
35
31
|
const ${name} = _comp_${name}.default || _comp_${name}['${name}'] || _comp_${name};`,
|
|
36
32
|
)
|
|
37
|
-
.join(
|
|
38
|
-
const componentMap = pluginComponents.map(([name]) => name).join(
|
|
33
|
+
.join('\n')
|
|
34
|
+
const componentMap = pluginComponents.map(([name]) => name).join(', ')
|
|
35
|
+
|
|
36
|
+
const docsDirName = path.basename(options.docsDir || 'docs')
|
|
39
37
|
|
|
40
|
-
const
|
|
38
|
+
const externalEntries = Object.entries(config?.external || {})
|
|
39
|
+
const externalImports = externalEntries
|
|
40
|
+
.map(
|
|
41
|
+
([_routePath, compPath], i) =>
|
|
42
|
+
`import _ext_${i} from '${normalizePath(compPath)}';`,
|
|
43
|
+
)
|
|
44
|
+
.join('\n')
|
|
45
|
+
const externalOption =
|
|
46
|
+
externalEntries.length > 0
|
|
47
|
+
? `externalPages: { ${externalEntries
|
|
48
|
+
.map(([path], i) => `"${path}": _ext_${i}`)
|
|
49
|
+
.join(', ')} },`
|
|
50
|
+
: ''
|
|
41
51
|
|
|
42
52
|
return `
|
|
43
53
|
import { createBoltdocsApp as _createApp } from 'boltdocs/client';
|
|
44
|
-
import 'boltdocs/style.css';
|
|
45
|
-
${customCssImport}
|
|
46
54
|
import _routes from 'virtual:boltdocs-routes';
|
|
47
55
|
import _config from 'virtual:boltdocs-config';
|
|
56
|
+
import _user_mdx_components from 'virtual:boltdocs-mdx-components';
|
|
48
57
|
${homeImport}
|
|
49
58
|
${componentImports}
|
|
59
|
+
${externalImports}
|
|
50
60
|
|
|
51
61
|
_createApp({
|
|
52
62
|
target: '#root',
|
|
@@ -56,7 +66,8 @@ _createApp({
|
|
|
56
66
|
modules: import.meta.glob('/${docsDirName}/**/*.{md,mdx}'),
|
|
57
67
|
hot: import.meta.hot,
|
|
58
68
|
${homeOption}
|
|
59
|
-
|
|
69
|
+
${externalOption}
|
|
70
|
+
components: { ${componentMap}${componentMap ? ', ' : ''} ...(_user_mdx_components || {}) },
|
|
60
71
|
});
|
|
61
|
-
|
|
72
|
+
`
|
|
62
73
|
}
|
package/src/node/plugin/html.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { BoltdocsConfig } from
|
|
1
|
+
import type { BoltdocsConfig } from '../config'
|
|
2
2
|
|
|
3
3
|
/**
|
|
4
4
|
* Injects OpenGraph, Twitter, and generic SEO meta tags into the final HTML output.
|
|
@@ -9,8 +9,8 @@ import type { BoltdocsConfig } from "../config";
|
|
|
9
9
|
* @returns The modified HTML string with injected tags
|
|
10
10
|
*/
|
|
11
11
|
export function injectHtmlMeta(html: string, config: BoltdocsConfig): string {
|
|
12
|
-
const title = config.themeConfig?.title ||
|
|
13
|
-
const description = config.themeConfig?.description ||
|
|
12
|
+
const title = config.themeConfig?.title || 'Boltdocs'
|
|
13
|
+
const description = config.themeConfig?.description || ''
|
|
14
14
|
|
|
15
15
|
const seoTags = [
|
|
16
16
|
`<meta name="description" content="${description}">`,
|
|
@@ -21,7 +21,7 @@ export function injectHtmlMeta(html: string, config: BoltdocsConfig): string {
|
|
|
21
21
|
`<meta name="twitter:title" content="${title}">`,
|
|
22
22
|
`<meta name="twitter:description" content="${description}">`,
|
|
23
23
|
`<meta name="generator" content="Boltdocs">`,
|
|
24
|
-
].join(
|
|
24
|
+
].join('\n ')
|
|
25
25
|
|
|
26
26
|
const themeScript = `
|
|
27
27
|
<script>
|
|
@@ -39,17 +39,17 @@ export function injectHtmlMeta(html: string, config: BoltdocsConfig): string {
|
|
|
39
39
|
} catch (e) {}
|
|
40
40
|
})();
|
|
41
41
|
</script>
|
|
42
|
-
|
|
42
|
+
`
|
|
43
43
|
|
|
44
|
-
html = html.replace(/<title>.*?<\/title>/, `<title>${title}</title>`)
|
|
45
|
-
html = html.replace(
|
|
44
|
+
html = html.replace(/<title>.*?<\/title>/, `<title>${title}</title>`)
|
|
45
|
+
html = html.replace('</head>', ` ${seoTags}\n${themeScript} </head>`)
|
|
46
46
|
|
|
47
|
-
if (!html.includes(
|
|
47
|
+
if (!html.includes('src/main')) {
|
|
48
48
|
html = html.replace(
|
|
49
|
-
|
|
49
|
+
'</body>',
|
|
50
50
|
' <script type="module">import "virtual:boltdocs-entry";</script>\n </body>',
|
|
51
|
-
)
|
|
51
|
+
)
|
|
52
52
|
}
|
|
53
53
|
|
|
54
|
-
return html
|
|
54
|
+
return html
|
|
55
55
|
}
|