"use strict";
/*!
 * Copyright (c) Microsoft Corporation and contributors. All rights reserved.
 * Licensed under the MIT License.
 */
Object.defineProperty(exports, "__esModule", { value: true });
exports.BranchCommitEnricher = void 0;
const internal_1 = require("@fluidframework/core-utils/internal");
const index_js_1 = require("../core/index.js");
const transactionEnricher_js_1 = require("./transactionEnricher.js");
/**
 * Utility for enriching commits from a {@link Branch} before these commits are applied and submitted.
 */
class BranchCommitEnricher {
    constructor(rebaser, enricher) {
        /**
         * Maps each local commit to the corresponding enriched commit.
         * Entries are added when the commits are prepared (before being applied and submitted).
         * Entries are removed when the commits are retrieved for submission (after being applied).
         * It's possible an entry will linger in the map indefinitely if it is never retrieved for submission.
         * This would happen if applying a commit were to fail and the commit were not retrieved/purged after the failure.
         */
        this.preparedCommits = new Map();
        this.enricher = enricher;
        this.transactionEnricher = new transactionEnricher_js_1.TransactionEnricher(rebaser, this.enricher);
    }
    /**
     * @returns The number of commits that have been prepared but not yet retrieved.
     */
    get preparedCommitsCount() {
        return this.preparedCommits.size;
    }
    startNewTransaction() {
        this.transactionEnricher.startNewTransaction();
    }
    commitCurrentTransaction() {
        this.transactionEnricher.commitCurrentTransaction();
    }
    abortCurrentTransaction() {
        this.transactionEnricher.abortCurrentTransaction();
    }
    /**
     * Adds a commit to the enricher.
     * @param commit - A commit that is part of a transaction.
     */
    ingestTransactionCommit(commit) {
        // We do not submit ops for changes that are part of a transaction.
        // But we need to enrich the commits that will be sent if the transaction is committed.
        this.transactionEnricher.addTransactionStep(commit);
    }
    /**
     * Prepares an enriched commit for later submission (see {@link BranchCommitEnricher.getPreparedCommit}).
     * @param commit - The commit to prepare an enriched version of.
     * @param concludesOuterTransaction - Whether the commit concludes an outer transaction.
     *
     * Each call to this method must be followed by a call to {@link BranchCommitEnricher.getPreparedCommit} or
     * {@link BranchCommitEnricher.purgePreparedCommits}. Failing to do so will result in a memory leak.
     */
    prepareCommit(commit, concludesOuterTransaction) {
        let enrichedChange;
        if (concludesOuterTransaction) {
            (0, internal_1.assert)(this.transactionEnricher !== undefined, 0x97f /* Unexpected transaction commit without transaction steps */);
            enrichedChange = this.transactionEnricher.getComposedChange(commit.revision);
        }
        else {
            enrichedChange = this.enricher.updateChangeEnrichments(commit.change, commit.revision);
        }
        this.preparedCommits.set(commit, (0, index_js_1.replaceChange)(commit, enrichedChange));
    }
    /**
     * @param commit - A commit previously passed to {@link BranchCommitEnricher.prepareCommit}.
     * @returns The enriched commit corresponds to the given commit.
     */
    getPreparedCommit(commit) {
        const prepared = this.preparedCommits.get(commit);
        (0, internal_1.assert)(prepared !== undefined, 0x980 /* Unknown commit */);
        this.preparedCommits.delete(commit);
        return prepared;
    }
    /**
     * Purges all commits that have been prepared but not been retrieved.
     * This should be called to avoid memory leaks if the prepared commits are no longer needed.
     *
     * Does not affect ingested transaction commits.
     */
    purgePreparedCommits() {
        this.preparedCommits.clear();
    }
}
exports.BranchCommitEnricher = BranchCommitEnricher;
//# sourceMappingURL=branchCommitEnricher.js.map