markstream-vue2 0.0.19-beta.9 → 0.0.20
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 +107 -0
- package/dist/index.cjs +1 -1
- package/dist/index.css +1 -1
- package/dist/index.d.ts +573 -436
- package/dist/index.px.css +1 -1
- package/dist/index.tailwind.css +1 -1
- package/dist/tailwind.ts +1 -1
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -139,6 +139,55 @@ new Vue({
|
|
|
139
139
|
}).$mount('#app')
|
|
140
140
|
```
|
|
141
141
|
|
|
142
|
+
## Streaming best practices
|
|
143
|
+
|
|
144
|
+
- For high-frequency SSE / token streaming, prefer parsing outside the renderer and pass `nodes` instead of reparsing the whole `content` string every chunk.
|
|
145
|
+
- Keep `viewport-priority` enabled unless you explicitly want eager rendering. Mermaid / Monaco / D2 blocks now stay idle while offscreen and resume when they approach the viewport.
|
|
146
|
+
|
|
147
|
+
```vue
|
|
148
|
+
<template>
|
|
149
|
+
<MarkdownRender
|
|
150
|
+
:nodes="nodes"
|
|
151
|
+
:final="final"
|
|
152
|
+
:viewport-priority="true"
|
|
153
|
+
:defer-nodes-until-visible="true"
|
|
154
|
+
/>
|
|
155
|
+
</template>
|
|
156
|
+
```
|
|
157
|
+
|
|
158
|
+
## Heavy-node prop forwarding
|
|
159
|
+
|
|
160
|
+
`MarkdownRender` can forward framework-level props directly into specialized heavy renderers:
|
|
161
|
+
|
|
162
|
+
```vue
|
|
163
|
+
<template>
|
|
164
|
+
<MarkdownRender
|
|
165
|
+
:content="markdown"
|
|
166
|
+
:mermaid-props="{
|
|
167
|
+
showHeader: false,
|
|
168
|
+
renderDebounceMs: 180,
|
|
169
|
+
previewPollDelayMs: 500
|
|
170
|
+
}"
|
|
171
|
+
:d2-props="{ progressiveIntervalMs: 500 }"
|
|
172
|
+
:infographic-props="{ showHeader: false }"
|
|
173
|
+
/>
|
|
174
|
+
</template>
|
|
175
|
+
```
|
|
176
|
+
|
|
177
|
+
Notes:
|
|
178
|
+
- Use kebab-case in templates: `mermaid-props`, `d2-props`, `infographic-props`.
|
|
179
|
+
- These props are forwarded to the built-in Mermaid / D2 / Infographic blocks and to custom `mermaid` / `d2` / `infographic` overrides registered with `setCustomComponents(...)`.
|
|
180
|
+
|
|
181
|
+
## Mermaid tuning
|
|
182
|
+
|
|
183
|
+
Common `mermaid-props` keys for streaming scenarios:
|
|
184
|
+
|
|
185
|
+
- `renderDebounceMs`: delay partial/full progressive work during rapid token bursts.
|
|
186
|
+
- `contentStableDelayMs`: how long source mode waits before auto-switching back to preview when content stabilizes.
|
|
187
|
+
- `previewPollDelayMs`: initial delay before preview polling tries to upgrade a partial preview into a full render.
|
|
188
|
+
- `previewPollMaxDelayMs`: cap for preview polling backoff.
|
|
189
|
+
- `previewPollMaxAttempts`: maximum retry count while the Mermaid source is still incomplete.
|
|
190
|
+
|
|
142
191
|
## Build and size checks
|
|
143
192
|
|
|
144
193
|
```bash
|
|
@@ -174,6 +223,64 @@ Fix: align both to the same version (e.g. `2.6.14` or `2.7.16`).
|
|
|
174
223
|
Cause: Vue 2.6 + Composition API missing `_setupProxy` patch, or plugin not installed.
|
|
175
224
|
Fix: ensure `@vue/composition-api` is installed + `Vue.use(...)`, and update to the latest markstream-vue2 build.
|
|
176
225
|
|
|
226
|
+
### Custom node renders trigger `infinite update loop`
|
|
227
|
+
Cause: in Vue 2.6 / Vue CLI 4, recursively mounting another `MarkdownRender` inside a custom node component can create a render loop when the parent renderer is still streaming.
|
|
228
|
+
Fix: prefer `NestedRenderer` for nested streaming content. If you only need static HTML output, `renderNestedMarkdownToHtml(...)` is still available.
|
|
229
|
+
|
|
230
|
+
```ts
|
|
231
|
+
import { NestedRenderer } from 'markstream-vue2'
|
|
232
|
+
|
|
233
|
+
export default {
|
|
234
|
+
components: { NestedRenderer },
|
|
235
|
+
props: {
|
|
236
|
+
node: { type: Object, required: true },
|
|
237
|
+
},
|
|
238
|
+
}
|
|
239
|
+
```
|
|
240
|
+
|
|
241
|
+
```vue
|
|
242
|
+
<template>
|
|
243
|
+
<NestedRenderer
|
|
244
|
+
:node="node"
|
|
245
|
+
custom-id="chat-demo"
|
|
246
|
+
:custom-html-tags="['thinking']"
|
|
247
|
+
:typewriter="false"
|
|
248
|
+
:batch-rendering="false"
|
|
249
|
+
:viewport-priority="false"
|
|
250
|
+
:defer-nodes-until-visible="false"
|
|
251
|
+
/>
|
|
252
|
+
</template>
|
|
253
|
+
```
|
|
254
|
+
|
|
255
|
+
`NestedRenderer` keeps the inner content streamable, but switches the nested renderer to the `nodes` path so Vue 2.6 does not recurse through a second `content`-driven renderer.
|
|
256
|
+
|
|
257
|
+
If you cannot mount another renderer and just need a static nested body, use `renderNestedMarkdownToHtml(...)`:
|
|
258
|
+
|
|
259
|
+
```ts
|
|
260
|
+
import { renderNestedMarkdownToHtml } from 'markstream-vue2'
|
|
261
|
+
|
|
262
|
+
export default {
|
|
263
|
+
props: {
|
|
264
|
+
node: { type: Object, required: true },
|
|
265
|
+
},
|
|
266
|
+
computed: {
|
|
267
|
+
renderedHtml() {
|
|
268
|
+
return renderNestedMarkdownToHtml(
|
|
269
|
+
{ node: this.node },
|
|
270
|
+
{
|
|
271
|
+
customHtmlTags: ['thinking'],
|
|
272
|
+
customNodeClass(node) {
|
|
273
|
+
return node.type === 'thinking' ? 'thinking-node__nested' : ''
|
|
274
|
+
},
|
|
275
|
+
},
|
|
276
|
+
)
|
|
277
|
+
},
|
|
278
|
+
},
|
|
279
|
+
}
|
|
280
|
+
```
|
|
281
|
+
|
|
282
|
+
This keeps deeply nested custom content streamable without recursively mounting a second `content`-driven `MarkdownRender` / `NodeRenderer`.
|
|
283
|
+
|
|
177
284
|
## Tailwind
|
|
178
285
|
|
|
179
286
|
If your app uses Tailwind and you want to avoid shipping duplicated utility CSS, import the Tailwind-ready output instead:
|