(path: string)
| 1038 | // native handle (and antivirus locks) can briefly outlive close(), so removing |
| 1039 | // a just-closed source/staging db throws EBUSY/EPERM. POSIX never hits this. |
| 1040 | const rmWithRetry = async (path: string): Promise<void> => { |
| 1041 | const delaysMs = [50, 100, 250, 500, 1000, 2000, 4000]; |
| 1042 | for (let attempt = 0; ; attempt++) { |
| 1043 | try { |
| 1044 | fs.rmSync(path, { force: true }); |
| 1045 | return; |
| 1046 | } catch (cause) { |
| 1047 | const code = (cause as NodeJS.ErrnoException).code; |
| 1048 | if ((code !== "EBUSY" && code !== "EPERM") || attempt >= delaysMs.length) throw cause; |
| 1049 | nudgeNativeHandleRelease(); |
| 1050 | await new Promise((resolveDelay) => setTimeout(resolveDelay, delaysMs[attempt])); |
| 1051 | } |
| 1052 | } |
| 1053 | }; |
| 1054 | |
| 1055 | const removeSqliteFileSetWithRetry = async (path: string): Promise<void> => { |
| 1056 | for (const suffix of fileSetSuffixes) await rmWithRetry(`${path}${suffix}`); |
no test coverage detected