1- import { ok as assert , ok } from "assert" ;
2- import type {
3- BundledLanguage ,
4- BundledTheme ,
5- Highlighter ,
6- TokenStyles ,
7- } from "shiki" with { "resolution-mode" : "import" } ;
1+ import * as shiki from "@gerrit0/mini-shiki" ;
2+ import type { ShikiInternal } from "@shikijs/types" ;
83import * as JSX from "./jsx.js" ;
94import { unique } from "./array.js" ;
5+ import assert from "assert" ;
106
117const aliases = new Map < string , string > ( ) ;
12- let supportedLanguagesWithoutAliases : string [ ] = [ ] ;
13- let supportedLanguages : string [ ] = [ ] ;
14- let supportedThemes : string [ ] = [ ] ;
15-
16- const plaintextLanguages = [ "txt" , "text" ] ;
17-
18- export async function loadShikiMetadata ( ) {
19- if ( aliases . size ) return ;
20-
21- const shiki = await import ( "shiki" ) ;
22- for ( const lang of shiki . bundledLanguagesInfo ) {
23- for ( const alias of lang . aliases || [ ] ) {
24- aliases . set ( alias , lang . id ) ;
25- }
8+ for ( const lang of shiki . bundledLanguagesInfo ) {
9+ for ( const alias of lang . aliases || [ ] ) {
10+ aliases . set ( alias , lang . id ) ;
2611 }
12+ }
2713
28- supportedLanguages = unique ( [
29- ...plaintextLanguages ,
30- ...aliases . keys ( ) ,
31- ...shiki . bundledLanguagesInfo . map ( ( lang ) => lang . id ) ,
32- ] ) . sort ( ) ;
14+ const plaintextLanguages = [ "txt" , "text" ] ;
3315
34- supportedLanguagesWithoutAliases = unique ( [
35- ...plaintextLanguages ,
36- ...shiki . bundledLanguagesInfo . map ( ( lang ) => lang . id ) ,
37- ] ) ;
16+ const supportedLanguagesWithoutAliases = unique ( [
17+ ...plaintextLanguages ,
18+ ...shiki . bundledLanguagesInfo . map ( ( lang ) => lang . id ) ,
19+ ] ) ;
20+ const supportedLanguages : string [ ] = unique ( [
21+ ...plaintextLanguages ,
22+ ...aliases . keys ( ) ,
23+ ...shiki . bundledLanguagesInfo . map ( ( lang ) => lang . id ) ,
24+ ] ) . sort ( ) ;
3825
39- supportedThemes = Object . keys ( shiki . bundledThemes ) ;
40- }
26+ const supportedThemes : string [ ] = Object . keys ( shiki . bundledThemes ) ;
4127
4228class DoubleHighlighter {
4329 private schemes = new Map < string , string > ( ) ;
4430
4531 constructor (
46- private highlighter : Highlighter ,
47- private light : BundledTheme ,
48- private dark : BundledTheme ,
32+ private highlighter : ShikiInternal ,
33+ private light : shiki . BundledTheme ,
34+ private dark : shiki . BundledTheme ,
4935 ) { }
5036
5137 supports ( lang : string ) {
5238 return this . highlighter . getLoadedLanguages ( ) . includes ( lang ) ;
5339 }
5440
5541 highlight ( code : string , lang : string ) {
56- const tokens = this . highlighter . codeToTokensWithThemes ( code , {
42+ const tokens = shiki . codeToTokensWithThemes ( this . highlighter , code , {
5743 themes : { light : this . light , dark : this . dark } ,
58- lang : lang as BundledLanguage ,
44+ lang : lang as shiki . BundledLanguage ,
5945 } ) ;
6046
6147 const docEls : JSX . Element [ ] = [ ] ;
@@ -121,7 +107,7 @@ class DoubleHighlighter {
121107 return style . join ( "\n" ) ;
122108 }
123109
124- private getClass ( variants : Record < string , TokenStyles > ) : string {
110+ private getClass ( variants : Record < string , shiki . TokenStyles > ) : string {
125111 const key = `${ variants [ "light" ] . color } | ${ variants [ "dark" ] . color } ` ;
126112 let scheme = this . schemes . get ( key ) ;
127113 if ( scheme == null ) {
@@ -132,13 +118,26 @@ class DoubleHighlighter {
132118 }
133119}
134120
121+ let shikiEngine : shiki . RegexEngine | undefined ;
135122let highlighter : DoubleHighlighter | undefined ;
136123
137- export async function loadHighlighter ( lightTheme : BundledTheme , darkTheme : BundledTheme , langs : BundledLanguage [ ] ) {
124+ export async function loadHighlighter (
125+ lightTheme : shiki . BundledTheme ,
126+ darkTheme : shiki . BundledTheme ,
127+ langs : shiki . BundledLanguage [ ] ,
128+ ) {
138129 if ( highlighter ) return ;
139130
140- const shiki = await import ( "shiki" ) ;
141- const hl = await shiki . createHighlighter ( { themes : [ lightTheme , darkTheme ] , langs } ) ;
131+ if ( ! shikiEngine ) {
132+ await shiki . loadBuiltinWasm ( ) ;
133+ shikiEngine = await shiki . createOnigurumaEngine ( ) ;
134+ }
135+
136+ const hl = await shiki . createShikiInternal ( {
137+ engine : shikiEngine ,
138+ themes : [ shiki . bundledThemes [ lightTheme ] , shiki . bundledThemes [ darkTheme ] ] ,
139+ langs : langs . map ( ( lang ) => shiki . bundledLanguages [ lang ] ) ,
140+ } ) ;
142141 highlighter = new DoubleHighlighter ( hl , lightTheme , darkTheme ) ;
143142}
144143
@@ -147,17 +146,14 @@ export function isSupportedLanguage(lang: string) {
147146}
148147
149148export function getSupportedLanguages ( ) : string [ ] {
150- ok ( supportedLanguages . length > 0 , "loadShikiMetadata has not been called" ) ;
151149 return supportedLanguages ;
152150}
153151
154152export function getSupportedLanguagesWithoutAliases ( ) : string [ ] {
155- ok ( supportedLanguagesWithoutAliases . length > 0 , "loadShikiMetadata has not been called" ) ;
156- return supportedLanguages ;
153+ return supportedLanguagesWithoutAliases ;
157154}
158155
159156export function getSupportedThemes ( ) : string [ ] {
160- ok ( supportedThemes . length > 0 , "loadShikiMetadata has not been called" ) ;
161157 return supportedThemes ;
162158}
163159
0 commit comments