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.
Files changed (102) hide show
  1. package/README.md +120 -2
  2. package/dist/client/extended-BTbixd9o.js +38 -0
  3. package/dist/client/index.js +5640 -0
  4. package/dist/client/katexWorkerClient-ZLzkPVv_.js +260 -0
  5. package/dist/client/languageIcon-CDTPjsAQ.js +280 -0
  6. package/dist/client/mermaidWorkerClient-BAvGYsCO.js +243 -0
  7. package/dist/client/utils/index.js +31 -0
  8. package/dist/client/utils/katex-threshold.js +32 -0
  9. package/dist/client/utils/performance-monitor.js +73 -0
  10. package/dist/client/utils/safeRaf.js +27 -0
  11. package/dist/client/workers/katexCdnWorker.js +177 -0
  12. package/dist/client/workers/katexRenderer.worker.js +45 -0
  13. package/dist/client/workers/katexWorkerClient.js +16 -0
  14. package/dist/client/workers/mermaidCdnWorker.js +226 -0
  15. package/dist/client/workers/mermaidParser.worker.js +73 -0
  16. package/dist/client/workers/mermaidWorkerClient.js +13 -0
  17. package/dist/components/BuiltinNodes.d.ts +42 -0
  18. package/dist/components/CodeBlockNode.d.ts +10 -0
  19. package/dist/components/DiagramBlockNode.d.ts +27 -0
  20. package/dist/components/HtmlPreviewFrame.d.ts +10 -0
  21. package/dist/components/MarkstreamProvider.d.ts +5 -0
  22. package/dist/components/MarkstreamVirtualTimeline.d.ts +35 -0
  23. package/dist/components/MathNode.d.ts +6 -0
  24. package/dist/components/NodeRenderer.d.ts +27 -0
  25. package/dist/components/NodeSlot.d.ts +11 -0
  26. package/dist/components/PreCodeBlock.d.ts +3 -0
  27. package/dist/components/PreCodeNode.d.ts +9 -0
  28. package/dist/components/RenderNode.d.ts +11 -0
  29. package/dist/components/StreamingTextNode.d.ts +2 -0
  30. package/dist/components/ToolbarButton.d.ts +14 -0
  31. package/dist/components/ToolbarIcon.d.ts +18 -0
  32. package/dist/components/Tooltip.d.ts +13 -0
  33. package/dist/components/lifecycle.d.ts +6 -0
  34. package/dist/components/mathHeightCache.d.ts +5 -0
  35. package/dist/components/rendererModeDefaults.d.ts +4 -0
  36. package/dist/components/shared/diagram-height.d.ts +16 -0
  37. package/dist/components/shared/node-helpers.d.ts +78 -0
  38. package/dist/components/shared/node-outlet-helpers.d.ts +10 -0
  39. package/dist/components/shared/render-window.d.ts +18 -0
  40. package/dist/components/shared/reuseParsedNodes.d.ts +3 -0
  41. package/dist/components/viewport.d.ts +5 -0
  42. package/dist/components/virtualLayoutKey.d.ts +13 -0
  43. package/dist/configuration.d.ts +9 -0
  44. package/dist/customComponents.d.ts +36 -0
  45. package/dist/enhanceRenderedHtml.d.ts +25 -0
  46. package/dist/hydrateCustomTagContent.d.ts +2 -0
  47. package/dist/i18n/useSafeI18n.d.ts +4 -0
  48. package/dist/icon-themes/index.d.ts +2 -0
  49. package/dist/icon-themes/material/core.d.ts +2 -0
  50. package/dist/icon-themes/material/extended.d.ts +2 -0
  51. package/dist/icon-themes/material/index.d.ts +2 -0
  52. package/dist/icon-themes/registry.d.ts +9 -0
  53. package/dist/icon-themes/types.d.ts +11 -0
  54. package/dist/index.css +3279 -0
  55. package/dist/index.d.ts +48 -0
  56. package/dist/index.px.css +3279 -0
  57. package/dist/index.tailwind.css +3279 -0
  58. package/dist/optional/d2.d.ts +17 -0
  59. package/dist/optional/infographic.d.ts +31 -0
  60. package/dist/optional/katex.d.ts +9 -0
  61. package/dist/optional/mermaid.d.ts +27 -0
  62. package/dist/optional/streamDiffs.d.ts +29 -0
  63. package/dist/renderMarkdownHtml.d.ts +30 -0
  64. package/dist/sanitizeHtmlContent.d.ts +2 -0
  65. package/dist/server/extended-CKyCqQt3.js +69 -0
  66. package/dist/server/index.js +6264 -0
  67. package/dist/server/languageIcon-TXkIEBPf.js +353 -0
  68. package/dist/server/utils/index.js +31 -0
  69. package/dist/server/utils/katex-threshold.js +41 -0
  70. package/dist/server/utils/performance-monitor.js +120 -0
  71. package/dist/server/utils/safeRaf.js +28 -0
  72. package/dist/server/workers/katexCdnWorker.js +190 -0
  73. package/dist/server/workers/katexWorkerClient.js +373 -0
  74. package/dist/server/workers/mermaidCdnWorker.js +238 -0
  75. package/dist/server/workers/mermaidWorkerClient.js +333 -0
  76. package/dist/streamDiffsWorker.d.ts +72 -0
  77. package/dist/tailwind.d.ts +2 -0
  78. package/dist/tailwind.js +3 -0
  79. package/dist/tooltip/singletonTooltip.d.ts +7 -0
  80. package/dist/types/component-props.d.ts +253 -0
  81. package/dist/types/node-renderer-props.d.ts +333 -0
  82. package/dist/useSmoothMarkdownStream.d.ts +22 -0
  83. package/dist/utils/clipboard.d.ts +1 -0
  84. package/dist/utils/d2RenderSalt.d.ts +1 -0
  85. package/dist/utils/footnoteTarget.d.ts +1 -0
  86. package/dist/utils/index.d.ts +8 -0
  87. package/dist/utils/katex-threshold.d.ts +20 -0
  88. package/dist/utils/languageIcon.d.ts +8 -0
  89. package/dist/utils/mermaidRenderId.d.ts +1 -0
  90. package/dist/utils/normalizeKaTeXRenderInput.d.ts +1 -0
  91. package/dist/utils/performance-monitor.d.ts +121 -0
  92. package/dist/utils/resolveLanguageIcon.d.ts +2 -0
  93. package/dist/utils/safeRaf.d.ts +2 -0
  94. package/dist/utils/virtualItemMeasurement.d.ts +5 -0
  95. package/dist/virtual-adapter.d.ts +165 -0
  96. package/dist/workers/katexCdnWorker.d.ts +20 -0
  97. package/dist/workers/katexRenderer.worker.d.ts +1 -0
  98. package/dist/workers/katexWorkerClient.d.ts +35 -0
  99. package/dist/workers/mermaidCdnWorker.d.ts +15 -0
  100. package/dist/workers/mermaidParser.worker.d.ts +1 -0
  101. package/dist/workers/mermaidWorkerClient.d.ts +15 -0
  102. package/package.json +149 -3
@@ -0,0 +1,190 @@
1
+ function stringifyForWorker(value) {
2
+ return JSON.stringify(value);
3
+ }
4
+ function buildKaTeXCDNWorkerSource(options) {
5
+ const mode = options.mode ?? "classic";
6
+ const renderOptions = {
7
+ throwOnError: true,
8
+ displayMode: true,
9
+ output: "html",
10
+ strict: "ignore",
11
+ ...options.renderOptions || {}
12
+ };
13
+ const renderOptionsLiteral = stringifyForWorker(renderOptions);
14
+ const katexUrlLiteral = stringifyForWorker(options.katexUrl);
15
+ const mhchemUrlLiteral = options.mhchemUrl ? stringifyForWorker(options.mhchemUrl) : '""';
16
+ if (mode === "module") {
17
+ return `
18
+ let DEBUG = false
19
+ let katex = null
20
+ let katexLoadError = null
21
+ let loadPromise = null
22
+
23
+ function normalizeKaTeX(mod) {
24
+ const resolved = mod && mod.default ? mod.default : mod
25
+ if (resolved && typeof resolved.renderToString === 'function')
26
+ return resolved
27
+ return null
28
+ }
29
+
30
+ async function loadKaTeX() {
31
+ if (katex || katexLoadError)
32
+ return
33
+ if (!loadPromise) {
34
+ loadPromise = (async () => {
35
+ try {
36
+ const mod = await import(${katexUrlLiteral})
37
+ katex = normalizeKaTeX(mod) || null
38
+ const mhchemUrl = ${mhchemUrlLiteral}
39
+ if (mhchemUrl) {
40
+ try {
41
+ await import(mhchemUrl)
42
+ }
43
+ catch (e) {
44
+ if (DEBUG)
45
+ console.warn('[markstream-solid:katex-cdn-worker] failed to load mhchem', e)
46
+ }
47
+ }
48
+ }
49
+ catch (e) {
50
+ katexLoadError = e
51
+ }
52
+ })()
53
+ }
54
+ await loadPromise
55
+ }
56
+
57
+ globalThis.addEventListener('message', async (ev) => {
58
+ const data = ev.data || {}
59
+ if (data.type === 'init') {
60
+ DEBUG = !!data.debug
61
+ return
62
+ }
63
+
64
+ const id = data.id ?? ''
65
+ const content = data.content ?? ''
66
+ const displayMode = data.displayMode ?? true
67
+
68
+ await loadKaTeX()
69
+
70
+ if (!katex) {
71
+ const reason = katexLoadError ? String(katexLoadError?.message || katexLoadError) : 'KaTeX is not available in worker'
72
+ globalThis.postMessage({ id, error: reason, content, displayMode })
73
+ return
74
+ }
75
+
76
+ try {
77
+ const opts = ${renderOptionsLiteral}
78
+ const html = katex.renderToString(content, { ...opts, displayMode: !!displayMode })
79
+ globalThis.postMessage({ id, html, content, displayMode })
80
+ }
81
+ catch (err) {
82
+ globalThis.postMessage({ id, error: String(err?.message || err), content, displayMode })
83
+ }
84
+ })
85
+ `.trimStart();
86
+ }
87
+ return `
88
+ let DEBUG = false
89
+ let katex = null
90
+ let katexLoadError = null
91
+
92
+ function normalizeKaTeX(val) {
93
+ const resolved = val && val.default ? val.default : val
94
+ if (resolved && typeof resolved.renderToString === 'function')
95
+ return resolved
96
+ return null
97
+ }
98
+
99
+ function loadKaTeXClassic() {
100
+ if (katex || katexLoadError)
101
+ return
102
+ try {
103
+ importScripts(${katexUrlLiteral})
104
+ const mhchemUrl = ${mhchemUrlLiteral}
105
+ if (mhchemUrl) {
106
+ try {
107
+ importScripts(mhchemUrl)
108
+ }
109
+ catch (e) {
110
+ if (DEBUG)
111
+ console.warn('[markstream-solid:katex-cdn-worker] failed to load mhchem', e)
112
+ }
113
+ }
114
+ katex = normalizeKaTeX(globalThis.katex)
115
+ }
116
+ catch (e) {
117
+ katexLoadError = e
118
+ }
119
+ }
120
+
121
+ loadKaTeXClassic()
122
+
123
+ globalThis.addEventListener('message', (ev) => {
124
+ const data = ev.data || {}
125
+ if (data.type === 'init') {
126
+ DEBUG = !!data.debug
127
+ return
128
+ }
129
+
130
+ const id = data.id ?? ''
131
+ const content = data.content ?? ''
132
+ const displayMode = data.displayMode ?? true
133
+
134
+ if (!katex && !katexLoadError)
135
+ loadKaTeXClassic()
136
+
137
+ if (!katex) {
138
+ const reason = katexLoadError ? String(katexLoadError?.message || katexLoadError) : 'KaTeX is not available in worker'
139
+ globalThis.postMessage({ id, error: reason, content, displayMode })
140
+ return
141
+ }
142
+
143
+ try {
144
+ const opts = ${renderOptionsLiteral}
145
+ const html = katex.renderToString(content, { ...opts, displayMode: !!displayMode })
146
+ globalThis.postMessage({ id, html, content, displayMode })
147
+ }
148
+ catch (err) {
149
+ globalThis.postMessage({ id, error: String(err?.message || err), content, displayMode })
150
+ }
151
+ })
152
+ `.trimStart();
153
+ }
154
+ function createKaTeXWorkerFromCDN(options) {
155
+ const source = buildKaTeXCDNWorkerSource(options);
156
+ if (typeof Worker === "undefined" || typeof URL === "undefined" || typeof Blob === "undefined") {
157
+ return {
158
+ worker: null,
159
+ dispose: () => {
160
+ },
161
+ source
162
+ };
163
+ }
164
+ const blob = new Blob([source], { type: "text/javascript" });
165
+ const url = URL.createObjectURL(blob);
166
+ let revoked = false;
167
+ const dispose = () => {
168
+ if (revoked)
169
+ return;
170
+ revoked = true;
171
+ try {
172
+ URL.revokeObjectURL(url);
173
+ } catch {
174
+ }
175
+ };
176
+ const mode = options.mode ?? "classic";
177
+ const workerOptions = mode === "module" ? { ...options.workerOptions ?? {}, type: "module" } : options.workerOptions;
178
+ const worker = new Worker(url, workerOptions);
179
+ if (options.debug) {
180
+ try {
181
+ worker.postMessage({ type: "init", debug: true });
182
+ } catch {
183
+ }
184
+ }
185
+ return { worker, dispose, source };
186
+ }
187
+ export {
188
+ buildKaTeXCDNWorkerSource,
189
+ createKaTeXWorkerFromCDN
190
+ };
@@ -0,0 +1,373 @@
1
+ let katex = null;
2
+ let importAttempted = false;
3
+ let pendingImport = null;
4
+ let katexLoader = defaultKatexLoader;
5
+ function normalizeKatexModule(mod) {
6
+ const resolved = mod?.default ?? mod;
7
+ if (resolved && typeof resolved.renderToString === "function")
8
+ return resolved;
9
+ return null;
10
+ }
11
+ function getGlobalKatex() {
12
+ try {
13
+ const globalStore = globalThis;
14
+ return normalizeKatexModule(globalStore?.katex);
15
+ } catch {
16
+ return null;
17
+ }
18
+ }
19
+ function defaultKatexLoader() {
20
+ return (async () => {
21
+ const globalKatex = getGlobalKatex();
22
+ if (globalKatex)
23
+ return globalKatex;
24
+ const mod = await import("katex");
25
+ try {
26
+ await import("katex/contrib/mhchem");
27
+ } catch {
28
+ }
29
+ return normalizeKatexModule(mod);
30
+ })();
31
+ }
32
+ function resetCache() {
33
+ katex = null;
34
+ importAttempted = false;
35
+ pendingImport = null;
36
+ }
37
+ function setKatexLoader(loader) {
38
+ katexLoader = loader;
39
+ resetCache();
40
+ }
41
+ function enableKatex(loader) {
42
+ setKatexLoader(loader ?? defaultKatexLoader);
43
+ }
44
+ function disableKatex() {
45
+ setKatexLoader(null);
46
+ }
47
+ function isKatexEnabled() {
48
+ return typeof katexLoader === "function";
49
+ }
50
+ async function getKatex() {
51
+ const globalKatex = getGlobalKatex();
52
+ if (globalKatex) {
53
+ katex = globalKatex;
54
+ return katex;
55
+ }
56
+ if (katex)
57
+ return katex;
58
+ if (pendingImport)
59
+ return await pendingImport;
60
+ if (importAttempted)
61
+ return null;
62
+ const loader = katexLoader;
63
+ if (!loader) {
64
+ importAttempted = true;
65
+ return null;
66
+ }
67
+ pendingImport = (async () => {
68
+ try {
69
+ const result = await loader();
70
+ const normalized = normalizeKatexModule(result) ?? result;
71
+ if (normalized) {
72
+ katex = normalized;
73
+ return katex;
74
+ }
75
+ } catch {
76
+ }
77
+ importAttempted = true;
78
+ return null;
79
+ })();
80
+ try {
81
+ return await pendingImport;
82
+ } finally {
83
+ pendingImport = null;
84
+ }
85
+ }
86
+ function normalizeKaTeXRenderInput(content) {
87
+ if (!content)
88
+ return "";
89
+ return content.replace(/·/g, "⋅").replace(/℃/g, "°C");
90
+ }
91
+ const WORKER_BUSY_CODE = "WORKER_BUSY";
92
+ let worker = null;
93
+ let workerInitError = null;
94
+ let debugKatexWorker = false;
95
+ const pending = /* @__PURE__ */ new Map();
96
+ const cache = /* @__PURE__ */ new Map();
97
+ const cacheMax = 200;
98
+ const drainWaiters = /* @__PURE__ */ new Set();
99
+ let maxConcurrency = 5;
100
+ function notifyDrainIfBelowCap() {
101
+ if (pending.size >= maxConcurrency || drainWaiters.size === 0)
102
+ return;
103
+ const currentWaiters = Array.from(drainWaiters);
104
+ drainWaiters.clear();
105
+ for (const waiter of currentWaiters) {
106
+ try {
107
+ waiter();
108
+ } catch {
109
+ }
110
+ }
111
+ }
112
+ function rememberCache(content, displayMode, html) {
113
+ cache.set(`${displayMode ? "d" : "i"}:${content}`, html);
114
+ if (cache.size > cacheMax) {
115
+ const firstKey = cache.keys().next().value;
116
+ if (firstKey)
117
+ cache.delete(firstKey);
118
+ }
119
+ }
120
+ function setKaTeXWorker(nextWorker) {
121
+ worker = nextWorker;
122
+ workerInitError = null;
123
+ worker.onmessage = (event) => {
124
+ const { id, html, error, content, displayMode } = event.data || {};
125
+ const active = pending.get(id);
126
+ if (!active)
127
+ return;
128
+ pending.delete(id);
129
+ clearTimeout(active.timeoutId);
130
+ notifyDrainIfBelowCap();
131
+ if (error) {
132
+ active.reject(new Error(error));
133
+ return;
134
+ }
135
+ if (content)
136
+ rememberCache(String(content), Boolean(displayMode), String(html || ""));
137
+ active.resolve(String(html || ""));
138
+ };
139
+ worker.onerror = (event) => {
140
+ for (const [, active] of pending.entries()) {
141
+ clearTimeout(active.timeoutId);
142
+ active.reject(new Error(`Worker error: ${event.message}`));
143
+ }
144
+ pending.clear();
145
+ notifyDrainIfBelowCap();
146
+ };
147
+ if (debugKatexWorker)
148
+ worker.postMessage({ type: "init", debug: true });
149
+ }
150
+ function clearKaTeXWorker() {
151
+ if (worker)
152
+ worker.terminate?.();
153
+ worker = null;
154
+ workerInitError = null;
155
+ }
156
+ function ensureWorker() {
157
+ if (worker)
158
+ return worker;
159
+ workerInitError = new Error("[markstream-solid:katexWorkerClient] No worker instance set. Please inject a Worker via setKaTeXWorker().");
160
+ workerInitError.name = "WorkerInitError";
161
+ workerInitError.code = "WORKER_INIT_ERROR";
162
+ return null;
163
+ }
164
+ function setKaTeXWorkerDebug(enabled) {
165
+ debugKatexWorker = !!enabled;
166
+ if (worker)
167
+ worker.postMessage({ type: "init", debug: debugKatexWorker });
168
+ }
169
+ async function renderKaTeXInWorker(content, displayMode = true, timeout = 2e3, signal) {
170
+ const normalizedContent = normalizeKaTeXRenderInput(content);
171
+ if (!isKatexEnabled()) {
172
+ const error = new Error("KaTeX rendering disabled");
173
+ error.name = "KaTeXDisabled";
174
+ error.code = "KATEX_DISABLED";
175
+ return Promise.reject(error);
176
+ }
177
+ if (workerInitError)
178
+ return Promise.reject(workerInitError);
179
+ const cacheKey = `${displayMode ? "d" : "i"}:${normalizedContent}`;
180
+ const cached = cache.get(cacheKey);
181
+ if (cached)
182
+ return cached;
183
+ const activeWorker = ensureWorker();
184
+ if (!activeWorker)
185
+ return Promise.reject(workerInitError);
186
+ if (pending.size >= maxConcurrency) {
187
+ const error = new Error("Worker busy");
188
+ error.name = "WorkerBusy";
189
+ error.code = WORKER_BUSY_CODE;
190
+ error.busy = true;
191
+ error.inFlight = pending.size;
192
+ error.max = maxConcurrency;
193
+ return Promise.reject(error);
194
+ }
195
+ return new Promise((resolve, reject) => {
196
+ if (signal?.aborted) {
197
+ const error = new Error("Aborted");
198
+ error.name = "AbortError";
199
+ reject(error);
200
+ return;
201
+ }
202
+ const id = Math.random().toString(36).slice(2);
203
+ const timeoutId = globalThis.setTimeout(() => {
204
+ pending.delete(id);
205
+ notifyDrainIfBelowCap();
206
+ const error = new Error("Worker render timed out");
207
+ error.name = "WorkerTimeout";
208
+ error.code = "WORKER_TIMEOUT";
209
+ reject(error);
210
+ }, timeout);
211
+ const onAbort = () => {
212
+ globalThis.clearTimeout(timeoutId);
213
+ if (pending.delete(id))
214
+ notifyDrainIfBelowCap();
215
+ const error = new Error("Aborted");
216
+ error.name = "AbortError";
217
+ reject(error);
218
+ };
219
+ signal?.addEventListener("abort", onAbort, { once: true });
220
+ pending.set(id, {
221
+ timeoutId,
222
+ resolve: (html) => {
223
+ signal?.removeEventListener("abort", onAbort);
224
+ resolve(html);
225
+ },
226
+ reject: (error) => {
227
+ signal?.removeEventListener("abort", onAbort);
228
+ reject(error);
229
+ }
230
+ });
231
+ activeWorker.postMessage({
232
+ id,
233
+ type: "render",
234
+ content: normalizedContent,
235
+ displayMode
236
+ });
237
+ });
238
+ }
239
+ function setKaTeXCache(content, displayMode = true, html) {
240
+ rememberCache(normalizeKaTeXRenderInput(content), displayMode, html);
241
+ }
242
+ function getKaTeXWorkerLoad() {
243
+ return {
244
+ inFlight: pending.size,
245
+ max: maxConcurrency
246
+ };
247
+ }
248
+ function setKaTeXWorkerMaxConcurrency(value) {
249
+ if (Number.isFinite(value) && value > 0)
250
+ maxConcurrency = Math.floor(value);
251
+ }
252
+ function isKaTeXWorkerBusy() {
253
+ return pending.size >= maxConcurrency;
254
+ }
255
+ function waitForKaTeXWorkerSlot(timeout = 2e3, signal) {
256
+ if (pending.size < maxConcurrency)
257
+ return Promise.resolve();
258
+ return new Promise((resolve, reject) => {
259
+ let settled = false;
260
+ let timer = null;
261
+ const onDrain = () => {
262
+ if (settled)
263
+ return;
264
+ settled = true;
265
+ if (timer)
266
+ clearTimeout(timer);
267
+ drainWaiters.delete(onDrain);
268
+ resolve();
269
+ };
270
+ drainWaiters.add(onDrain);
271
+ timer = setTimeout(() => {
272
+ if (settled)
273
+ return;
274
+ settled = true;
275
+ drainWaiters.delete(onDrain);
276
+ const error = new Error("Wait for worker slot timed out");
277
+ error.name = "WorkerBusyTimeout";
278
+ error.code = "WORKER_BUSY_TIMEOUT";
279
+ reject(error);
280
+ }, timeout);
281
+ queueMicrotask(() => notifyDrainIfBelowCap());
282
+ if (signal) {
283
+ const onAbort = () => {
284
+ if (settled)
285
+ return;
286
+ settled = true;
287
+ if (timer)
288
+ clearTimeout(timer);
289
+ drainWaiters.delete(onDrain);
290
+ const error = new Error("Aborted");
291
+ error.name = "AbortError";
292
+ reject(error);
293
+ };
294
+ if (signal.aborted)
295
+ onAbort();
296
+ else
297
+ signal.addEventListener("abort", onAbort, { once: true });
298
+ }
299
+ });
300
+ }
301
+ const defaultBackpressure = {
302
+ timeout: 2e3,
303
+ waitTimeout: 1500,
304
+ backoffMs: 30,
305
+ maxRetries: 1
306
+ };
307
+ const maxBackpressureRetries = 8;
308
+ function setKaTeXBackpressureDefaults(options) {
309
+ if (options.timeout != null)
310
+ defaultBackpressure.timeout = Math.max(0, Math.floor(options.timeout));
311
+ if (options.waitTimeout != null)
312
+ defaultBackpressure.waitTimeout = Math.max(0, Math.floor(options.waitTimeout));
313
+ if (options.backoffMs != null)
314
+ defaultBackpressure.backoffMs = Math.max(0, Math.floor(options.backoffMs));
315
+ if (options.maxRetries != null)
316
+ defaultBackpressure.maxRetries = Math.max(0, Math.floor(options.maxRetries));
317
+ }
318
+ function getKaTeXBackpressureDefaults() {
319
+ return { ...defaultBackpressure };
320
+ }
321
+ async function renderKaTeXWithBackpressure(content, displayMode = true, options = {}) {
322
+ if (!isKatexEnabled()) {
323
+ const error = new Error("KaTeX rendering disabled");
324
+ error.name = "KaTeXDisabled";
325
+ error.code = "KATEX_DISABLED";
326
+ throw error;
327
+ }
328
+ const timeout = options.timeout ?? defaultBackpressure.timeout;
329
+ const waitTimeout = options.waitTimeout ?? defaultBackpressure.waitTimeout;
330
+ const backoffMs = options.backoffMs ?? defaultBackpressure.backoffMs;
331
+ const rawMaxRetries = options.maxRetries ?? defaultBackpressure.maxRetries;
332
+ const maxRetries = Number.isFinite(rawMaxRetries) ? Math.max(0, Math.min(Math.floor(rawMaxRetries), maxBackpressureRetries)) : defaultBackpressure.maxRetries;
333
+ let attempt = 0;
334
+ for (; ; ) {
335
+ if (options.signal?.aborted) {
336
+ const error = new Error("Aborted");
337
+ error.name = "AbortError";
338
+ throw error;
339
+ }
340
+ try {
341
+ return await renderKaTeXInWorker(content, displayMode, timeout, options.signal);
342
+ } catch (error) {
343
+ if (error?.code !== WORKER_BUSY_CODE || attempt >= maxRetries)
344
+ throw error;
345
+ attempt += 1;
346
+ await waitForKaTeXWorkerSlot(waitTimeout, options.signal).catch(() => {
347
+ });
348
+ if (backoffMs > 0)
349
+ await new Promise((resolve) => globalThis.setTimeout(resolve, backoffMs * attempt));
350
+ }
351
+ }
352
+ }
353
+ export {
354
+ WORKER_BUSY_CODE,
355
+ clearKaTeXWorker,
356
+ disableKatex as d,
357
+ enableKatex as e,
358
+ getKatex as g,
359
+ getKaTeXBackpressureDefaults,
360
+ getKaTeXWorkerLoad,
361
+ isKatexEnabled as i,
362
+ isKaTeXWorkerBusy,
363
+ normalizeKaTeXRenderInput as n,
364
+ renderKaTeXInWorker,
365
+ renderKaTeXWithBackpressure,
366
+ setKatexLoader as s,
367
+ setKaTeXBackpressureDefaults,
368
+ setKaTeXCache,
369
+ setKaTeXWorker,
370
+ setKaTeXWorkerDebug,
371
+ setKaTeXWorkerMaxConcurrency,
372
+ waitForKaTeXWorkerSlot
373
+ };