markstream-svelte 2.0.0 → 2.0.1
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.
|
@@ -55,6 +55,8 @@
|
|
|
55
55
|
let rendering = $state(false)
|
|
56
56
|
let rerenderQueued = $state(false)
|
|
57
57
|
let rerenderForce = $state(false)
|
|
58
|
+
let renderScheduled = $state(false)
|
|
59
|
+
let renderScheduledForce = $state(false)
|
|
58
60
|
let hasPreview = $state(false)
|
|
59
61
|
let copied = $state(false)
|
|
60
62
|
let collapsed = $state(false)
|
|
@@ -111,7 +113,16 @@
|
|
|
111
113
|
function queueInfographicRender(force = false) {
|
|
112
114
|
if (!mounted || !renderHost || collapsed || showSource || !source.trim())
|
|
113
115
|
return
|
|
114
|
-
|
|
116
|
+
renderScheduledForce = renderScheduledForce || force
|
|
117
|
+
if (renderScheduled)
|
|
118
|
+
return
|
|
119
|
+
renderScheduled = true
|
|
120
|
+
void tick().then(() => {
|
|
121
|
+
renderScheduled = false
|
|
122
|
+
const forceNext = renderScheduledForce
|
|
123
|
+
renderScheduledForce = false
|
|
124
|
+
return renderInfographic(forceNext)
|
|
125
|
+
})
|
|
115
126
|
}
|
|
116
127
|
|
|
117
128
|
async function renderInfographic(force = false) {
|
|
@@ -128,7 +139,9 @@
|
|
|
128
139
|
return
|
|
129
140
|
}
|
|
130
141
|
|
|
131
|
-
const
|
|
142
|
+
const renderSource = source
|
|
143
|
+
const renderFinal = final
|
|
144
|
+
const signature = `${renderSource}\n${resolvedIsDark}\n${renderFinal}\n${progressivePreview}`
|
|
132
145
|
if (!force && signature === lastCompletedRenderSignature && hasPreview)
|
|
133
146
|
return
|
|
134
147
|
if (!force && signature === lastSuppressedErrorSignature)
|
|
@@ -148,6 +161,8 @@
|
|
|
148
161
|
rendering = true
|
|
149
162
|
if (shouldShowError)
|
|
150
163
|
renderError = ''
|
|
164
|
+
let nextInstance: any = null
|
|
165
|
+
let previousChildren: ChildNode[] | null = null
|
|
151
166
|
|
|
152
167
|
try {
|
|
153
168
|
const InfographicClass = await getInfographic()
|
|
@@ -155,17 +170,22 @@
|
|
|
155
170
|
return
|
|
156
171
|
if (!InfographicClass)
|
|
157
172
|
throw new Error('Infographic renderer is not available.')
|
|
173
|
+
const currentSignature = `${source}\n${resolvedIsDark}\n${final}\n${progressivePreview}`
|
|
174
|
+
const canRender = signature === currentSignature
|
|
175
|
+
|| (!renderFinal && resolvedLoading && source.startsWith(renderSource))
|
|
176
|
+
if (!canRender)
|
|
177
|
+
return
|
|
158
178
|
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
instance = new InfographicClass({
|
|
179
|
+
previousChildren = Array.from(renderHost.childNodes)
|
|
180
|
+
nextInstance = new InfographicClass({
|
|
162
181
|
container: renderHost,
|
|
163
182
|
width: '100%',
|
|
164
183
|
height: '100%',
|
|
165
184
|
})
|
|
166
185
|
|
|
167
186
|
let renderErrorMessage = ''
|
|
168
|
-
|
|
187
|
+
let renderCompleted = false
|
|
188
|
+
nextInstance.on?.('error', (error: unknown) => {
|
|
169
189
|
const errors = Array.isArray(error) ? error : [error]
|
|
170
190
|
renderErrorMessage = errors
|
|
171
191
|
.map((item) => {
|
|
@@ -180,15 +200,24 @@
|
|
|
180
200
|
.filter(Boolean)
|
|
181
201
|
.join('; ')
|
|
182
202
|
})
|
|
203
|
+
nextInstance.on?.('rendered', () => {
|
|
204
|
+
renderCompleted = true
|
|
205
|
+
})
|
|
183
206
|
|
|
184
|
-
|
|
207
|
+
nextInstance.render(renderSource)
|
|
185
208
|
if (renderErrorMessage)
|
|
186
209
|
throw new Error(renderErrorMessage)
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
210
|
+
const nextChildren = Array.from(renderHost.childNodes)
|
|
211
|
+
const replacedChildren = nextChildren.length > 0 && (
|
|
212
|
+
nextChildren.length !== previousChildren.length
|
|
213
|
+
|| nextChildren.some((child, index) => child !== previousChildren?.[index])
|
|
214
|
+
)
|
|
215
|
+
if (!renderCompleted && !replacedChildren)
|
|
191
216
|
throw new Error('Infographic render returned empty output.')
|
|
217
|
+
|
|
218
|
+
instance?.destroy?.()
|
|
219
|
+
instance = nextInstance
|
|
220
|
+
nextInstance = null
|
|
192
221
|
hasPreview = true
|
|
193
222
|
renderError = ''
|
|
194
223
|
lastCompletedRenderSignature = signature
|
|
@@ -196,8 +225,11 @@
|
|
|
196
225
|
}
|
|
197
226
|
catch (error) {
|
|
198
227
|
if (token === renderToken) {
|
|
228
|
+
nextInstance?.destroy?.()
|
|
229
|
+
nextInstance = null
|
|
199
230
|
lastCompletedRenderSignature = ''
|
|
200
|
-
|
|
231
|
+
const currentSignature = `${source}\n${resolvedIsDark}\n${final}\n${progressivePreview}`
|
|
232
|
+
if (shouldShowError && signature === currentSignature) {
|
|
201
233
|
lastSuppressedErrorSignature = ''
|
|
202
234
|
destroyInstance()
|
|
203
235
|
clearElement(renderHost)
|
|
@@ -205,11 +237,15 @@
|
|
|
205
237
|
renderError = error instanceof Error ? error.message : String(error)
|
|
206
238
|
}
|
|
207
239
|
else {
|
|
208
|
-
|
|
240
|
+
if (previousChildren && renderHost)
|
|
241
|
+
renderHost.replaceChildren(...previousChildren)
|
|
242
|
+
if (signature === currentSignature)
|
|
243
|
+
lastSuppressedErrorSignature = signature
|
|
209
244
|
}
|
|
210
245
|
}
|
|
211
246
|
}
|
|
212
247
|
finally {
|
|
248
|
+
nextInstance?.destroy?.()
|
|
213
249
|
if (token === renderToken) {
|
|
214
250
|
rendering = false
|
|
215
251
|
activeRenderSignature = ''
|
|
@@ -239,6 +275,8 @@
|
|
|
239
275
|
rendering = false
|
|
240
276
|
rerenderQueued = false
|
|
241
277
|
rerenderForce = false
|
|
278
|
+
renderScheduled = false
|
|
279
|
+
renderScheduledForce = false
|
|
242
280
|
hasPreview = false
|
|
243
281
|
renderError = ''
|
|
244
282
|
activeRenderSignature = ''
|
|
@@ -417,6 +455,9 @@
|
|
|
417
455
|
</div>
|
|
418
456
|
{/if}
|
|
419
457
|
<div class="infographic-render" style={previewStyle}>
|
|
458
|
+
{#if !hasPreview && !renderError}
|
|
459
|
+
<pre class="infographic-source-code infographic-pending-source"><code>{source}</code></pre>
|
|
460
|
+
{/if}
|
|
420
461
|
<div bind:this={renderHost} style={transformStyle}></div>
|
|
421
462
|
{#if renderError}
|
|
422
463
|
<p class="d2-error">{renderError}</p>
|
package/dist/index.css
CHANGED
|
@@ -2126,6 +2126,15 @@ body > div[id^="dmermaid-"] {
|
|
|
2126
2126
|
text-align: center;
|
|
2127
2127
|
}
|
|
2128
2128
|
|
|
2129
|
+
.markstream-svelte .infographic-pending-source {
|
|
2130
|
+
position: absolute;
|
|
2131
|
+
inset: 0;
|
|
2132
|
+
z-index: 1;
|
|
2133
|
+
overflow: auto;
|
|
2134
|
+
padding: var(--ms-inset-panel-body);
|
|
2135
|
+
text-align: left;
|
|
2136
|
+
}
|
|
2137
|
+
|
|
2129
2138
|
.markstream-svelte .infographic-render > div {
|
|
2130
2139
|
transition: transform 120ms ease;
|
|
2131
2140
|
}
|
package/dist/index.px.css
CHANGED
|
@@ -2126,6 +2126,15 @@ body > div[id^="dmermaid-"] {
|
|
|
2126
2126
|
text-align: center;
|
|
2127
2127
|
}
|
|
2128
2128
|
|
|
2129
|
+
.markstream-svelte .infographic-pending-source {
|
|
2130
|
+
position: absolute;
|
|
2131
|
+
inset: 0;
|
|
2132
|
+
z-index: 1;
|
|
2133
|
+
overflow: auto;
|
|
2134
|
+
padding: var(--ms-inset-panel-body);
|
|
2135
|
+
text-align: left;
|
|
2136
|
+
}
|
|
2137
|
+
|
|
2129
2138
|
.markstream-svelte .infographic-render > div {
|
|
2130
2139
|
transition: transform 120ms ease;
|
|
2131
2140
|
}
|
package/dist/index.tailwind.css
CHANGED
|
@@ -2126,6 +2126,15 @@ body > div[id^="dmermaid-"] {
|
|
|
2126
2126
|
text-align: center;
|
|
2127
2127
|
}
|
|
2128
2128
|
|
|
2129
|
+
.markstream-svelte .infographic-pending-source {
|
|
2130
|
+
position: absolute;
|
|
2131
|
+
inset: 0;
|
|
2132
|
+
z-index: 1;
|
|
2133
|
+
overflow: auto;
|
|
2134
|
+
padding: var(--ms-inset-panel-body);
|
|
2135
|
+
text-align: left;
|
|
2136
|
+
}
|
|
2137
|
+
|
|
2129
2138
|
.markstream-svelte .infographic-render > div {
|
|
2130
2139
|
transition: transform 120ms ease;
|
|
2131
2140
|
}
|
|
@@ -22,7 +22,6 @@ export interface CodeBlockOptions {
|
|
|
22
22
|
disableLineNumbers?: boolean;
|
|
23
23
|
overflow?: 'scroll' | 'wrap';
|
|
24
24
|
disableVirtualizationBuffers?: boolean;
|
|
25
|
-
preferredHighlighter?: 'shiki-js' | 'shiki-wasm';
|
|
26
25
|
useCSSClasses?: boolean;
|
|
27
26
|
useTokenTransformer?: boolean;
|
|
28
27
|
tokenizeMaxLineLength?: number;
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "markstream-svelte",
|
|
3
3
|
"type": "module",
|
|
4
|
-
"version": "2.0.
|
|
4
|
+
"version": "2.0.1",
|
|
5
5
|
"description": "Svelte 5 and SvelteKit streaming Markdown renderer for AI chat, LLM token streams, SSE/WebSocket output, incomplete Markdown, Mermaid, KaTeX, stream-diffs powered code blocks, and custom Svelte components.",
|
|
6
6
|
"author": "Simon He",
|
|
7
7
|
"license": "MIT",
|
|
@@ -100,8 +100,8 @@
|
|
|
100
100
|
},
|
|
101
101
|
"dependencies": {
|
|
102
102
|
"@floating-ui/dom": "^1.8.0",
|
|
103
|
-
"
|
|
104
|
-
"
|
|
103
|
+
"stream-markdown-parser": "1.2.9",
|
|
104
|
+
"markstream-core": "2.0.1"
|
|
105
105
|
},
|
|
106
106
|
"devDependencies": {
|
|
107
107
|
"@sveltejs/package": "^2.5.8",
|