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 CHANGED
@@ -5,24 +5,63 @@
5
5
  [![NPM version](https://img.shields.io/npm/v/markstream-vue?color=a1b858&label=)](https://www.npmjs.com/package/markstream-vue)
6
6
  [![中文版](https://img.shields.io/badge/docs-中文文档-blue)](README.zh-CN.md)
7
7
  [![Docs](https://img.shields.io/badge/docs-vitepress-blue)](https://markstream-vue-docs.simonhe.me/)
8
+ [![Playground](https://img.shields.io/badge/playground-live-34c759)](https://markstream-vue.simonhe.me/)
9
+ [![Test page](https://img.shields.io/badge/test-shareable%20repro-0A84FF)](https://markstream-vue.simonhe.me/test)
8
10
  [![NPM downloads](https://img.shields.io/npm/dm/markstream-vue)](https://www.npmjs.com/package/markstream-vue)
9
11
  [![Bundle size](https://img.shields.io/bundlephobia/minzip/markstream-vue)](https://bundlephobia.com/package/markstream-vue)
12
+ [![Release](https://img.shields.io/github/v/release/Simon-He95/markstream-vue?display_name=release&logo=github)](https://github.com/Simon-He95/markstream-vue/releases)
13
+ [![Discussions](https://img.shields.io/github/discussions/Simon-He95/markstream-vue?logo=github)](https://github.com/Simon-He95/markstream-vue/discussions)
14
+ [![Discord](https://img.shields.io/discord/986352439269560380?label=discord&logo=discord&logoColor=fff&color=5865F2)](https://discord.gg/vkzdkjeRCW)
15
+ [![Support](https://img.shields.io/badge/support-guide-ff6f61)](./SUPPORT.md)
16
+ [![Security](https://img.shields.io/badge/security-policy-8A2BE2)](./SECURITY.md)
17
+ [![CI](https://github.com/Simon-He95/markstream-vue/actions/workflows/ci.yml/badge.svg)](https://github.com/Simon-He95/markstream-vue/actions/workflows/ci.yml)
10
18
  [![License](https://img.shields.io/npm/l/markstream-vue)](./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
- ## 🚀 Playground & Demo
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
- Try the interactive test page to quickly verify and debug:
21
- https://markstream-vue.simonhe.me/test
58
+ ## 💬 Community & support
22
59
 
23
- This page provides a left editor and right live preview (powered by this library). It includes "generate & copy share link" functionality, encoding your input into the URL for sharing. If the input is too long, fallback options are provided to open directly or pre-fill a GitHub Issue.
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
- You can use this page to reproduce rendering issues, verify math/Mermaid/code block behavior, and quickly generate shareable links or reproducible issues.
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](./LICENSE) © [Simon He](https://github.com/Simon-He95)
381
+ [MIT](./license) © [Simon He](https://github.com/Simon-He95)