62 lines
1.7 KiB
JavaScript
62 lines
1.7 KiB
JavaScript
/**
|
|
* search_progress.mjs — Track which searches have completed
|
|
* Enables resume on restart without re-running finished searches
|
|
*/
|
|
import { readFileSync, writeFileSync, existsSync, unlinkSync } from 'fs';
|
|
|
|
let progressPath = null;
|
|
let progress = null;
|
|
|
|
export function initProgress(dataDir, lookbackDays) {
|
|
progressPath = `${dataDir}/search_progress.json`;
|
|
|
|
if (existsSync(progressPath)) {
|
|
const saved = JSON.parse(readFileSync(progressPath, 'utf8'));
|
|
// Only resume if same lookback window
|
|
if (saved.lookback_days === lookbackDays) {
|
|
progress = saved;
|
|
const done = progress.completed.length;
|
|
if (done > 0) {
|
|
console.log(`🔁 Resuming — skipping already-completed: ${progress.completed.join(', ')}\n`);
|
|
}
|
|
return progress;
|
|
}
|
|
console.log(`🆕 New lookback window (${lookbackDays}d), starting fresh\n`);
|
|
}
|
|
|
|
// Fresh start
|
|
progress = {
|
|
lookback_days: lookbackDays,
|
|
started_at: Date.now(),
|
|
completed: [],
|
|
pending: [],
|
|
};
|
|
save();
|
|
return progress;
|
|
}
|
|
|
|
export function isCompleted(platform, track) {
|
|
if (!progress) return false;
|
|
return progress.completed.includes(`${platform}:${track}`);
|
|
}
|
|
|
|
export function markComplete(platform, track, stats) {
|
|
if (!progress) return;
|
|
const key = `${platform}:${track}`;
|
|
progress.pending = progress.pending.filter(k => k !== key);
|
|
if (!progress.completed.includes(key)) progress.completed.push(key);
|
|
progress[`stats:${key}`] = { ...stats, completed_at: Date.now() };
|
|
save();
|
|
}
|
|
|
|
export function clearProgress() {
|
|
try { if (progressPath) unlinkSync(progressPath); } catch {}
|
|
progress = null;
|
|
}
|
|
|
|
function save() {
|
|
if (progressPath && progress) {
|
|
writeFileSync(progressPath, JSON.stringify(progress, null, 2));
|
|
}
|
|
}
|