markstream-vue 0.0.3-beta.1 → 0.0.3-beta.3
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/README.md +281 -7
- package/README.zh-CN.md +289 -16
- package/dist/exports-DYua_tlG.js +5323 -0
- package/dist/exports-h70Zx97z.cjs +246 -0
- package/dist/exports.js +1 -1
- package/dist/{index-ClFlwUOZ.cjs → index-3jXtLsem.cjs} +1 -1
- package/dist/{index-DGTqKnzM.js → index-9wg07cmN.js} +409 -383
- package/dist/{index-BZqRC51k.js → index-CtDwbqLS.js} +1 -1
- package/dist/{index-Cn5LHgOE.cjs → index-DgwtvqiC.cjs} +1 -1
- package/dist/index-DpjKVeoo.cjs +22 -0
- package/dist/{index-D-TkURzk.js → index-Zn32X7og.js} +1 -1
- package/dist/index.cjs +1 -1
- package/dist/index.css +1 -1
- package/dist/index.d.ts +45 -27
- package/dist/index.js +64 -63
- package/dist/index.tailwind.css +1 -1
- package/dist/index4.js +1 -1
- package/dist/tailwind.ts +0 -0
- package/package.json +14 -5
- package/dist/exports-ByrWvfQh.cjs +0 -246
- package/dist/exports-CuW10Rlw.js +0 -4909
- package/dist/index-CapyHsmU.cjs +0 -22
package/README.md
CHANGED
|
@@ -5,24 +5,63 @@
|
|
|
5
5
|
[](https://www.npmjs.com/package/markstream-vue)
|
|
6
6
|
[](README.zh-CN.md)
|
|
7
7
|
[](https://markstream-vue-docs.simonhe.me/)
|
|
8
|
+
[](https://markstream-vue.simonhe.me/)
|
|
9
|
+
[](https://markstream-vue.simonhe.me/test)
|
|
8
10
|
[](https://www.npmjs.com/package/markstream-vue)
|
|
9
11
|
[](https://bundlephobia.com/package/markstream-vue)
|
|
12
|
+
[](https://github.com/Simon-He95/markstream-vue/releases)
|
|
13
|
+
[](https://github.com/Simon-He95/markstream-vue/discussions)
|
|
14
|
+
[](https://discord.gg/vkzdkjeRCW)
|
|
15
|
+
[](./SUPPORT.md)
|
|
16
|
+
[](./SECURITY.md)
|
|
17
|
+
[](https://github.com/Simon-He95/markstream-vue/actions/workflows/ci.yml)
|
|
10
18
|
[](./LICENSE)
|
|
11
19
|
|
|
20
|
+
## Contents
|
|
21
|
+
|
|
22
|
+
- [TL;DR Highlights](#tldr-highlights)
|
|
23
|
+
- [Try It Now](#-try-it-now)
|
|
24
|
+
- [Quick Start](#-quick-start)
|
|
25
|
+
- [Common commands](#-common-commands)
|
|
26
|
+
- [Streaming in 30 seconds](#-streaming-in-30-seconds)
|
|
27
|
+
- [Performance presets](#-performance-presets)
|
|
28
|
+
- [Key props & options](#-key-props--options-cheatsheet)
|
|
29
|
+
- [Where it shines](#-where-it-shines)
|
|
30
|
+
- [FAQ](#-faq-quick-answers)
|
|
31
|
+
- [Why markstream-vue](#-why-markstream-vue-over-a-typical-markdown-renderer)
|
|
32
|
+
- [Releases](#-releases)
|
|
33
|
+
- [Showcase](#-showcase--examples)
|
|
34
|
+
- [Contributing & community](#-contributing--community)
|
|
35
|
+
- [Community & support](#-community--support)
|
|
36
|
+
- [Troubleshooting](#troubleshooting--common-issues)
|
|
12
37
|
> 📖 All detailed documentation, API, examples, and advanced usage have been migrated to the VitePress documentation site:
|
|
13
38
|
> https://markstream-vue-docs.simonhe.me/guide/
|
|
14
39
|
|
|
15
|
-
##
|
|
40
|
+
## TL;DR Highlights
|
|
41
|
+
|
|
42
|
+
- Purpose-built for **streaming Markdown** (AI/chat/SSE) with zero flicker and predictable memory.
|
|
43
|
+
- **Two render modes**: virtual window for long docs, incremental batching for “typing” effects.
|
|
44
|
+
- **Progressive diagrams** (Mermaid) and **streaming code blocks** (Monaco/Shiki) that keep up with diffs.
|
|
45
|
+
- Works with **raw Markdown strings or pre-parsed nodes**, supports **custom Vue components** inline.
|
|
46
|
+
- TypeScript-first, ship-ready defaults — import CSS and render.
|
|
47
|
+
|
|
48
|
+
## 🚀 Try It Now
|
|
16
49
|
|
|
17
50
|
- Playground (interactive demo): https://markstream-vue.simonhe.me/
|
|
18
|
-
- Interactive test page: https://markstream-vue.simonhe.me/test
|
|
51
|
+
- Interactive test page (shareable links, easy reproduction): https://markstream-vue.simonhe.me/test
|
|
52
|
+
- Docs: https://markstream-vue-docs.simonhe.me/guide/
|
|
53
|
+
- One-click StackBlitz demo: https://stackblitz.com/github/Simon-He95/markstream-vue?file=playground/src/App.vue
|
|
54
|
+
- Changelog: [CHANGELOG.md](./CHANGELOG.md)
|
|
55
|
+
- Nuxt playground: `pnpm play:nuxt`
|
|
56
|
+
- Discord: https://discord.gg/vkzdkjeRCW
|
|
19
57
|
|
|
20
|
-
|
|
21
|
-
https://markstream-vue.simonhe.me/test
|
|
58
|
+
## 💬 Community & support
|
|
22
59
|
|
|
23
|
-
|
|
60
|
+
- Discussions: https://github.com/Simon-He95/markstream-vue/discussions
|
|
61
|
+
- Discord: https://discord.gg/vkzdkjeRCW
|
|
62
|
+
- Issues: please use templates and attach a repro link (https://markstream-vue.simonhe.me/test)
|
|
24
63
|
|
|
25
|
-
|
|
64
|
+
The test page gives you an editor + live preview plus “generate share link” that encodes the input in the URL (with a fallback to open directly or pre-fill a GitHub Issue for long payloads).
|
|
26
65
|
|
|
27
66
|
## ⚡ Quick Start
|
|
28
67
|
|
|
@@ -50,6 +89,123 @@ createApp({
|
|
|
50
89
|
|
|
51
90
|
Import `markstream-vue/index.css` after your reset (e.g., Tailwind `@layer components`) so renderer styles win over utility classes. Install optional peers such as `stream-monaco`, `shiki`, `mermaid`, and `katex` only when you need Monaco code blocks, Shiki highlighting, diagrams, or math.
|
|
52
91
|
|
|
92
|
+
Enable heavy peers only when needed:
|
|
93
|
+
|
|
94
|
+
```ts
|
|
95
|
+
import { enableKatex, enableMermaid } from 'markstream-vue'
|
|
96
|
+
import 'markstream-vue/index.css'
|
|
97
|
+
|
|
98
|
+
// after you install `mermaid` / `katex` peers
|
|
99
|
+
enableMermaid()
|
|
100
|
+
enableKatex()
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
### Nuxt quick drop-in
|
|
104
|
+
|
|
105
|
+
```ts
|
|
106
|
+
// plugins/markstream-vue.client.ts
|
|
107
|
+
import { defineNuxtPlugin } from '#app'
|
|
108
|
+
import MarkdownRender from 'markstream-vue'
|
|
109
|
+
import 'markstream-vue/index.css'
|
|
110
|
+
|
|
111
|
+
export default defineNuxtPlugin((nuxtApp) => {
|
|
112
|
+
nuxtApp.vueApp.component('MarkdownRender', MarkdownRender)
|
|
113
|
+
})
|
|
114
|
+
```
|
|
115
|
+
|
|
116
|
+
Then use `<MarkdownRender :content="md" />` in your pages.
|
|
117
|
+
|
|
118
|
+
## 🛠️ Common commands
|
|
119
|
+
|
|
120
|
+
- `pnpm dev` — playground dev server
|
|
121
|
+
- `pnpm play:nuxt` — Nuxt playground dev
|
|
122
|
+
- `pnpm build` — library + CSS build
|
|
123
|
+
- `pnpm test` — Vitest suite (`pnpm test:update` for snapshots)
|
|
124
|
+
- `pnpm typecheck` / `pnpm lint` — type and lint checks
|
|
125
|
+
|
|
126
|
+
## ⏱️ Streaming in 30 seconds
|
|
127
|
+
|
|
128
|
+
Render streamed Markdown (SSE/websocket) with incremental updates:
|
|
129
|
+
|
|
130
|
+
```ts
|
|
131
|
+
import type { ParsedNode } from 'markstream-vue'
|
|
132
|
+
import MarkdownRender, {
|
|
133
|
+
getMarkdown,
|
|
134
|
+
|
|
135
|
+
parseMarkdownToStructure
|
|
136
|
+
} from 'markstream-vue'
|
|
137
|
+
import { ref } from 'vue'
|
|
138
|
+
|
|
139
|
+
const nodes = ref<ParsedNode[]>([])
|
|
140
|
+
const buffer = ref('')
|
|
141
|
+
const md = getMarkdown()
|
|
142
|
+
|
|
143
|
+
function addChunk(chunk: string) {
|
|
144
|
+
buffer.value += chunk
|
|
145
|
+
nodes.value = parseMarkdownToStructure(buffer.value, md)
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
// e.g., inside your SSE/onmessage handler
|
|
149
|
+
eventSource.onmessage = event => addChunk(event.data)
|
|
150
|
+
|
|
151
|
+
// template
|
|
152
|
+
// <MarkdownRender
|
|
153
|
+
// :nodes="nodes"
|
|
154
|
+
// :max-live-nodes="0"
|
|
155
|
+
// :batch-rendering="{
|
|
156
|
+
// renderBatchSize: 16,
|
|
157
|
+
// renderBatchDelay: 8,
|
|
158
|
+
// }"
|
|
159
|
+
// />
|
|
160
|
+
```
|
|
161
|
+
|
|
162
|
+
Switch rendering style per surface:
|
|
163
|
+
|
|
164
|
+
- Virtualized window (default): steady scrolling and memory usage for long docs.
|
|
165
|
+
- Incremental batches: set `:max-live-nodes="0"` for AI-like “typing” with lightweight placeholders.
|
|
166
|
+
|
|
167
|
+
### SSR / Worker usage (deterministic output)
|
|
168
|
+
|
|
169
|
+
Pre-parse Markdown on the server or in a worker and render typed nodes on the client:
|
|
170
|
+
|
|
171
|
+
```ts
|
|
172
|
+
// server or worker
|
|
173
|
+
import { getMarkdown, parseMarkdownToStructure } from 'markstream-vue'
|
|
174
|
+
|
|
175
|
+
const md = getMarkdown()
|
|
176
|
+
const nodes = parseMarkdownToStructure('# Hello\n\nThis is parsed once', md)
|
|
177
|
+
// send `nodes` JSON to the client
|
|
178
|
+
```
|
|
179
|
+
|
|
180
|
+
```vue
|
|
181
|
+
<!-- client -->
|
|
182
|
+
<MarkdownRender :nodes="nodesFromServer" />
|
|
183
|
+
```
|
|
184
|
+
|
|
185
|
+
This avoids client-side parsing and keeps SSR/hydration deterministic.
|
|
186
|
+
|
|
187
|
+
### Hybrid: SSR + streaming handoff
|
|
188
|
+
|
|
189
|
+
- Server: parse the first Markdown batch to nodes and serialize `initialNodes` (and the raw `initialMarkdown` if you also stream later chunks).
|
|
190
|
+
- Client: hydrate with the same parser options, then keep streaming:
|
|
191
|
+
|
|
192
|
+
```ts
|
|
193
|
+
import type { ParsedNode } from 'markstream-vue'
|
|
194
|
+
import { getMarkdown, parseMarkdownToStructure } from 'markstream-vue'
|
|
195
|
+
import { ref } from 'vue'
|
|
196
|
+
|
|
197
|
+
const nodes = ref<ParsedNode[]>(initialNodes)
|
|
198
|
+
const buffer = ref(initialMarkdown)
|
|
199
|
+
const md = getMarkdown() // match server setup
|
|
200
|
+
|
|
201
|
+
function addChunk(chunk: string) {
|
|
202
|
+
buffer.value += chunk
|
|
203
|
+
nodes.value = parseMarkdownToStructure(buffer.value, md)
|
|
204
|
+
}
|
|
205
|
+
```
|
|
206
|
+
|
|
207
|
+
This avoids re-parsing SSR content while letting later SSE/WebSocket chunks continue the stream.
|
|
208
|
+
|
|
53
209
|
## ⚙️ Performance presets
|
|
54
210
|
|
|
55
211
|
- **Virtual window (default)** – keep `max-live-nodes` at its default `320` to enable virtualization. Nodes render immediately and the renderer keeps a sliding window of elements mounted so long docs remain responsive without showing skeleton placeholders.
|
|
@@ -57,6 +213,99 @@ Import `markstream-vue/index.css` after your reset (e.g., Tailwind `@layer compo
|
|
|
57
213
|
|
|
58
214
|
Pick one mode per surface: virtualization for best scrollback and steady memory usage, or incremental batching for AI-style “typing” previews.
|
|
59
215
|
|
|
216
|
+
> Tip: In chats, combine `max-live-nodes="0"` with small `renderBatchSize` (e.g., `16`) and a tiny `renderBatchDelay` (e.g., `8ms`) to keep the “typing” feel smooth without jumping large chunks. Tune `renderBatchBudgetMs` down if you need to cap CPU per frame.
|
|
217
|
+
|
|
218
|
+
## 🧰 Key props & options (cheatsheet)
|
|
219
|
+
|
|
220
|
+
- `content` vs `nodes`: pass raw Markdown or pre-parsed nodes (from `parseMarkdownToStructure`).
|
|
221
|
+
- `max-live-nodes`: `320` (default virtualization) or `0` (incremental batches).
|
|
222
|
+
- `batchRendering`: fine-tune batches with `initialRenderBatchSize`, `renderBatchSize`, `renderBatchDelay`, `renderBatchBudgetMs`.
|
|
223
|
+
- `enableMermaid` / `enableKatex` / `enableMonaco`: opt-in heavy deps when needed.
|
|
224
|
+
- `parse-options`: reuse parser hooks (e.g., `preTransformTokens`, `requireClosingStrong`) on the component.
|
|
225
|
+
- `custom-components`: register inline Vue components for custom tags/markers.
|
|
226
|
+
|
|
227
|
+
Example: map Markdown placeholders to Vue components
|
|
228
|
+
|
|
229
|
+
```ts
|
|
230
|
+
import { setCustomComponents } from 'markstream-vue'
|
|
231
|
+
|
|
232
|
+
setCustomComponents({
|
|
233
|
+
CALLOUT: () => import('./components/Callout.vue'),
|
|
234
|
+
})
|
|
235
|
+
|
|
236
|
+
// Markdown: [[CALLOUT:warning title="Heads up" body="Details here"]]
|
|
237
|
+
```
|
|
238
|
+
|
|
239
|
+
Or pass per-renderer:
|
|
240
|
+
|
|
241
|
+
```vue
|
|
242
|
+
<MarkdownRender
|
|
243
|
+
:content="doc"
|
|
244
|
+
:custom-components="{
|
|
245
|
+
CALLOUT: () => import('./components/Callout.vue'),
|
|
246
|
+
}"
|
|
247
|
+
/>
|
|
248
|
+
```
|
|
249
|
+
|
|
250
|
+
Parse hooks example (match server + client):
|
|
251
|
+
|
|
252
|
+
```vue
|
|
253
|
+
<MarkdownRender
|
|
254
|
+
:content="doc"
|
|
255
|
+
:parse-options="{
|
|
256
|
+
requireClosingStrong: true,
|
|
257
|
+
preTransformTokens: (tokens) => tokens,
|
|
258
|
+
}"
|
|
259
|
+
/>
|
|
260
|
+
```
|
|
261
|
+
|
|
262
|
+
## 🔥 Where it shines
|
|
263
|
+
|
|
264
|
+
- AI/chat UIs with long-form answers and Markdown tokens arriving over SSE/websocket.
|
|
265
|
+
- Docs, changelogs, and knowledge bases that need instant load but stay responsive as they grow.
|
|
266
|
+
- Streaming diffs and code review panes that benefit from Monaco live updates.
|
|
267
|
+
- Diagram-heavy content that should render progressively (Mermaid) without blocking.
|
|
268
|
+
- Embedding Vue components in Markdown-driven surfaces (callouts, widgets, CTA buttons).
|
|
269
|
+
|
|
270
|
+
## ❓ FAQ (quick answers)
|
|
271
|
+
|
|
272
|
+
- Mermaid/KaTeX not rendering? Install the peer (`mermaid` / `katex`) and pass `:enable-mermaid="true"` / `:enable-katex="true"` or call the loader setters.
|
|
273
|
+
- Bundle size: peers are optional and not bundled; import only `markstream-vue/index.css` once. Use Shiki (`MarkdownCodeBlockNode`) when Monaco is too heavy.
|
|
274
|
+
- Custom UI: register components via `setCustomComponents` (global) or `custom-components` prop, then emit markers/placeholders in Markdown and map them to Vue components.
|
|
275
|
+
|
|
276
|
+
## 🆚 Why markstream-vue over a typical Markdown renderer?
|
|
277
|
+
|
|
278
|
+
| Needs | Typical Markdown preview | markstream-vue |
|
|
279
|
+
| --- | --- | --- |
|
|
280
|
+
| Streaming input | Re-renders whole tree, flashes | Incremental batches with virtual windowing |
|
|
281
|
+
| Large code blocks | Slow re-highlight | Monaco streaming updates + Shiki option |
|
|
282
|
+
| Diagrams | Blocks while parsing | Progressive Mermaid with graceful fallback |
|
|
283
|
+
| Custom UI | Limited slots | Inline Vue components & typed nodes |
|
|
284
|
+
| Long docs | Memory spikes | Configurable live-node cap for steady usage |
|
|
285
|
+
|
|
286
|
+
## 🗺️ Roadmap (snapshot)
|
|
287
|
+
|
|
288
|
+
- More “instant start” templates (Vite + Nuxt + Tailwind) and updated StackBlitz.
|
|
289
|
+
- Additional codeblock presets (diff-friendly Shiki themes, Monaco decoration helpers).
|
|
290
|
+
- Cookbook docs for AI/chat patterns (SSE/WebSocket, retry/resume, markdown mid-states).
|
|
291
|
+
- More showcase examples for embedding Vue components inside Markdown surfaces.
|
|
292
|
+
|
|
293
|
+
## 📦 Releases
|
|
294
|
+
|
|
295
|
+
- Latest: [Releases](https://github.com/Simon-He95/markstream-vue/releases) — see highlights and upgrade notes.
|
|
296
|
+
- Full history: [CHANGELOG.md](./CHANGELOG.md)
|
|
297
|
+
- Recent highlights (0.0.3-beta.1/beta.0):
|
|
298
|
+
- Parser bumped to `stream-markdown-parser@0.0.36` for parsing fixes.
|
|
299
|
+
- Monaco upgrades with more languages/themes + diff-friendly code block tweaks.
|
|
300
|
+
- HTML/SVG preview dialog and AST debug view in the playground.
|
|
301
|
+
|
|
302
|
+
## 🧭 Showcase & examples
|
|
303
|
+
|
|
304
|
+
Build something with markstream-vue? Open a PR to add it here (include a link + 1 screenshot/GIF). Ideal fits: AI/chat UIs, streaming docs, diff/code-review panes, or Markdown-driven pages with embedded Vue components.
|
|
305
|
+
|
|
306
|
+
- **FlowNote** — streaming Markdown note app demo (SSE + virtual window) — https://markstream-vue.simonhe.me/
|
|
307
|
+
- **AI Chat surface** — playground “test” page showing incremental batches + share links — https://markstream-vue.simonhe.me/test
|
|
308
|
+
|
|
60
309
|
## 📺 Introduction Video
|
|
61
310
|
|
|
62
311
|
A short video introduces the key features and usage of markstream-vue:
|
|
@@ -79,6 +328,25 @@ Watch on Bilibili: [Open in Bilibili](https://www.bilibili.com/video/BV17Z4qzpE9
|
|
|
79
328
|
- 🎨 Flexible code block rendering: choose Monaco editor (`CodeBlockNode`) or lightweight Shiki highlighting (`MarkdownCodeBlockNode`)
|
|
80
329
|
- 🧰 Parser toolkit: [`stream-markdown-parser`](./packages/markdown-parser) now documents how to reuse the parser in workers/SSE streams and feed `<MarkdownRender :nodes>` directly, plus APIs for registering global plugins and custom math helpers.
|
|
81
330
|
|
|
331
|
+
## 🙌 Contributing & community
|
|
332
|
+
|
|
333
|
+
- Read the contributor guide: [CONTRIBUTING.md](./CONTRIBUTING.md) and follow the PR template.
|
|
334
|
+
- Be kind and follow the [Code of Conduct](./CODE_OF_CONDUCT.md).
|
|
335
|
+
- Issues: use templates for bugs/requests; attach a repro from https://markstream-vue.simonhe.me/test when possible.
|
|
336
|
+
- Questions? Start a discussion: https://github.com/Simon-He95/markstream-vue/discussions
|
|
337
|
+
- Chat live: Discord https://discord.gg/vkzdkjeRCW
|
|
338
|
+
- Looking to contribute? Start with [good first issues](https://github.com/Simon-He95/markstream-vue/labels/good%20first%20issue).
|
|
339
|
+
- Support guide: [SUPPORT.md](./SUPPORT.md)
|
|
340
|
+
- PRs: follow Conventional Commits, add tests for parser/render changes, and include screenshots/GIFs for UI tweaks.
|
|
341
|
+
- If the project helps you, consider starring and sharing the repo — it keeps the work sustainable.
|
|
342
|
+
- Security: see [SECURITY.md](./SECURITY.md) to report vulnerabilities privately.
|
|
343
|
+
|
|
344
|
+
### Quick ways to help
|
|
345
|
+
|
|
346
|
+
- Add repro links/screenshots to existing issues.
|
|
347
|
+
- Improve docs/examples (especially streaming + SSR/worker patterns).
|
|
348
|
+
- Share playground/test links that showcase performance edge cases.
|
|
349
|
+
|
|
82
350
|
## Troubleshooting & Common Issues
|
|
83
351
|
|
|
84
352
|
Troubleshooting has moved into the docs:
|
|
@@ -87,12 +355,18 @@ https://markstream-vue-docs.simonhe.me/guide/troubleshooting
|
|
|
87
355
|
If you can't find a solution there, open a GitHub issue:
|
|
88
356
|
https://github.com/Simon-He95/markstream-vue/issues
|
|
89
357
|
|
|
358
|
+
### Report an issue quickly
|
|
359
|
+
|
|
360
|
+
1. Reproduce in the test page and click “generate share link”: https://markstream-vue.simonhe.me/test
|
|
361
|
+
2. Open a bug report with the link and a screenshot: https://github.com/Simon-He95/markstream-vue/issues/new?template=bug_report.yml
|
|
362
|
+
|
|
90
363
|
## Thanks
|
|
91
364
|
|
|
92
365
|
This project uses and benefits from:
|
|
93
366
|
- [stream-monaco](https://github.com/Simon-He95/stream-monaco)
|
|
94
367
|
- [stream-markdown](https://github.com/Simon-He95/stream-markdown)
|
|
95
368
|
- [mermaid](https://mermaid-js.github.io/mermaid)
|
|
369
|
+
- [katex](https://katex.org/)
|
|
96
370
|
- [shiki](https://github.com/shikijs/shiki)
|
|
97
371
|
- [markdown-it-ts](https://github.com/Simon-He95/markdown-it-ts)
|
|
98
372
|
|
|
@@ -104,4 +378,4 @@ Thanks to the authors and contributors of these projects!
|
|
|
104
378
|
|
|
105
379
|
## License
|
|
106
380
|
|
|
107
|
-
[MIT](./
|
|
381
|
+
[MIT](./license) © [Simon He](https://github.com/Simon-He95)
|