(logsDirs: string[])
| 191 | * Processes workspace directories in parallel batches. |
| 192 | */ |
| 193 | export async function computeDirMetasAsync(logsDirs: string[]): Promise<DirMetas> { |
| 194 | const metas: DirMetas = {}; |
| 195 | const CONCURRENCY = 64; |
| 196 | |
| 197 | // Collect all workspace paths first |
| 198 | const wsPaths: string[] = []; |
| 199 | for (const logsDir of logsDirs) { |
| 200 | if (logsDir.includes(path.join('.config', 'github-copilot', 'xcode')) || |
| 201 | logsDir.includes(path.join('.copilot', 'session-state')) || |
| 202 | logsDir.includes(path.join('.copilot', 'history-session-state'))) continue; |
| 203 | try { |
| 204 | const entries = await fs.promises.readdir(logsDir, { withFileTypes: true }); |
| 205 | for (const e of entries) { |
| 206 | if (!e.isDirectory()) continue; |
| 207 | wsPaths.push(path.join(logsDir, e.name)); |
| 208 | } |
| 209 | } catch { /* cannot read logsDir */ } |
| 210 | } |
| 211 | |
| 212 | // Process in parallel batches |
| 213 | for (let i = 0; i < wsPaths.length; i += CONCURRENCY) { |
| 214 | const batch = wsPaths.slice(i, i + CONCURRENCY); |
| 215 | const results = await Promise.allSettled( |
| 216 | batch.map(async wsPath => { |
| 217 | const [chat, edit] = await Promise.all([ |
| 218 | dirFingerprintAsync(path.join(wsPath, 'chatSessions')), |
| 219 | dirFingerprintAsync(path.join(wsPath, 'chatEditingSessions'), true), |
| 220 | ]); |
| 221 | return { wsPath, chat, edit }; |
| 222 | }) |
| 223 | ); |
| 224 | for (const r of results) { |
| 225 | if (r.status === 'fulfilled') { |
| 226 | metas[r.value.wsPath] = { |
| 227 | chatCount: r.value.chat.count, |
| 228 | chatMaxMtime: r.value.chat.mtime, |
| 229 | editCount: r.value.edit.count, |
| 230 | editMaxMtime: r.value.edit.mtime, |
| 231 | }; |
| 232 | } |
| 233 | } |
| 234 | } |
| 235 | return metas; |
| 236 | } |
| 237 | |
| 238 | /* ---- Diff helpers ---- */ |
| 239 |
no test coverage detected