markstream-solid 0.0.0-stage → 2.0.23
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 +120 -2
- package/dist/client/extended-BTbixd9o.js +38 -0
- package/dist/client/index.js +5640 -0
- package/dist/client/katexWorkerClient-ZLzkPVv_.js +260 -0
- package/dist/client/languageIcon-CDTPjsAQ.js +280 -0
- package/dist/client/mermaidWorkerClient-BAvGYsCO.js +243 -0
- package/dist/client/utils/index.js +31 -0
- package/dist/client/utils/katex-threshold.js +32 -0
- package/dist/client/utils/performance-monitor.js +73 -0
- package/dist/client/utils/safeRaf.js +27 -0
- package/dist/client/workers/katexCdnWorker.js +177 -0
- package/dist/client/workers/katexRenderer.worker.js +45 -0
- package/dist/client/workers/katexWorkerClient.js +16 -0
- package/dist/client/workers/mermaidCdnWorker.js +226 -0
- package/dist/client/workers/mermaidParser.worker.js +73 -0
- package/dist/client/workers/mermaidWorkerClient.js +13 -0
- package/dist/components/BuiltinNodes.d.ts +42 -0
- package/dist/components/CodeBlockNode.d.ts +10 -0
- package/dist/components/DiagramBlockNode.d.ts +27 -0
- package/dist/components/HtmlPreviewFrame.d.ts +10 -0
- package/dist/components/MarkstreamProvider.d.ts +5 -0
- package/dist/components/MarkstreamVirtualTimeline.d.ts +35 -0
- package/dist/components/MathNode.d.ts +6 -0
- package/dist/components/NodeRenderer.d.ts +27 -0
- package/dist/components/NodeSlot.d.ts +11 -0
- package/dist/components/PreCodeBlock.d.ts +3 -0
- package/dist/components/PreCodeNode.d.ts +9 -0
- package/dist/components/RenderNode.d.ts +11 -0
- package/dist/components/StreamingTextNode.d.ts +2 -0
- package/dist/components/ToolbarButton.d.ts +14 -0
- package/dist/components/ToolbarIcon.d.ts +18 -0
- package/dist/components/Tooltip.d.ts +13 -0
- package/dist/components/lifecycle.d.ts +6 -0
- package/dist/components/mathHeightCache.d.ts +5 -0
- package/dist/components/rendererModeDefaults.d.ts +4 -0
- package/dist/components/shared/diagram-height.d.ts +16 -0
- package/dist/components/shared/node-helpers.d.ts +78 -0
- package/dist/components/shared/node-outlet-helpers.d.ts +10 -0
- package/dist/components/shared/render-window.d.ts +18 -0
- package/dist/components/shared/reuseParsedNodes.d.ts +3 -0
- package/dist/components/viewport.d.ts +5 -0
- package/dist/components/virtualLayoutKey.d.ts +13 -0
- package/dist/configuration.d.ts +9 -0
- package/dist/customComponents.d.ts +36 -0
- package/dist/enhanceRenderedHtml.d.ts +25 -0
- package/dist/hydrateCustomTagContent.d.ts +2 -0
- package/dist/i18n/useSafeI18n.d.ts +4 -0
- package/dist/icon-themes/index.d.ts +2 -0
- package/dist/icon-themes/material/core.d.ts +2 -0
- package/dist/icon-themes/material/extended.d.ts +2 -0
- package/dist/icon-themes/material/index.d.ts +2 -0
- package/dist/icon-themes/registry.d.ts +9 -0
- package/dist/icon-themes/types.d.ts +11 -0
- package/dist/index.css +3279 -0
- package/dist/index.d.ts +48 -0
- package/dist/index.px.css +3279 -0
- package/dist/index.tailwind.css +3279 -0
- package/dist/optional/d2.d.ts +17 -0
- package/dist/optional/infographic.d.ts +31 -0
- package/dist/optional/katex.d.ts +9 -0
- package/dist/optional/mermaid.d.ts +27 -0
- package/dist/optional/streamDiffs.d.ts +29 -0
- package/dist/renderMarkdownHtml.d.ts +30 -0
- package/dist/sanitizeHtmlContent.d.ts +2 -0
- package/dist/server/extended-CKyCqQt3.js +69 -0
- package/dist/server/index.js +6264 -0
- package/dist/server/languageIcon-TXkIEBPf.js +353 -0
- package/dist/server/utils/index.js +31 -0
- package/dist/server/utils/katex-threshold.js +41 -0
- package/dist/server/utils/performance-monitor.js +120 -0
- package/dist/server/utils/safeRaf.js +28 -0
- package/dist/server/workers/katexCdnWorker.js +190 -0
- package/dist/server/workers/katexWorkerClient.js +373 -0
- package/dist/server/workers/mermaidCdnWorker.js +238 -0
- package/dist/server/workers/mermaidWorkerClient.js +333 -0
- package/dist/streamDiffsWorker.d.ts +72 -0
- package/dist/tailwind.d.ts +2 -0
- package/dist/tailwind.js +3 -0
- package/dist/tooltip/singletonTooltip.d.ts +7 -0
- package/dist/types/component-props.d.ts +253 -0
- package/dist/types/node-renderer-props.d.ts +333 -0
- package/dist/useSmoothMarkdownStream.d.ts +22 -0
- package/dist/utils/clipboard.d.ts +1 -0
- package/dist/utils/d2RenderSalt.d.ts +1 -0
- package/dist/utils/footnoteTarget.d.ts +1 -0
- package/dist/utils/index.d.ts +8 -0
- package/dist/utils/katex-threshold.d.ts +20 -0
- package/dist/utils/languageIcon.d.ts +8 -0
- package/dist/utils/mermaidRenderId.d.ts +1 -0
- package/dist/utils/normalizeKaTeXRenderInput.d.ts +1 -0
- package/dist/utils/performance-monitor.d.ts +121 -0
- package/dist/utils/resolveLanguageIcon.d.ts +2 -0
- package/dist/utils/safeRaf.d.ts +2 -0
- package/dist/utils/virtualItemMeasurement.d.ts +5 -0
- package/dist/virtual-adapter.d.ts +165 -0
- package/dist/workers/katexCdnWorker.d.ts +20 -0
- package/dist/workers/katexRenderer.worker.d.ts +1 -0
- package/dist/workers/katexWorkerClient.d.ts +35 -0
- package/dist/workers/mermaidCdnWorker.d.ts +15 -0
- package/dist/workers/mermaidParser.worker.d.ts +1 -0
- package/dist/workers/mermaidWorkerClient.d.ts +15 -0
- package/package.json +149 -3
|
@@ -0,0 +1,243 @@
|
|
|
1
|
+
const z = () => import("mermaid"), E = "__MARKSTREAM_SOLID_MERMAID__";
|
|
2
|
+
let l = null, d = !1, W = null, m = null, I = z;
|
|
3
|
+
function _(e) {
|
|
4
|
+
const r = String(e?.securityLevel ?? "strict"), t = e?.flowchart?.htmlLabels;
|
|
5
|
+
return `${r}|htmlLabels:${t === !1 ? "0" : "1"}`;
|
|
6
|
+
}
|
|
7
|
+
function w(e) {
|
|
8
|
+
if (!e)
|
|
9
|
+
return e;
|
|
10
|
+
const r = e?.default ?? e;
|
|
11
|
+
if (r && (typeof r.render == "function" || typeof r.parse == "function" || typeof r.initialize == "function"))
|
|
12
|
+
return r;
|
|
13
|
+
if (r?.mermaidAPI && (typeof r.mermaidAPI.render == "function" || typeof r.mermaidAPI.parse == "function")) {
|
|
14
|
+
const t = r.mermaidAPI;
|
|
15
|
+
return {
|
|
16
|
+
...r,
|
|
17
|
+
render: t.render.bind(t),
|
|
18
|
+
parse: t.parse ? t.parse.bind(t) : void 0,
|
|
19
|
+
initialize: (i) => typeof r.initialize == "function" ? r.initialize(i) : t.initialize ? t.initialize(i) : void 0
|
|
20
|
+
};
|
|
21
|
+
}
|
|
22
|
+
return e?.mermaid && typeof e.mermaid.render == "function" ? e.mermaid : r;
|
|
23
|
+
}
|
|
24
|
+
function b(e) {
|
|
25
|
+
if (e)
|
|
26
|
+
try {
|
|
27
|
+
const r = e?.initialize;
|
|
28
|
+
e.initialize = (t) => {
|
|
29
|
+
const i = { suppressErrorRendering: !0, ...t || {} };
|
|
30
|
+
if (typeof r == "function")
|
|
31
|
+
return r.call(e, i);
|
|
32
|
+
if (e?.mermaidAPI && typeof e.mermaidAPI.initialize == "function")
|
|
33
|
+
return e.mermaidAPI.initialize(i);
|
|
34
|
+
};
|
|
35
|
+
} catch {
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
function k(e, r) {
|
|
39
|
+
if (!e || !r)
|
|
40
|
+
return;
|
|
41
|
+
const t = _(r);
|
|
42
|
+
if (W !== t)
|
|
43
|
+
try {
|
|
44
|
+
typeof e.initialize == "function" ? e.initialize(r) : e.mermaidAPI?.initialize && e.mermaidAPI.initialize(r), W = t;
|
|
45
|
+
} catch {
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
function D() {
|
|
49
|
+
try {
|
|
50
|
+
const e = globalThis;
|
|
51
|
+
return w(e?.[E] ?? e?.mermaid);
|
|
52
|
+
} catch {
|
|
53
|
+
return null;
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
function g(e) {
|
|
57
|
+
try {
|
|
58
|
+
globalThis[E] = e;
|
|
59
|
+
} catch {
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
function L() {
|
|
63
|
+
l = null, d = !1, W = null, m = null;
|
|
64
|
+
try {
|
|
65
|
+
delete globalThis[E];
|
|
66
|
+
} catch {
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
function A(e) {
|
|
70
|
+
I = e, L();
|
|
71
|
+
}
|
|
72
|
+
function K(e) {
|
|
73
|
+
A(e ?? z);
|
|
74
|
+
}
|
|
75
|
+
function v() {
|
|
76
|
+
A(null);
|
|
77
|
+
}
|
|
78
|
+
function j() {
|
|
79
|
+
return typeof I == "function";
|
|
80
|
+
}
|
|
81
|
+
async function x(e) {
|
|
82
|
+
if (l)
|
|
83
|
+
return k(l, e), l;
|
|
84
|
+
const r = D();
|
|
85
|
+
if (r)
|
|
86
|
+
return b(r), l = r, g(l), k(l, e), l;
|
|
87
|
+
if (m) {
|
|
88
|
+
const i = await m;
|
|
89
|
+
return i && k(i, e), i;
|
|
90
|
+
}
|
|
91
|
+
if (d)
|
|
92
|
+
return null;
|
|
93
|
+
const t = I;
|
|
94
|
+
if (!t)
|
|
95
|
+
return d = !0, null;
|
|
96
|
+
m = (async () => {
|
|
97
|
+
try {
|
|
98
|
+
const i = await t(), o = w(i);
|
|
99
|
+
return o ? (b(o), l = o, g(l), l) : (d = !0, null);
|
|
100
|
+
} catch {
|
|
101
|
+
return d = !0, null;
|
|
102
|
+
}
|
|
103
|
+
})();
|
|
104
|
+
try {
|
|
105
|
+
const i = await m;
|
|
106
|
+
return i && k(i, e), i;
|
|
107
|
+
} finally {
|
|
108
|
+
m = null;
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
let a = null, u = null;
|
|
112
|
+
const n = /* @__PURE__ */ new Map();
|
|
113
|
+
let y = 5, P = !1;
|
|
114
|
+
function B(e) {
|
|
115
|
+
P = !!e;
|
|
116
|
+
}
|
|
117
|
+
function U(e) {
|
|
118
|
+
Number.isFinite(e) && e > 0 && (y = Math.floor(e));
|
|
119
|
+
}
|
|
120
|
+
function F() {
|
|
121
|
+
return { inFlight: n.size, max: y };
|
|
122
|
+
}
|
|
123
|
+
const O = "WORKER_BUSY", T = "MERMAID_DISABLED";
|
|
124
|
+
function G(e) {
|
|
125
|
+
a = e, u = null;
|
|
126
|
+
const r = e;
|
|
127
|
+
a.onmessage = (t) => {
|
|
128
|
+
if (a !== r)
|
|
129
|
+
return;
|
|
130
|
+
const { id: i, ok: o, result: M, error: c } = t.data || {}, f = n.get(i);
|
|
131
|
+
f && (o === !1 || c ? f.reject(new Error(c || "Unknown error")) : f.resolve(M));
|
|
132
|
+
}, a.onerror = (t) => {
|
|
133
|
+
if (a === r) {
|
|
134
|
+
if (n.size === 0) {
|
|
135
|
+
console.debug?.("[markstream-solid:mermaidWorkerClient] Worker error (idle):", t?.message || t);
|
|
136
|
+
return;
|
|
137
|
+
}
|
|
138
|
+
try {
|
|
139
|
+
P ? console.error("[markstream-solid:mermaidWorkerClient] Worker error:", t?.message || t) : console.debug?.("[markstream-solid:mermaidWorkerClient] Worker error:", t?.message || t);
|
|
140
|
+
} catch {
|
|
141
|
+
}
|
|
142
|
+
for (const [, i] of n.entries())
|
|
143
|
+
i.reject(new Error(`Worker error: ${t.message}`));
|
|
144
|
+
n.clear();
|
|
145
|
+
}
|
|
146
|
+
}, a.onmessageerror = (t) => {
|
|
147
|
+
if (a === r) {
|
|
148
|
+
if (n.size === 0) {
|
|
149
|
+
console.debug?.("[markstream-solid:mermaidWorkerClient] Worker messageerror (idle):", t);
|
|
150
|
+
return;
|
|
151
|
+
}
|
|
152
|
+
for (const [, i] of n.entries())
|
|
153
|
+
i.reject(new Error("Worker messageerror"));
|
|
154
|
+
n.clear();
|
|
155
|
+
}
|
|
156
|
+
};
|
|
157
|
+
}
|
|
158
|
+
function N() {
|
|
159
|
+
if (a)
|
|
160
|
+
try {
|
|
161
|
+
for (const [, e] of n.entries())
|
|
162
|
+
e.reject(new Error("Worker cleared"));
|
|
163
|
+
n.clear(), a.terminate?.();
|
|
164
|
+
} catch {
|
|
165
|
+
}
|
|
166
|
+
a = null, u = null;
|
|
167
|
+
}
|
|
168
|
+
function C() {
|
|
169
|
+
return a || (u = new Error("[markstream-solid:mermaidWorkerClient] No worker instance set. Please inject a Worker via setMermaidWorker()."), u.name = "WorkerInitError", u.code = "WORKER_INIT_ERROR", null);
|
|
170
|
+
}
|
|
171
|
+
function R(e, r, t = 1400) {
|
|
172
|
+
if (!j()) {
|
|
173
|
+
const o = new Error("Mermaid rendering disabled");
|
|
174
|
+
return o.name = "MermaidDisabled", o.code = T, Promise.reject(o);
|
|
175
|
+
}
|
|
176
|
+
if (u)
|
|
177
|
+
return Promise.reject(u);
|
|
178
|
+
const i = C();
|
|
179
|
+
if (!i)
|
|
180
|
+
return Promise.reject(u);
|
|
181
|
+
if (n.size >= y) {
|
|
182
|
+
const o = new Error("Worker busy");
|
|
183
|
+
return o.name = "WorkerBusy", o.code = O, o.inFlight = n.size, o.max = y, Promise.reject(o);
|
|
184
|
+
}
|
|
185
|
+
return new Promise((o, M) => {
|
|
186
|
+
const c = Math.random().toString(36).slice(2);
|
|
187
|
+
let f = !1, p = null;
|
|
188
|
+
const h = () => {
|
|
189
|
+
f || (f = !0, p != null && clearTimeout(p), n.delete(c));
|
|
190
|
+
};
|
|
191
|
+
n.set(c, {
|
|
192
|
+
resolve: (s) => {
|
|
193
|
+
h(), o(s);
|
|
194
|
+
},
|
|
195
|
+
reject: (s) => {
|
|
196
|
+
h(), M(s);
|
|
197
|
+
}
|
|
198
|
+
});
|
|
199
|
+
try {
|
|
200
|
+
i.postMessage({ id: c, action: e, payload: r });
|
|
201
|
+
} catch (s) {
|
|
202
|
+
n.delete(c), M(s);
|
|
203
|
+
return;
|
|
204
|
+
}
|
|
205
|
+
p = setTimeout(() => {
|
|
206
|
+
const s = new Error("Worker call timed out");
|
|
207
|
+
s.name = "WorkerTimeout", s.code = "WORKER_TIMEOUT", n.get(c)?.reject(s);
|
|
208
|
+
}, t);
|
|
209
|
+
});
|
|
210
|
+
}
|
|
211
|
+
async function Y(e, r, t = 1400) {
|
|
212
|
+
return await R("canParse", { code: e, theme: r }, t);
|
|
213
|
+
}
|
|
214
|
+
async function $(e, r, t = 1400) {
|
|
215
|
+
return await R("findPrefix", { code: e, theme: r }, t);
|
|
216
|
+
}
|
|
217
|
+
function q() {
|
|
218
|
+
if (a)
|
|
219
|
+
try {
|
|
220
|
+
for (const [, e] of n.entries())
|
|
221
|
+
e.reject(new Error("Worker terminated"));
|
|
222
|
+
n.clear(), a.terminate();
|
|
223
|
+
} finally {
|
|
224
|
+
a = null;
|
|
225
|
+
}
|
|
226
|
+
}
|
|
227
|
+
export {
|
|
228
|
+
T as M,
|
|
229
|
+
O as a,
|
|
230
|
+
N as b,
|
|
231
|
+
Y as c,
|
|
232
|
+
v as d,
|
|
233
|
+
K as e,
|
|
234
|
+
$ as f,
|
|
235
|
+
x as g,
|
|
236
|
+
F as h,
|
|
237
|
+
j as i,
|
|
238
|
+
G as j,
|
|
239
|
+
B as k,
|
|
240
|
+
U as l,
|
|
241
|
+
A as s,
|
|
242
|
+
q as t
|
|
243
|
+
};
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import { N as o, g as r, a as s, i as n, l as t, d as g, n as i, p as l, e as m, r as d, h as f, s as c, j as u, u as R } from "../languageIcon-CDTPjsAQ.js";
|
|
2
|
+
import { defaultRByClass as I, estimateRByFormula as L, recommendNForSamples as M, recommendWorkerThreshold as h } from "./katex-threshold.js";
|
|
3
|
+
import { disablePerfMonitoring as C, enablePerfMonitoring as E, getPerfReport as T, perfMonitor as k } from "./performance-monitor.js";
|
|
4
|
+
import { safeCancelRaf as B, safeRaf as N } from "./safeRaf.js";
|
|
5
|
+
export * from "stream-markdown-parser";
|
|
6
|
+
export {
|
|
7
|
+
o as MARKSTREAM_NODE_LIFECYCLE_KEY,
|
|
8
|
+
I as defaultRByClass,
|
|
9
|
+
C as disablePerfMonitoring,
|
|
10
|
+
E as enablePerfMonitoring,
|
|
11
|
+
L as estimateRByFormula,
|
|
12
|
+
r as getLanguageIcon,
|
|
13
|
+
T as getPerfReport,
|
|
14
|
+
s as getRegisteredThemes,
|
|
15
|
+
n as isCodeBlockRuntimeReady,
|
|
16
|
+
t as languageIconsRevision,
|
|
17
|
+
g as languageMap,
|
|
18
|
+
i as normalizeLanguageIdentifier,
|
|
19
|
+
k as perfMonitor,
|
|
20
|
+
l as preloadCodeBlockRuntime,
|
|
21
|
+
m as preloadExtendedLanguageIcons,
|
|
22
|
+
M as recommendNForSamples,
|
|
23
|
+
h as recommendWorkerThreshold,
|
|
24
|
+
d as registerIconTheme,
|
|
25
|
+
f as resolveLanguageId,
|
|
26
|
+
B as safeCancelRaf,
|
|
27
|
+
N as safeRaf,
|
|
28
|
+
c as setIconTheme,
|
|
29
|
+
u as setLanguageIconResolver,
|
|
30
|
+
R as useMarkstreamNodeLifecycle
|
|
31
|
+
};
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
function s({ R: e, H: t = 0, B: n = 50 }) {
|
|
2
|
+
const r = e * (1 - t) || 1e-6;
|
|
3
|
+
return Math.max(1, Math.floor(n / r));
|
|
4
|
+
}
|
|
5
|
+
function m(e) {
|
|
6
|
+
const t = e.length, n = (e.match(/\\/g) || []).length, r = t + n * 10;
|
|
7
|
+
return r < 10 ? "simple" : r < 40 ? "medium" : "complex";
|
|
8
|
+
}
|
|
9
|
+
function u(e) {
|
|
10
|
+
switch (e) {
|
|
11
|
+
case "simple":
|
|
12
|
+
return 3;
|
|
13
|
+
case "medium":
|
|
14
|
+
return 10;
|
|
15
|
+
case "complex":
|
|
16
|
+
return 30;
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
function l(e, t) {
|
|
20
|
+
let n = 0;
|
|
21
|
+
for (const r of e) {
|
|
22
|
+
const o = m(r), c = u(o);
|
|
23
|
+
c > n && (n = c);
|
|
24
|
+
}
|
|
25
|
+
return s({ R: n, H: t?.H ?? 0, B: t?.B ?? 50 });
|
|
26
|
+
}
|
|
27
|
+
export {
|
|
28
|
+
u as defaultRByClass,
|
|
29
|
+
m as estimateRByFormula,
|
|
30
|
+
l as recommendNForSamples,
|
|
31
|
+
s as recommendWorkerThreshold
|
|
32
|
+
};
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
class v {
|
|
2
|
+
metrics = [];
|
|
3
|
+
enabled = !1;
|
|
4
|
+
maxMetrics = 1e3;
|
|
5
|
+
// Prevent memory leak
|
|
6
|
+
enable() {
|
|
7
|
+
this.enabled = !0;
|
|
8
|
+
}
|
|
9
|
+
disable() {
|
|
10
|
+
this.enabled = !1;
|
|
11
|
+
}
|
|
12
|
+
recordRender(e) {
|
|
13
|
+
this.enabled && (this.metrics.push(e), this.metrics.length > this.maxMetrics && this.metrics.shift());
|
|
14
|
+
}
|
|
15
|
+
getStats() {
|
|
16
|
+
if (this.metrics.length === 0)
|
|
17
|
+
return {
|
|
18
|
+
totalRenders: 0,
|
|
19
|
+
cacheHitRate: 0,
|
|
20
|
+
averageWorkerTime: 0,
|
|
21
|
+
averageDirectTime: 0,
|
|
22
|
+
averageCacheHitTime: 0,
|
|
23
|
+
workerSavings: 0,
|
|
24
|
+
recommendation: "Insufficient data"
|
|
25
|
+
};
|
|
26
|
+
const e = this.metrics.filter((t) => t.type === "worker" && t.success), o = this.metrics.filter((t) => t.type === "direct" && t.success), n = this.metrics.filter((t) => t.type === "cache-hit"), c = this.metrics.length, d = n.length, l = d / c * 100, g = e.length > 0 ? e.reduce((t, r) => t + r.duration, 0) / e.length : 0, s = o.length > 0 ? o.reduce((t, r) => t + r.duration, 0) / o.length : 0, h = n.length > 0 ? n.reduce((t, r) => t + r.duration, 0) / n.length : 0, m = c * s, f = e.reduce((t, r) => t + r.duration, 0) + o.reduce((t, r) => t + r.duration, 0) + n.reduce((t, r) => t + r.duration, 0), u = m - f;
|
|
27
|
+
let i = "";
|
|
28
|
+
return l > 70 && g < s * 2 ? i = "✅ Worker + Cache is highly beneficial" : l > 50 ? i = "✅ Worker + Cache is beneficial" : g > s * 3 ? i = "⚠️ Worker overhead too high, consider direct rendering" : s < 5 ? i = "⚠️ Formulas too simple, Worker overhead may not be worth it" : i = "✅ Worker prevents main thread blocking", {
|
|
29
|
+
totalRenders: c,
|
|
30
|
+
cacheHits: d,
|
|
31
|
+
cacheHitRate: l.toFixed(1),
|
|
32
|
+
workerCalls: e.length,
|
|
33
|
+
directCalls: o.length,
|
|
34
|
+
averageWorkerTime: g.toFixed(2),
|
|
35
|
+
averageDirectTime: s.toFixed(2),
|
|
36
|
+
averageCacheHitTime: h.toFixed(3),
|
|
37
|
+
workerSavings: u.toFixed(2),
|
|
38
|
+
recommendation: i
|
|
39
|
+
};
|
|
40
|
+
}
|
|
41
|
+
printReport() {
|
|
42
|
+
const e = this.getStats();
|
|
43
|
+
return console.group("📊 KaTeX Rendering Performance Report"), console.log(`Total renders: ${e.totalRenders}`), console.log(`Cache hits: ${e.cacheHits} (${e.cacheHitRate}%)`), console.log(`Worker calls: ${e.workerCalls}`), console.log(`Direct calls: ${e.directCalls}`), console.log(""), console.log("Timing:"), console.log(` Worker average: ${e.averageWorkerTime}ms`), console.log(` Direct average: ${e.averageDirectTime}ms`), console.log(` Cache hit average: ${e.averageCacheHitTime}ms`), console.log(""), console.log(`Time saved: ${e.workerSavings}ms`), console.log(`Recommendation: ${e.recommendation}`), console.groupEnd(), e;
|
|
44
|
+
}
|
|
45
|
+
reset() {
|
|
46
|
+
this.metrics = [];
|
|
47
|
+
}
|
|
48
|
+
// Export metrics for analysis
|
|
49
|
+
exportMetrics() {
|
|
50
|
+
return {
|
|
51
|
+
metrics: [...this.metrics],
|
|
52
|
+
stats: this.getStats(),
|
|
53
|
+
timestamp: Date.now()
|
|
54
|
+
};
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
const a = new v();
|
|
58
|
+
function T() {
|
|
59
|
+
a.enable(), console.log("📊 KaTeX performance monitoring enabled");
|
|
60
|
+
}
|
|
61
|
+
function w() {
|
|
62
|
+
a.disable(), console.log("📊 KaTeX performance monitoring disabled");
|
|
63
|
+
}
|
|
64
|
+
function k() {
|
|
65
|
+
return a.printReport();
|
|
66
|
+
}
|
|
67
|
+
typeof window < "u" && (window.__katexPerfReport = k, window.__katexPerfMonitor = a);
|
|
68
|
+
export {
|
|
69
|
+
w as disablePerfMonitoring,
|
|
70
|
+
T as enablePerfMonitoring,
|
|
71
|
+
k as getPerfReport,
|
|
72
|
+
a as perfMonitor
|
|
73
|
+
};
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
function n(e) {
|
|
2
|
+
try {
|
|
3
|
+
if (typeof globalThis < "u" && typeof globalThis.requestAnimationFrame == "function")
|
|
4
|
+
return globalThis.requestAnimationFrame(e);
|
|
5
|
+
} catch {
|
|
6
|
+
}
|
|
7
|
+
return globalThis.setTimeout(e, 0);
|
|
8
|
+
}
|
|
9
|
+
function t(e) {
|
|
10
|
+
try {
|
|
11
|
+
if (e == null)
|
|
12
|
+
return;
|
|
13
|
+
if (typeof globalThis < "u" && typeof globalThis.cancelAnimationFrame == "function") {
|
|
14
|
+
globalThis.cancelAnimationFrame(e);
|
|
15
|
+
return;
|
|
16
|
+
}
|
|
17
|
+
} catch {
|
|
18
|
+
}
|
|
19
|
+
try {
|
|
20
|
+
globalThis.clearTimeout(e);
|
|
21
|
+
} catch {
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
export {
|
|
25
|
+
t as safeCancelRaf,
|
|
26
|
+
n as safeRaf
|
|
27
|
+
};
|
|
@@ -0,0 +1,177 @@
|
|
|
1
|
+
function s(e) {
|
|
2
|
+
return JSON.stringify(e);
|
|
3
|
+
}
|
|
4
|
+
function i(e) {
|
|
5
|
+
const t = e.mode ?? "classic", n = {
|
|
6
|
+
throwOnError: !0,
|
|
7
|
+
displayMode: !0,
|
|
8
|
+
output: "html",
|
|
9
|
+
strict: "ignore",
|
|
10
|
+
...e.renderOptions || {}
|
|
11
|
+
}, r = s(n), o = s(e.katexUrl), a = e.mhchemUrl ? s(e.mhchemUrl) : '""';
|
|
12
|
+
return t === "module" ? `
|
|
13
|
+
let DEBUG = false
|
|
14
|
+
let katex = null
|
|
15
|
+
let katexLoadError = null
|
|
16
|
+
let loadPromise = null
|
|
17
|
+
|
|
18
|
+
function normalizeKaTeX(mod) {
|
|
19
|
+
const resolved = mod && mod.default ? mod.default : mod
|
|
20
|
+
if (resolved && typeof resolved.renderToString === 'function')
|
|
21
|
+
return resolved
|
|
22
|
+
return null
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
async function loadKaTeX() {
|
|
26
|
+
if (katex || katexLoadError)
|
|
27
|
+
return
|
|
28
|
+
if (!loadPromise) {
|
|
29
|
+
loadPromise = (async () => {
|
|
30
|
+
try {
|
|
31
|
+
const mod = await import(${o})
|
|
32
|
+
katex = normalizeKaTeX(mod) || null
|
|
33
|
+
const mhchemUrl = ${a}
|
|
34
|
+
if (mhchemUrl) {
|
|
35
|
+
try {
|
|
36
|
+
await import(mhchemUrl)
|
|
37
|
+
}
|
|
38
|
+
catch (e) {
|
|
39
|
+
if (DEBUG)
|
|
40
|
+
console.warn('[markstream-solid:katex-cdn-worker] failed to load mhchem', e)
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
catch (e) {
|
|
45
|
+
katexLoadError = e
|
|
46
|
+
}
|
|
47
|
+
})()
|
|
48
|
+
}
|
|
49
|
+
await loadPromise
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
globalThis.addEventListener('message', async (ev) => {
|
|
53
|
+
const data = ev.data || {}
|
|
54
|
+
if (data.type === 'init') {
|
|
55
|
+
DEBUG = !!data.debug
|
|
56
|
+
return
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
const id = data.id ?? ''
|
|
60
|
+
const content = data.content ?? ''
|
|
61
|
+
const displayMode = data.displayMode ?? true
|
|
62
|
+
|
|
63
|
+
await loadKaTeX()
|
|
64
|
+
|
|
65
|
+
if (!katex) {
|
|
66
|
+
const reason = katexLoadError ? String(katexLoadError?.message || katexLoadError) : 'KaTeX is not available in worker'
|
|
67
|
+
globalThis.postMessage({ id, error: reason, content, displayMode })
|
|
68
|
+
return
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
try {
|
|
72
|
+
const opts = ${r}
|
|
73
|
+
const html = katex.renderToString(content, { ...opts, displayMode: !!displayMode })
|
|
74
|
+
globalThis.postMessage({ id, html, content, displayMode })
|
|
75
|
+
}
|
|
76
|
+
catch (err) {
|
|
77
|
+
globalThis.postMessage({ id, error: String(err?.message || err), content, displayMode })
|
|
78
|
+
}
|
|
79
|
+
})
|
|
80
|
+
`.trimStart() : `
|
|
81
|
+
let DEBUG = false
|
|
82
|
+
let katex = null
|
|
83
|
+
let katexLoadError = null
|
|
84
|
+
|
|
85
|
+
function normalizeKaTeX(val) {
|
|
86
|
+
const resolved = val && val.default ? val.default : val
|
|
87
|
+
if (resolved && typeof resolved.renderToString === 'function')
|
|
88
|
+
return resolved
|
|
89
|
+
return null
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
function loadKaTeXClassic() {
|
|
93
|
+
if (katex || katexLoadError)
|
|
94
|
+
return
|
|
95
|
+
try {
|
|
96
|
+
importScripts(${o})
|
|
97
|
+
const mhchemUrl = ${a}
|
|
98
|
+
if (mhchemUrl) {
|
|
99
|
+
try {
|
|
100
|
+
importScripts(mhchemUrl)
|
|
101
|
+
}
|
|
102
|
+
catch (e) {
|
|
103
|
+
if (DEBUG)
|
|
104
|
+
console.warn('[markstream-solid:katex-cdn-worker] failed to load mhchem', e)
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
katex = normalizeKaTeX(globalThis.katex)
|
|
108
|
+
}
|
|
109
|
+
catch (e) {
|
|
110
|
+
katexLoadError = e
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
loadKaTeXClassic()
|
|
115
|
+
|
|
116
|
+
globalThis.addEventListener('message', (ev) => {
|
|
117
|
+
const data = ev.data || {}
|
|
118
|
+
if (data.type === 'init') {
|
|
119
|
+
DEBUG = !!data.debug
|
|
120
|
+
return
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
const id = data.id ?? ''
|
|
124
|
+
const content = data.content ?? ''
|
|
125
|
+
const displayMode = data.displayMode ?? true
|
|
126
|
+
|
|
127
|
+
if (!katex && !katexLoadError)
|
|
128
|
+
loadKaTeXClassic()
|
|
129
|
+
|
|
130
|
+
if (!katex) {
|
|
131
|
+
const reason = katexLoadError ? String(katexLoadError?.message || katexLoadError) : 'KaTeX is not available in worker'
|
|
132
|
+
globalThis.postMessage({ id, error: reason, content, displayMode })
|
|
133
|
+
return
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
try {
|
|
137
|
+
const opts = ${r}
|
|
138
|
+
const html = katex.renderToString(content, { ...opts, displayMode: !!displayMode })
|
|
139
|
+
globalThis.postMessage({ id, html, content, displayMode })
|
|
140
|
+
}
|
|
141
|
+
catch (err) {
|
|
142
|
+
globalThis.postMessage({ id, error: String(err?.message || err), content, displayMode })
|
|
143
|
+
}
|
|
144
|
+
})
|
|
145
|
+
`.trimStart();
|
|
146
|
+
}
|
|
147
|
+
function m(e) {
|
|
148
|
+
const t = i(e);
|
|
149
|
+
if (typeof Worker > "u" || typeof URL > "u" || typeof Blob > "u")
|
|
150
|
+
return {
|
|
151
|
+
worker: null,
|
|
152
|
+
dispose: () => {
|
|
153
|
+
},
|
|
154
|
+
source: t
|
|
155
|
+
};
|
|
156
|
+
const n = new Blob([t], { type: "text/javascript" }), r = URL.createObjectURL(n);
|
|
157
|
+
let o = !1;
|
|
158
|
+
const a = () => {
|
|
159
|
+
if (!o) {
|
|
160
|
+
o = !0;
|
|
161
|
+
try {
|
|
162
|
+
URL.revokeObjectURL(r);
|
|
163
|
+
} catch {
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
}, l = (e.mode ?? "classic") === "module" ? { ...e.workerOptions ?? {}, type: "module" } : e.workerOptions, d = new Worker(r, l);
|
|
167
|
+
if (e.debug)
|
|
168
|
+
try {
|
|
169
|
+
d.postMessage({ type: "init", debug: !0 });
|
|
170
|
+
} catch {
|
|
171
|
+
}
|
|
172
|
+
return { worker: d, dispose: a, source: t };
|
|
173
|
+
}
|
|
174
|
+
export {
|
|
175
|
+
i as buildKaTeXCDNWorkerSource,
|
|
176
|
+
m as createKaTeXWorkerFromCDN
|
|
177
|
+
};
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import d from "katex";
|
|
2
|
+
import "katex/dist/contrib/mhchem";
|
|
3
|
+
let i = !1;
|
|
4
|
+
globalThis.addEventListener("message", (r) => {
|
|
5
|
+
const e = r.data || {};
|
|
6
|
+
if (e.type === "init") {
|
|
7
|
+
i = !!e.debug;
|
|
8
|
+
return;
|
|
9
|
+
}
|
|
10
|
+
const a = e.id ?? "", t = e.content ?? "", o = e.displayMode ?? !0;
|
|
11
|
+
try {
|
|
12
|
+
i && console.debug("[markstream-solid:katexRenderer.worker] render start", { id: a, displayMode: o, content: t });
|
|
13
|
+
const s = d.renderToString(t, {
|
|
14
|
+
throwOnError: !0,
|
|
15
|
+
displayMode: o,
|
|
16
|
+
output: "html",
|
|
17
|
+
strict: "ignore"
|
|
18
|
+
}), n = {
|
|
19
|
+
id: a,
|
|
20
|
+
html: s,
|
|
21
|
+
content: t,
|
|
22
|
+
displayMode: o
|
|
23
|
+
};
|
|
24
|
+
globalThis.postMessage(n);
|
|
25
|
+
} catch (s) {
|
|
26
|
+
const n = {
|
|
27
|
+
id: a,
|
|
28
|
+
error: String(s?.message ?? s),
|
|
29
|
+
content: t,
|
|
30
|
+
displayMode: o
|
|
31
|
+
};
|
|
32
|
+
globalThis.postMessage(n);
|
|
33
|
+
}
|
|
34
|
+
});
|
|
35
|
+
globalThis.addEventListener("error", (r) => {
|
|
36
|
+
try {
|
|
37
|
+
globalThis.postMessage({
|
|
38
|
+
id: "__worker_uncaught__",
|
|
39
|
+
error: String(r.message ?? r.error),
|
|
40
|
+
content: "",
|
|
41
|
+
displayMode: !0
|
|
42
|
+
});
|
|
43
|
+
} catch {
|
|
44
|
+
}
|
|
45
|
+
});
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { W as r, c as s, g as o, a as t, i as K, r as k, h as T, s as X, j as W, k as c, l as u, m as l, w as n } from "../katexWorkerClient-ZLzkPVv_.js";
|
|
2
|
+
export {
|
|
3
|
+
r as WORKER_BUSY_CODE,
|
|
4
|
+
s as clearKaTeXWorker,
|
|
5
|
+
o as getKaTeXBackpressureDefaults,
|
|
6
|
+
t as getKaTeXWorkerLoad,
|
|
7
|
+
K as isKaTeXWorkerBusy,
|
|
8
|
+
k as renderKaTeXInWorker,
|
|
9
|
+
T as renderKaTeXWithBackpressure,
|
|
10
|
+
X as setKaTeXBackpressureDefaults,
|
|
11
|
+
W as setKaTeXCache,
|
|
12
|
+
c as setKaTeXWorker,
|
|
13
|
+
u as setKaTeXWorkerDebug,
|
|
14
|
+
l as setKaTeXWorkerMaxConcurrency,
|
|
15
|
+
n as waitForKaTeXWorkerSlot
|
|
16
|
+
};
|