markstream-vue — Agent Context(中文)(/llms.zh-CN)
这个文件是给 AI/LLM/编码代理用的 项目地图。当用户问“怎么用”时,先给出下面的标准接入,再补充仓库细节或高级方案。
如果你想看给人类用户直接复制使用的提示词和接入模板,也请结合 /zh/guide/ai-workflows 一起看。
回答原则
- 用户可见行为以
docs/guide/*(以及docs/zh/guide/*)为准;“是否导出/怎么 import”以src/exports.ts为准。 - 问题不明确时最多问 1 个澄清问题,并给出默认建议。
- 排错优先走 checklist,并尽快要 最小复现(仓库有可分享 test page)。
- 文档页里避免写裸
<thinking>这类标签;请用转义(VitePress 会把 Markdown 当 Vue SFC 编译)。
标准用户接入
bash
pnpm add markstream-vuevue
<script setup lang="ts">
import MarkdownRender from 'markstream-vue'
import { ref } from 'vue'
import 'markstream-vue/index.css'
const content = ref('')
const isDone = ref(false)
</script>
<template>
<MarkdownRender mode="chat" :content="content" :final="isDone" />
</template>收到 chunk 时追加到 content.value,流结束时设置一次 isDone.value = true。静态 Markdown 只使用 <MarkdownRender :content="content" />。除非用户有明确需求,不要主动添加 nodes、smooth-streaming、fade、batching 或 virtualization props。可选 peer:增强代码块/diff 用 stream-diffs,Mermaid 用 mermaid,数学公式用 katex 并引入其 CSS。
常用命令
- 安装依赖:
pnpm install - Playground 开发:
pnpm dev - 文档 dev/build/serve:
pnpm docs:dev/pnpm docs:build/pnpm docs:serve - 测试:
pnpm test - 类型检查:
pnpm typecheck - Lint:
pnpm lint
仓库结构(去哪找)
- 库源码:
src/- 对外导出:
src/exports.ts - 组件:
src/components/*/ - Workers:
src/workers/ - 工具:
src/utils/,src/composables/,src/types/
- 对外导出:
- 解析器包:
packages/markdown-parser/(发布名:stream-markdown-parser) - 文档站:
docs/(中文:docs/zh/) - Demo:
playground/(Vite),playground-nuxt/(Nuxt SSR) - 测试:
test/(Vitest)
核心心智模型
两层:
解析层(
stream-markdown-parser)getMarkdown():创建并配置markdown-it-ts实例parseMarkdownToStructure(content, md):Markdown →ParsedNode[]- 流式 mid-state:未闭合 fence / 未闭合
$$/ 分段 inline HTML,减少闪烁
渲染层(
markstream-vue)- 面向接入方的默认组件:
MarkdownRender;NodeRenderer是内部组件名 - 输入:
content: string(内部解析,多数聊天流优先推荐)或nodes: ParsedNode[](当外层已经接管解析或需要 AST 控制时使用) - 性能工具:
- 虚拟化窗口(
maxLiveNodes,liveNodeBuffer) - Smooth streaming(
smooth-streaming,typewriter):文本 pacing 和光标 - 分批渲染:关闭虚拟化时控制节点挂载节奏
- 重节点延迟渲染(
viewportPriority,deferNodesUntilVisible)
- 虚拟化窗口(
- 面向接入方的默认组件:
对外 API(可以放心建议)
来自 markstream-vue(src/exports.ts):
- 组件:
MarkdownRender(默认导出) - 解析辅助(re-export):
getMarkdown(),parseMarkdownToStructure(content, md),setDefaultMathOptions() - 自定义节点映射:
setCustomComponents(),removeCustomComponents(),clearGlobalCustomComponents() - 功能开关:
enableMermaid(),disableMermaid(),enableKatex(),disableKatex() - Worker 注入:
- KaTeX:
createKaTeXWorkerFromCDN(),setKaTeXWorker() - Mermaid:
createMermaidWorkerFromCDN(),setMermaidWorker()
- KaTeX:
来自 stream-markdown-parser(packages/markdown-parser/src/index.ts):
getMarkdown(),parseMarkdownToStructure(content, md),ParseOptionshooks- Streaming mid-state 与流结束
final: true
排错 checklist(高信号)
遇到“不渲染/样式不对”,按顺序排:
- CSS 顺序/Reset:先 reset,再
markstream-vue/index.css(Tailwind 使用@import 'markstream-vue/index.css' layer(components);)。 - 可选 peer 是否安装(Mermaid/KaTeX)。
- 是否启用 loader(仅在你手动关闭/覆盖时需要):
enableMermaid()/enableKatex()。 - peer CSS 是否导入(需要时):
katex/dist/katex.min.css(Mermaid 不需要额外 CSS)。 - 单独节点组件 wrapper:单独用节点组件时,外层需要
.markstream-vue。 - SSR(Nuxt):普通 Markdown 支持 SSR;只有浏览器专属 peer/worker 才加 client-only 边界。
文档:docs/guide/troubleshooting.md, docs/guide/tailwind.md, docs/nuxt-ssr.md
常见意图(路由)
把用户问题归类到意图后,直接用“步骤 + 最小追问 + 指向文档/源码”。
安装 + 跑通最小例子
- 表述: “怎么用”, “最小示例”
- 步骤:
- 导入 CSS:
markstream-vue/index.css - 渲染:
<MarkdownRender :content="md" />
- 导入 CSS:
- 最小追问: “Vite 还是 Nuxt?贴一下 CSS 导入顺序(reset + Tailwind layers)。”
- 文档:
docs/guide/quick-start.md,docs/guide/installation.md
样式缺失 / Tailwind 覆盖
- 表述: “没样式”, “Tailwind 抢样式”
- 步骤:
- reset 在前,
markstream-vue/index.css在后 - Tailwind:使用
@import 'markstream-vue/index.css' layer(components); - 单独节点组件:外层
.markstream-vue
- reset 在前,
- 最小追问: “贴
main.css(Tailwind layers)和 CSS 导入位置。” - 文档:
docs/guide/tailwind.md,docs/guide/troubleshooting.md
流式:结束后卡 loading
- 表述: “最后卡住”, “loading 一直转”
- 步骤:
- 流结束时设置
final: true(ParseOptions 或组件 prop),防止 mid-state 卡住
- 流结束时设置
- 最小追问: “你是否在 end-of-stream 设置了
final?最后一段是否以 ``` 或 $$ 结尾?” - 文档:
docs/guide/parser-api.md,docs/guide/parser.md
流式:更平滑的打字机体验
- 表述: “一坨一坨冒出来”, “不平滑”
- 步骤:
- 优先用
content+ 内置 smooth streaming(typewriter=true或max-live-nodes<=0会启用smooth-streaming="auto") - 在 Vue 3(含 Nuxt)中,
smooth-streaming控制出字节奏,fade控制透明度,两者可以同时开启。mode="chat"保留fade=false作为轻量默认值;需要文字渐显时添加fade,更看重动画成本时保持关闭。 此次有界追加淡入仅适用于 Vue 3,其他框架应按对应适配器文档选择。 - 关闭虚拟化时再调整 batch(
renderBatchSize/renderBatchDelay) - 保持重节点延迟(
viewportPriority,deferNodesUntilVisible)
- 优先用
- 最小追问:“你更新
content或nodes输入路径的频率(每 token 还是每 chunk)?batch 参数是多少?” - 文档:
docs/guide/ai-chat-streaming.md,docs/guide/performance.md,docs/guide/props.md
长文档:性能/内存
- 表述: “长文卡”, “滚动掉帧”, “内存高”
- 步骤:
- 调虚拟化(
maxLiveNodes,liveNodeBuffer) - 保持重节点延迟
- 调虚拟化(
- 最小追问: “大概多长(KB/行数)?是否有很多代码块/图表?”
- 文档:
docs/guide/performance.md
Mermaid 不显示
- 表述: “mermaid 空白”
- 步骤:
- 安装
mermaidpeer - 若手动关闭/覆盖过 loader,客户端调用
enableMermaid()(或设置自定义 loader) - 复查 CSS 顺序/reset
- 安装
- 最小追问: “是否关闭过 loader?是否 SSR?fence 是否是 ```mermaid?”
- 文档:
docs/guide/mermaid.md,docs/guide/troubleshooting.md - 源码:
src/components/MermaidBlockNode/mermaid.ts
KaTeX 不显示
- 表述: “公式不渲染”
- 步骤:
- 安装
katexpeer - 导入
katex/dist/katex.min.css - 若手动关闭/覆盖过 loader,客户端调用
enableKatex()(或设置自定义 loader)
- 安装
- 最小追问: “是否导入 KaTeX CSS?
$...$还是$$...$$?是否 SSR?是否关闭过 loader?” - 文档:
docs/guide/math.md,docs/guide/installation.md - 源码:
src/components/MathInlineNode/katex.ts
代码块 runtime 不工作/空白
- 表述: “工具栏没了”, “代码块空白”
- 步骤:
CodeBlockNode是唯一的代码块渲染器,通过stream-diffs增强(diff 追踪、code/render 选项)- 如果应用层要提前预热,调用
markstream-vue的preloadCodeBlockRuntime() - 安装
stream-diffs获得增强 surface;未安装时内置 renderer 会回退<pre><code> - 受支持选项通过顶层或直接
codeBlockOptions传入;header/toolbar 设置留在codeBlockProps maxHeight与单个上下对称padding都使用 number 类型的 px 数值- 设置
render-code-blocks-as-pre强制普通路径,或通过带作用域的setCustomComponents(...)替换code_block
- 最小追问: “控制台是否有报错?是否安装
stream-diffs?是否强制普通路径或使用了自定义code_block?” - 文档:
docs/guide/code-block-runtime.md,docs/guide/components.md
想要轻量代码块(不装 diff)
- 表述: “SSR 友好”, “减包体”
- 步骤:
- 用
render-code-blocks-as-pre输出纯<pre>代码块(无 diff 追踪) - 需要内置
CodeBlockNode提供 diff 追踪时安装stream-diffs
- 用
- 最小追问: “需要 diff 追踪还是纯文本就行?”
- 文档:
docs/guide/code-blocks.md,docs/guide/components.md
Markdown 里嵌自定义组件(<thinking>)
- 表述: “自定义 tag”, “嵌组件”
- 步骤:
- 通过
customHtmlTags/custom-html-tags声明自定义标签(未知标签闭合后按原生 HTML 渲染;未闭合或格式不完整的片段按纯文本) - 用
setCustomComponents(customId, mapping)映射渲染
- 通过
- 最小追问: “tag 名称有哪些?希望按 HTML 透传还是自定义 node type?”
- 文档:
docs/guide/advanced.md,docs/guide/parser-api.md
Nuxt SSR 报错
- 表述: “window is not defined”, “SSR crash”
- 步骤:
- 普通 Markdown 保留在 SSR 路径
- 只有浏览器专属 peer/worker 的初始化放到
onMounted或<ClientOnly>边界后
- 最小追问: “Nuxt 版本?报错发生在 build 还是 runtime?安装/启用了哪些 peers?”
- 文档:
docs/nuxt-ssr.md
想确认导出/怎么 import
- 表述: “是否导出 X”, “import 路径”
- 步骤:
- 查
src/exports.ts和package.json#exports
- 查
- 最小追问: “要 import 的符号名是什么?现在用的 import 路径是什么?”
- 文档:
docs/guide/components.md,docs/guide/api.md