@@ -12,14 +12,16 @@ const log = createLogger('chunker');
1212
1313// eslint-disable-next-line @typescript-eslint/no-explicit-any
1414let ParserClass : any ;
15- let initialized = false ;
15+ let initPromise : Promise < void > | null = null ;
1616
1717async function ensureInit ( ) : Promise < void > {
18- if ( initialized ) return ;
19- const mod = await import ( 'web-tree-sitter' ) ;
20- ParserClass = mod . default ;
21- await ParserClass . init ( ) ;
22- initialized = true ;
18+ if ( initPromise ) return initPromise ;
19+ initPromise = ( async ( ) => {
20+ const mod = await import ( 'web-tree-sitter' ) ;
21+ ParserClass = mod . default ;
22+ await ParserClass . init ( ) ;
23+ } ) ( ) ;
24+ return initPromise ;
2325}
2426
2527// --- Grammar loading (WASM files from tree-sitter-wasms package) ---
@@ -39,18 +41,25 @@ const GRAMMAR_FILES: Record<string, string> = {
3941
4042// eslint-disable-next-line @typescript-eslint/no-explicit-any
4143const languages = new Map < string , any > ( ) ;
44+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
45+ const languageLoading = new Map < string , Promise < any > > ( ) ;
4246
4347// eslint-disable-next-line @typescript-eslint/no-explicit-any
4448async function getLanguage ( language : string ) : Promise < any | undefined > {
4549 if ( languages . has ( language ) ) return languages . get ( language ) ! ;
50+ if ( languageLoading . has ( language ) ) return languageLoading . get ( language ) ! ;
4651
4752 const file = GRAMMAR_FILES [ language ] ;
4853 if ( ! file ) return undefined ;
4954
5055 const wasmPath = resolve ( wasmsDir , file ) ;
51- const lang = await ParserClass . Language . load ( wasmPath ) ;
52- languages . set ( language , lang ) ;
53- return lang ;
56+ const p = ParserClass . Language . load ( wasmPath ) . then ( ( lang : unknown ) => {
57+ languages . set ( language , lang ) ;
58+ languageLoading . delete ( language ) ;
59+ return lang ;
60+ } ) ;
61+ languageLoading . set ( language , p ) ;
62+ return p ;
5463}
5564
5665// --- Top-level node types to extract per language ---
@@ -100,43 +109,42 @@ async function chunkAST(source: string, filePath: string, language: string): Pro
100109 const parser = new ParserClass ( ) ;
101110 parser . setLanguage ( lang ) ;
102111
112+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
113+ let tree : any ;
103114 try {
104- const tree = parser . parse ( source ) ;
105-
106- try {
107- const chunks : Chunk [ ] = [ ] ;
108-
109- for ( const node of tree . rootNode . children ) {
110- if ( ! nodeTypes . has ( node . type ) ) continue ;
111-
112- const content = node . text . trim ( ) ;
113- if ( content . length === 0 ) continue ;
114-
115- chunks . push ( {
116- content,
117- filePath,
118- lineStart : node . startPosition . row + 1 ,
119- lineEnd : node . endPosition . row + 1 ,
120- language,
121- type : 'ast' ,
122- } ) ;
123- }
124-
125- if ( chunks . length === 0 && source . trim ( ) . length > 0 ) {
126- log . warn ( `AST parsed but found 0 matching nodes for "${ language } " in: ${ filePath } ` ) ;
127- return [ fallbackChunk ( source , filePath , language ) ] ;
128- }
129-
130- return chunks ;
131- } finally {
132- tree . delete ( ) ;
115+ tree = parser . parse ( source ) ;
116+
117+ const chunks : Chunk [ ] = [ ] ;
118+
119+ for ( const node of tree . rootNode . children ) {
120+ if ( ! nodeTypes . has ( node . type ) ) continue ;
121+
122+ const content = node . text . trim ( ) ;
123+ if ( content . length === 0 ) continue ;
124+
125+ chunks . push ( {
126+ content,
127+ filePath,
128+ lineStart : node . startPosition . row + 1 ,
129+ lineEnd : node . endPosition . row + 1 ,
130+ language,
131+ type : 'ast' ,
132+ } ) ;
133+ }
134+
135+ if ( chunks . length === 0 && source . trim ( ) . length > 0 ) {
136+ log . warn ( `AST parsed but found 0 matching nodes for "${ language } " in: ${ filePath } ` ) ;
137+ return [ fallbackChunk ( source , filePath , language ) ] ;
133138 }
139+
140+ return chunks ;
134141 } catch ( err : unknown ) {
135142 log . error (
136143 `tree-sitter parse failed for ${ filePath } : ${ err instanceof Error ? err . message : err } ` ,
137144 ) ;
138145 return [ fallbackChunk ( source , filePath , language ) ] ;
139146 } finally {
147+ tree ?. delete ( ) ;
140148 parser . delete ( ) ;
141149 }
142150}
0 commit comments