| 40 | |
| 41 | /** Append one extract event. Only the truncation modes are recorded (whole pages aren't interesting). Best-effort. */ |
| 42 | export async function recordExtract(mode: ExtractMode): Promise<void> { |
| 43 | if (mode !== 'semantic' && mode !== 'head-tail') return; |
| 44 | try { |
| 45 | const { promises: fs } = await import('fs'); |
| 46 | const path = await import('path'); |
| 47 | const file = await metricsFile(); |
| 48 | await fs.mkdir(path.dirname(file), { recursive: true }); |
| 49 | await fs.appendFile(file, JSON.stringify({ t: Date.now(), mode }) + '\n'); |
| 50 | } catch { /* metrics must never break a fetch */ } |
| 51 | } |
| 52 | |
| 53 | /** Read + aggregate the metrics file (last 5000 events). Best-effort → zeros if absent. */ |
| 54 | export async function readExtractMetrics(): Promise<ExtractCounts> { |