@@ -207,6 +207,16 @@ export type Highlighter = {
207207 dark : string ;
208208 } ;
209209 } ;
210+ /**
211+ * Reexported utilities functions.
212+ */
213+ utils : {
214+ isBundleLanguage : typeof isBundleLanguage ;
215+ isBundleTheme : typeof isBundleTheme ;
216+ isDualTheme : typeof isDualTheme ;
217+ isSingleTheme : typeof isSingleTheme ;
218+ isThemeRegistration : typeof isThemeRegistration ;
219+ } ;
210220} ;
211221
212222export type ShikiHighlighter = shiki . HighlighterGeneric < shiki . BundledLanguage , shiki . BundledTheme > ;
@@ -222,13 +232,16 @@ let manager: MaybePromise<HighlighterManager> | null = null;
222232async function getManager ( ) {
223233 if ( manager !== null ) return manager ;
224234
225- manager = {
235+ // Immediately assign a promise to the manager variable
236+ // to prevent multiple calls to getManager from creating multiple instances
237+ // since shiki.getHighlighter is an async function.
238+ manager = ( async ( ) => ( {
226239 shikiHighlighter : await shiki . getHighlighter ( {
227240 langs : [ ] ,
228241 themes : [ ]
229242 } ) ,
230243 highlighters : [ ]
231- } ;
244+ } ) ) ( ) ;
232245
233246 return manager ;
234247}
@@ -299,10 +312,11 @@ export async function loadHighlighter(options: HighlighterOptions): Promise<High
299312 ) ;
300313
301314 if ( ! langAlreadyLoaded ) {
315+ const langClone = structuredClone ( langDefinition ) ;
302316 // Load the custom language
303- injectGrammarRules ( langDefinition , grammarRules ) ;
304- ( langDefinition as shiki . LanguageRegistration ) . name = langHash ;
305- await manager . shikiHighlighter . loadLanguage ( langDefinition ) ;
317+ injectGrammarRules ( langClone , grammarRules ) ;
318+ ( langClone as shiki . LanguageRegistration ) . name = langHash ;
319+ await manager . shikiHighlighter . loadLanguage ( langClone ) ;
306320 }
307321
308322 let themeHash : string | { light : string ; dark : string } ;
@@ -323,9 +337,10 @@ export async function loadHighlighter(options: HighlighterOptions): Promise<High
323337 ) ;
324338
325339 if ( ! existingHighlighter ) {
326- injectHighlightRules ( themeRegistration , highlightingRules ) ;
327- themeRegistration . name = themeHash ;
328- await manager . shikiHighlighter . loadTheme ( themeRegistration ) ;
340+ const langClone : shiki . ThemeRegistration = structuredClone ( langDefinition ) ;
341+ injectHighlightRules ( langClone , highlightingRules ) ;
342+ langClone . name = themeHash ;
343+ await manager . shikiHighlighter . loadTheme ( langClone ) ;
329344 }
330345 } else {
331346 const { light, dark } = theme ;
@@ -362,12 +377,14 @@ export async function loadHighlighter(options: HighlighterOptions): Promise<High
362377 ) ;
363378
364379 if ( ! existingHighlighter ) {
365- injectHighlightRules ( lightRegistration , highlightingRules ) ;
366- injectHighlightRules ( darkRegistration , highlightingRules ) ;
367- lightRegistration . name = lightHash ;
368- darkRegistration . name = darkHash ;
369- await manager . shikiHighlighter . loadTheme ( lightRegistration ) ;
370- await manager . shikiHighlighter . loadTheme ( darkRegistration ) ;
380+ const lightClone : shiki . ThemeRegistration = structuredClone ( lightRegistration ) ;
381+ const darkClone : shiki . ThemeRegistration = structuredClone ( darkRegistration ) ;
382+ injectHighlightRules ( lightClone , highlightingRules ) ;
383+ injectHighlightRules ( darkClone , highlightingRules ) ;
384+ lightClone . name = lightHash ;
385+ darkClone . name = darkHash ;
386+ await manager . shikiHighlighter . loadTheme ( lightClone ) ;
387+ await manager . shikiHighlighter . loadTheme ( darkClone ) ;
371388 }
372389 }
373390
@@ -394,6 +411,13 @@ export async function loadHighlighter(options: HighlighterOptions): Promise<High
394411 settings : {
395412 langHash,
396413 themeHash
414+ } ,
415+ utils : {
416+ isBundleLanguage,
417+ isBundleTheme,
418+ isDualTheme,
419+ isSingleTheme,
420+ isThemeRegistration
397421 }
398422 } ;
399423
0 commit comments