/**
 * executeGCInSession — compacts trie-backed alive sets through StateSession.
 *
 * Mirrors the legacy synchronous GC contract while keeping the trie-backed
 * substrate honest: metrics are read through session scans and compaction
 * happens through session-owned state access.
 *
 * @module domain/services/executeGCInSession
 */
import VersionVector from "../crdt/VersionVector.js";
import WarpError from "../errors/WarpError.js";
import GCMetrics from "./GCMetrics.js";
import GCExecuteResult from "./GCExecuteResult.js";
export default async function executeGCInSession(session, appliedVV) {
    validateAppliedVersionVector(appliedVV);
    const beforeMetrics = await GCMetrics.fromSession(session);
    await compactSession(session, appliedVV);
    const afterMetrics = await GCMetrics.fromSession(session);
    return new GCExecuteResult({
        nodesCompacted: beforeMetrics.nodeEntries - afterMetrics.nodeEntries,
        edgesCompacted: beforeMetrics.edgeEntries - afterMetrics.edgeEntries,
        tombstonesRemoved: beforeMetrics.totalTombstones - afterMetrics.totalTombstones,
    });
}
function validateAppliedVersionVector(appliedVV) {
    if (!(appliedVV instanceof VersionVector)) {
        throw new WarpError("executeGCInSession requires appliedVV to be a VersionVector", "E_GC_INVALID_VV");
    }
}
async function compactSession(session, appliedVV) {
    try {
        await session.compact(appliedVV);
    }
    catch (error) {
        if (error instanceof WarpError && error.code === "E_STATE_SESSION_CLOSED") {
            throw error;
        }
        throw new WarpError("GC compaction failed during session phase", "E_GC_COMPACT_FAILED", { context: { phase: "session" } });
    }
}
