@@ -491,20 +491,13 @@ async function runPostNativeAnalysis(
491491 }
492492 }
493493
494- // Wire up WAL checkpoint callbacks for the analysis engine
494+ // Flush JS WAL pages once so Rust can see them, then no-op callbacks.
495+ // Previously each feature called wal_checkpoint(TRUNCATE) individually
496+ // (~68ms each × 3-4 features). One FULL checkpoint suffices.
495497 if ( ctx . nativeDb && ctx . engineOpts ) {
496- ctx . engineOpts . suspendJsDb = ( ) => {
497- ctx . db . pragma ( 'wal_checkpoint(TRUNCATE)' ) ;
498- } ;
499- ctx . engineOpts . resumeJsDb = ( ) => {
500- try {
501- ctx . nativeDb ?. exec ( 'PRAGMA wal_checkpoint(TRUNCATE)' ) ;
502- } catch ( e ) {
503- debug (
504- `resumeJsDb: WAL checkpoint failed (nativeDb may already be closed): ${ toErrorMessage ( e ) } ` ,
505- ) ;
506- }
507- } ;
498+ ctx . db . pragma ( 'wal_checkpoint(FULL)' ) ;
499+ ctx . engineOpts . suspendJsDb = ( ) => { } ;
500+ ctx . engineOpts . resumeJsDb = ( ) => { } ;
508501 }
509502
510503 try {
@@ -532,7 +525,9 @@ async function runPostNativeAnalysis(
532525 warn ( `Analysis phases failed after native build: ${ toErrorMessage ( err ) } ` ) ;
533526 }
534527
535- // Close nativeDb after analyses
528+ // Close nativeDb after analyses — TRUNCATE checkpoint flushes all Rust
529+ // WAL writes so JS and external readers can see them. Runs once after
530+ // all analysis features complete (not per-feature).
536531 if ( ctx . nativeDb ) {
537532 try {
538533 ctx . nativeDb . exec ( 'PRAGMA wal_checkpoint(TRUNCATE)' ) ;
@@ -753,25 +748,20 @@ async function runPipelineStages(ctx: PipelineContext): Promise<void> {
753748 await buildEdges ( ctx ) ;
754749 await buildStructure ( ctx ) ;
755750
756- // Reopen nativeDb for feature modules (ast, cfg, complexity, dataflow)
757- // which use suspendJsDb/resumeJsDb WAL checkpoint before native writes.
751+ // Reopen nativeDb for feature modules (ast, cfg, complexity, dataflow).
758752 // Skip for small incremental builds — same rationale as insertNodes above.
753+ //
754+ // Perf: do ONE upfront FULL checkpoint to flush JS WAL pages so Rust
755+ // can see the latest rows, then make suspendJsDb/resumeJsDb no-ops.
756+ // Previously each feature called wal_checkpoint(TRUNCATE) individually
757+ // (~68ms each × 3-4 features = ~200-270ms overhead on incremental builds).
759758 if ( ctx . nativeAvailable && ! smallIncremental ) {
760759 reopenNativeDb ( ctx , 'analyses' ) ;
761760 if ( ctx . nativeDb && ctx . engineOpts ) {
761+ ctx . db . pragma ( 'wal_checkpoint(FULL)' ) ;
762762 ctx . engineOpts . nativeDb = ctx . nativeDb ;
763- ctx . engineOpts . suspendJsDb = ( ) => {
764- ctx . db . pragma ( 'wal_checkpoint(TRUNCATE)' ) ;
765- } ;
766- ctx . engineOpts . resumeJsDb = ( ) => {
767- try {
768- ctx . nativeDb ?. exec ( 'PRAGMA wal_checkpoint(TRUNCATE)' ) ;
769- } catch ( e ) {
770- debug (
771- `resumeJsDb: WAL checkpoint failed (nativeDb may already be closed): ${ toErrorMessage ( e ) } ` ,
772- ) ;
773- }
774- } ;
763+ ctx . engineOpts . suspendJsDb = ( ) => { } ;
764+ ctx . engineOpts . resumeJsDb = ( ) => { } ;
775765 }
776766 if ( ! ctx . nativeDb && ctx . engineOpts ) {
777767 ctx . engineOpts . nativeDb = undefined ;
@@ -782,11 +772,15 @@ async function runPipelineStages(ctx: PipelineContext): Promise<void> {
782772
783773 await runAnalyses ( ctx ) ;
784774
785- // Keep nativeDb open through finalize so persistBuildMetadata, advisory
786- // checks, and count queries use the native path. closeDbPair inside
787- // finalize handles both connections. Refresh the JS db so it has a
788- // valid page cache in case finalize falls back to JS paths (#751).
775+ // Flush Rust WAL writes (AST, complexity, CFG, dataflow) so the JS
776+ // connection and any post-build readers can see them. One TRUNCATE
777+ // here replaces the N per-feature resumeJsDb checkpoints (#checkpoint-opt).
789778 if ( ctx . nativeDb ) {
779+ try {
780+ ctx . nativeDb . exec ( 'PRAGMA wal_checkpoint(TRUNCATE)' ) ;
781+ } catch ( e ) {
782+ debug ( `post-analyses WAL checkpoint failed: ${ toErrorMessage ( e ) } ` ) ;
783+ }
790784 refreshJsDb ( ctx ) ;
791785 }
792786
0 commit comments