@uniweb/scholar 0.1.0

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.
@@ -0,0 +1,105 @@
1
+ /**
2
+ * KaTeX Lazy Loader
3
+ *
4
+ * Provides lazy loading of KaTeX with module-level caching.
5
+ * KaTeX is only loaded when math rendering is actually needed.
6
+ *
7
+ * @module @uniweb/scholar/math/katex-loader
8
+ */
9
+
10
+ // Module-level state for singleton pattern
11
+ let katexInstance = null
12
+ let katexLoadPromise = null
13
+ let cssInjected = false
14
+
15
+ /**
16
+ * CDN URL for KaTeX CSS (matches the katex version in package.json)
17
+ */
18
+ const KATEX_CSS_URL = 'https://cdn.jsdelivr.net/npm/katex@0.16.0/dist/katex.min.css'
19
+
20
+ /**
21
+ * Inject KaTeX CSS into the document head
22
+ * Only injects once per page load
23
+ */
24
+ function injectKatexCSS() {
25
+ if (cssInjected || typeof document === 'undefined') return
26
+
27
+ const styleId = 'uniweb-katex-css'
28
+
29
+ // Check if already injected
30
+ if (document.getElementById(styleId)) {
31
+ cssInjected = true
32
+ return
33
+ }
34
+
35
+ const link = document.createElement('link')
36
+ link.id = styleId
37
+ link.rel = 'stylesheet'
38
+ link.href = KATEX_CSS_URL
39
+ link.crossOrigin = 'anonymous'
40
+ document.head.appendChild(link)
41
+
42
+ cssInjected = true
43
+ }
44
+
45
+ /**
46
+ * Load KaTeX lazily
47
+ *
48
+ * Returns cached instance if already loaded, otherwise loads
49
+ * KaTeX dynamically and injects its CSS.
50
+ *
51
+ * @returns {Promise<Object>} The KaTeX module
52
+ */
53
+ export async function loadKatex() {
54
+ if (katexInstance) return katexInstance
55
+ if (katexLoadPromise) return katexLoadPromise
56
+
57
+ katexLoadPromise = (async () => {
58
+ try {
59
+ const katex = await import('katex')
60
+ katexInstance = katex.default || katex
61
+
62
+ // Inject CSS when KaTeX is loaded
63
+ injectKatexCSS()
64
+
65
+ return katexInstance
66
+ } catch (error) {
67
+ console.warn('[scholar/math] Failed to load KaTeX:', error)
68
+ katexLoadPromise = null
69
+ return null
70
+ }
71
+ })()
72
+
73
+ return katexLoadPromise
74
+ }
75
+
76
+ /**
77
+ * Check if KaTeX is already loaded
78
+ *
79
+ * @returns {boolean} True if KaTeX is loaded and ready
80
+ */
81
+ export function isKatexLoaded() {
82
+ return katexInstance !== null
83
+ }
84
+
85
+ /**
86
+ * Render LaTeX to HTML string
87
+ *
88
+ * @param {string} latex - LaTeX string to render
89
+ * @param {Object} options - KaTeX options
90
+ * @returns {Promise<string|null>} Rendered HTML or null on error
91
+ */
92
+ export async function renderLatex(latex, options = {}) {
93
+ const katex = await loadKatex()
94
+ if (!katex) return null
95
+
96
+ try {
97
+ return katex.renderToString(latex, {
98
+ throwOnError: false,
99
+ ...options,
100
+ })
101
+ } catch (error) {
102
+ console.warn('[scholar/math] LaTeX render error:', error.message)
103
+ return null
104
+ }
105
+ }