| 141 | } |
| 142 | |
| 143 | export const getHighlighter = async (language?: string): Promise<Highlighter> => { |
| 144 | try { |
| 145 | const shikilang = normalizeLanguage(language) |
| 146 | |
| 147 | // Initialize highlighter if needed |
| 148 | if (!state.instanceInitPromise) { |
| 149 | state.instanceInitPromise = (async () => { |
| 150 | // const startTime = performance.now() |
| 151 | // console.debug("[Shiki] Initialization started...") |
| 152 | |
| 153 | const instance = await createHighlighter({ |
| 154 | themes: Object.keys(bundledThemes) as BundledTheme[], |
| 155 | langs: initialLanguages, |
| 156 | }) |
| 157 | |
| 158 | // const elapsed = Math.round(performance.now() - startTime) |
| 159 | // console.debug(`[Shiki] Initialization complete (${elapsed}ms)`) |
| 160 | |
| 161 | state.instance = instance |
| 162 | |
| 163 | // Track initially loaded languages |
| 164 | initialLanguages.forEach((lang) => state.loadedLanguages.add(lang)) |
| 165 | |
| 166 | return instance |
| 167 | })() |
| 168 | } |
| 169 | |
| 170 | // Wait for initialization to complete |
| 171 | const instance = await state.instanceInitPromise |
| 172 | |
| 173 | // Load requested language if needed (txt is already in loadedLanguages) |
| 174 | if (!state.loadedLanguages.has(shikilang)) { |
| 175 | // Check for existing pending load |
| 176 | let loadingPromise = state.pendingLanguageLoads.get(shikilang) |
| 177 | |
| 178 | if (!loadingPromise) { |
| 179 | // const loadStart = performance.now() |
| 180 | // Create new loading promise |
| 181 | loadingPromise = (async () => { |
| 182 | try { |
| 183 | // Add artificial delay for testing if nonzero |
| 184 | if (LANGUAGE_LOAD_DELAY > 0) { |
| 185 | await new Promise((resolve) => setTimeout(resolve, LANGUAGE_LOAD_DELAY)) |
| 186 | } |
| 187 | |
| 188 | await instance.loadLanguage(shikilang as BundledLanguage) |
| 189 | state.loadedLanguages.add(shikilang) |
| 190 | |
| 191 | // const loadTime = Math.round(performance.now() - loadStart) |
| 192 | // console.debug(`[Shiki] Loaded language ${shikilang} (${loadTime}ms)`) |
| 193 | } catch (error) { |
| 194 | console.error(`[Shiki] Failed to load language ${shikilang}:`, error) |
| 195 | throw error |
| 196 | } finally { |
| 197 | // Clean up pending promise after completion |
| 198 | state.pendingLanguageLoads.delete(shikilang) |
| 199 | } |
| 200 | })() |