(path: string, state: IngestState)
| 324 | } |
| 325 | |
| 326 | function fileChangedSinceState(path: string, state: IngestState): boolean { |
| 327 | const entry = state.sessions[path]; |
| 328 | if (!entry) return true; |
| 329 | try { |
| 330 | const st = statSync(path); |
| 331 | const mtimeNs = Math.floor(st.mtimeMs * 1e6); |
| 332 | if (mtimeNs === entry.mtime_ns) return false; |
| 333 | const sha = fileSha256(path); |
| 334 | if (sha === entry.sha256) { |
| 335 | // mtime changed but content didn't; just refresh mtime to skip future hashing |
| 336 | entry.mtime_ns = mtimeNs; |
| 337 | return false; |
| 338 | } |
| 339 | return true; |
| 340 | } catch { |
| 341 | return true; |
| 342 | } |
| 343 | } |
| 344 | |
| 345 | // ── Walkers ──────────────────────────────────────────────────────────────── |
| 346 |
no test coverage detected