| 283 | * only that file's speedup. |
| 284 | */ |
| 285 | export function tryKernelExtract( |
| 286 | filePath: string, |
| 287 | source: string, |
| 288 | language: Language |
| 289 | ): ExtractionResult | null { |
| 290 | if (!kernelRoutes(language)) return null; |
| 291 | const kernel = getKernel(); |
| 292 | if (!kernel) return null; |
| 293 | if (takeDeferredPreParse(filePath, source, language) !== null) return null; // already deferred |
| 294 | const t0 = Date.now(); |
| 295 | const pre = preParsedSource(filePath, source, language); |
| 296 | try { |
| 297 | const buffers = kernel.extractFile(filePath, pre, language); |
| 298 | const result = decodeExtractBuffers(buffers, filePath, language); |
| 299 | POST_PASSES[language]?.(result, source); |
| 300 | // Read beside the tables, as TreeSitterExtractor does (a CommonJS `require`). |
| 301 | result.unresolvedReferences.push(...commonJsRequireRefs(filePath, source, language)); |
| 302 | result.durationMs = Date.now() - t0; |
| 303 | return result; |
| 304 | } catch (err) { |
| 305 | const message = err instanceof Error ? err.message : String(err); |
| 306 | // `defer:` is the kernel's expected-routing signal (files with parse |
| 307 | // errors take the wasm path — its error RECOVERY is the canonical one; |
| 308 | // recovery differs between UTF-8 and UTF-16 parsing). Silent by design. |
| 309 | if (message.includes('defer:')) { |
| 310 | deferSlot = { filePath, source, language, pre }; |
| 311 | return null; |
| 312 | } |
| 313 | if (!warned.has(language)) { |
| 314 | warned.add(language); |
| 315 | process.stderr.write( |
| 316 | `[codegraph-kernel] ${language} extraction failed (${message}) — falling back to the wasm path\n` |
| 317 | ); |
| 318 | } |
| 319 | return null; |
| 320 | } |
| 321 | } |