@@ -11,6 +11,7 @@ import os from 'node:os';
1111import path from 'node:path' ;
1212import Database from 'better-sqlite3' ;
1313import { afterAll , beforeAll , describe , expect , type TestContext , test } from 'vitest' ;
14+ import { flushDeferredClose } from '../../src/db/index.js' ;
1415
1516// Detect whether transformers is available (optional dep)
1617let hasTransformers = false ;
@@ -81,7 +82,22 @@ describe.skipIf(!hasTransformers)('embedding regression (real model)', () => {
8182 } , 240_000 ) ;
8283
8384 afterAll ( ( ) => {
84- if ( tmpDir ) fs . rmSync ( tmpDir , { recursive : true , force : true } ) ;
85+ if ( ! tmpDir ) return ;
86+ // Flush any deferred DB closes before deleting the temp directory.
87+ // On Windows, SQLite WAL files can remain locked briefly after db.close(),
88+ // causing intermittent EBUSY errors. Retry up to 3 times with a short delay.
89+ flushDeferredClose ( ) ;
90+ const sharedBuf = new SharedArrayBuffer ( 4 ) ;
91+ const sharedArr = new Int32Array ( sharedBuf ) ;
92+ for ( let attempt = 0 ; attempt < 3 ; attempt ++ ) {
93+ try {
94+ fs . rmSync ( tmpDir , { recursive : true , force : true } ) ;
95+ return ;
96+ } catch ( err ) {
97+ if ( ( err as NodeJS . ErrnoException ) . code !== 'EBUSY' || attempt === 2 ) throw err ;
98+ Atomics . wait ( sharedArr , 0 , 0 , 100 ) ;
99+ }
100+ }
85101 } ) ;
86102
87103 describe ( 'smoke tests' , ( ) => {
0 commit comments