import { randomUUID } from "node:crypto";
import type { Assessment, Draft, Review, Source } from "../src/types";
import { fingerprint } from "./context";
type Entry = {
owner: string;
expires: number;
draft: Draft;
sources: Source[];
report?: {
id: string;
assessment: Assessment;
review: Review;
createdAt: string;
};
};
const entries = new Map<string, Entry>();
const TTL = 2 * 60 * 60 * 1000;
function purge() {
for (const [id, entry] of entries)
if (entry.expires <= Date.now()) entries.delete(id);
}
export function keepDraft(
draft: Draft,
sources: Source[],
owner = "local"
): Draft {
purge();
if (entries.size >= 50) entries.delete(entries.keys().next().value!);
const id = randomUUID();
const saved = { ...draft, id };
entries.set(id, {
owner,
draft: structuredClone(saved),
sources: structuredClone(sources),
expires: Date.now() + TTL,
});
return saved;
}
export function getDraft(
id: string,
sources: Source[],
owner = "local"
): Draft {
purge();
const entry = entries.get(id);
if (!entry || entry.owner !== owner)
throw new Error(
"The review session expired or the server restarted. Extract the sources again."
);
if (fingerprint(sources) !== entry.draft.fingerprint)
throw new Error("Sources changed. Extract and review this version again.");
return structuredClone(entry.draft);
}
export function keepReport(
id: string,
assessment: Assessment,
review: Review,
owner = "local"
): Assessment {
const entry = entries.get(id);
if (!entry || entry.owner !== owner)
throw new Error("The review session expired. Extract again.");
const reportId = randomUUID();
const saved = {
...assessment,
reportId,
extraction: {
mode: entry.draft.mode,
model: entry.draft.model,
durationMs: entry.draft.durationMs,
attempts: entry.draft.attempts,
strategy: entry.draft.strategy,
metrics: entry.draft.metrics,
},
};
entry.report = {
id: reportId,
assessment: structuredClone(saved),
review: structuredClone(review),
createdAt: new Date().toISOString(),
};
return saved;
}
export function getReport(id: string, owner = "local") {
purge();
const entry = [...entries.values()].find((e) => e.report?.id === id);
if (!entry?.report || entry.owner !== owner)
throw new Error(
"This report expired or is no longer current. Run the assessment again."
);
return {
product: "MARMAR Context",
schemaVersion: 1,
synthetic: true,
sources: entry.sources,
extraction: entry.draft,
...entry.report,
};
}