* Index all files in the project
(
onProgress?: (progress: IndexProgress) => void,
signal?: AbortSignal,
verbose?: boolean,
// Writer-side backstop for deferred WAL checkpointing (#1231): returns
// null in the normal case, or a promise to await (at this safe,
// between-transactions boundary) when the WAL has outrun the off-thread
// checkpointer past its hard cap. See db/wal-valve.ts.
walBackpressure?: () => Promise<void> | null,
// Fresh-DB store offload (perf): when set, per-file store bundles are
// applied by a dedicated writer thread instead of the main thread. Only
// passed for a COMPLETELY fresh database, where the main thread performs
// no reads/writes during the parse loop, so one writer applying bundles
// in file order preserves the #1015 determinism exactly.
storeWriterOpts?: { dbPath: string; fastInit: boolean } | null
)
| 1506 | * Index all files in the project |
| 1507 | */ |
| 1508 | async indexAll( |
| 1509 | onProgress?: (progress: IndexProgress) => void, |
| 1510 | signal?: AbortSignal, |
| 1511 | verbose?: boolean, |
| 1512 | // Writer-side backstop for deferred WAL checkpointing (#1231): returns |
| 1513 | // null in the normal case, or a promise to await (at this safe, |
| 1514 | // between-transactions boundary) when the WAL has outrun the off-thread |
| 1515 | // checkpointer past its hard cap. See db/wal-valve.ts. |
| 1516 | walBackpressure?: () => Promise<void> | null, |
| 1517 | // Fresh-DB store offload (perf): when set, per-file store bundles are |
| 1518 | // applied by a dedicated writer thread instead of the main thread. Only |
| 1519 | // passed for a COMPLETELY fresh database, where the main thread performs |
| 1520 | // no reads/writes during the parse loop, so one writer applying bundles |
| 1521 | // in file order preserves the #1015 determinism exactly. |
| 1522 | storeWriterOpts?: { dbPath: string; fastInit: boolean } | null |
| 1523 | ): Promise<IndexResult> { |
| 1524 | const tGrammar = Date.now(); |
| 1525 | await initGrammars(); |
| 1526 | if (process.env.CODEGRAPH_SYNTH_TIMINGS) console.error(`[phase-timing] grammar-init: ${Date.now() - tGrammar}ms`); |
| 1527 | const startTime = Date.now(); |
| 1528 | const errors: ExtractionError[] = []; |
| 1529 | let filesIndexed = 0; |
| 1530 | let filesSkipped = 0; |
| 1531 | let filesErrored = 0; |
| 1532 | let totalNodes = 0; |
| 1533 | let totalEdges = 0; |
| 1534 | |
| 1535 | // Custom extension → language overrides from the project's codegraph.json. |
| 1536 | // Threaded into language detection so custom-extension files load the right |
| 1537 | // grammar and store under the mapped language. |
| 1538 | const overrides = loadExtensionOverrides(this.rootDir); |
| 1539 | |
| 1540 | const log = verbose |
| 1541 | ? (msg: string) => { console.log(`[worker] ${msg}`); } |
| 1542 | : (_msg: string) => {}; |
| 1543 | |
| 1544 | // Phase 1: Scan for files |
| 1545 | onProgress?.({ |
| 1546 | phase: 'scanning', |
| 1547 | current: 0, |
| 1548 | total: 0, |
| 1549 | }); |
| 1550 | |
| 1551 | // Phase attribution to stderr (same opt-in as the synthesis timings): |
| 1552 | // early-run 5-10s single stalls were observed on 95k-file repos but never |
| 1553 | // attributed — these labels settle scan vs framework-detect vs grammars. |
| 1554 | const tScan = Date.now(); |
| 1555 | const files = await scanDirectoryAsync(this.rootDir, (current, file) => { |
| 1556 | onProgress?.({ |
| 1557 | phase: 'scanning', |
| 1558 | current, |
| 1559 | total: 0, |
| 1560 | currentFile: file, |
| 1561 | }); |
| 1562 | }); |
| 1563 | if (process.env.CODEGRAPH_SYNTH_TIMINGS) console.error(`[phase-timing] scan: ${Date.now() - tScan}ms (${files.length} files)`); |
| 1564 | |
| 1565 | // Detect frameworks once per indexAll run using the scanned file list. |
no test coverage detected