// WAYBACK PROVENANCE ON DISK — the `wayback.json` sidecar. // // A record downloaded from a Wayback Machine capture (lib/wayback.ts) carries // what it is a copy of: the original URL, the capture's timestamp, the capture // as a page that plays and as its raw bytes. Built from the capture URL alone // — no request — so it is written on every download of one // (ytdlp/downloadOneManaged.ts) and by `archilyzer wayback refresh` for a // record imported before this existed (controller/waybackRefresh.ts). import { WAYBACK_PROVENANCE_FILENAME, buildWaybackProvenance, coerceWaybackProvenance, sameWaybackProvenance, type WaybackProvenance, } from "./wayback"; import { sidecar, sidecarField } from "./sidecar-server"; export const waybackProvenanceSidecar = sidecar( WAYBACK_PROVENANCE_FILENAME, sidecarField(coerceWaybackProvenance), ); export const { load: loadWaybackProvenance, write: writeWaybackProvenance } = waybackProvenanceSidecar; // The sidecar for a record fetched by `url`: written when the URL is a // capture and the one on disk is absent or says otherwise. Returns what the // record now carries (null for a URL that is not a capture) and whether it was // (or, with `dryRun`, would be) written. export async function ensureWaybackProvenance( videoDir: string, url: string, opts: { dryRun?: boolean; onLog?: (line: string) => void } = {}, ): Promise<{ provenance: WaybackProvenance | null; written: boolean }> { const next = buildWaybackProvenance(url); if (!next) return { provenance: null, written: false }; const prev = await loadWaybackProvenance(videoDir); if (prev && sameWaybackProvenance(prev, next)) return { provenance: prev, written: false }; if (!opts.dryRun) await writeWaybackProvenance(videoDir, next); opts.onLog?.(`Wayback provenance: a capture of ${next.originalUrl} (${next.captureTs}).\n`); return { provenance: next, written: true }; }