import { ClockTable } from '../../json-crdt-patch/codec/clock/ClockTable';
import { PartialEditModel } from './PartialEditModel';
export class PartialEdit {
    decoder;
    encoder;
    clockTable;
    /** List of fields/nodes to fetch before applying the patches. */
    loadList = new Set();
    doc = null;
    constructor(decoder, encoder, clockTable = new ClockTable()) {
        this.decoder = decoder;
        this.encoder = encoder;
        this.clockTable = clockTable;
    }
    populateLoadList(patch) {
        const ops = patch.ops;
        const length = ops.length;
        const loadList = this.loadList;
        for (let i = 0; i < length; i++) {
            const op = ops[i];
            const obj = op.obj;
            if (obj) {
                if (obj.sid === 0) {
                    loadList.add('r');
                    continue;
                }
                const entry = this.clockTable.bySid.get(obj.sid);
                if (!entry)
                    continue;
                const fieldName = `${entry.index.toString(36)}_${obj.time.toString(36)}`;
                loadList.add(fieldName);
            }
        }
    }
    getFieldsToLoad() {
        return this.loadList;
    }
    loadPartialModel(fields) {
        this.doc = this.decoder.decodeFields(this.clockTable, fields, PartialEditModel);
        return this.doc;
    }
    applyPatch(patch) {
        this.doc.applyPatch(patch);
    }
    populateClockTable() {
        const doc = this.doc;
        const peers = doc.clock.peers;
        const clockTable = this.clockTable;
        peers.forEach((clock, sid) => {
            if (!clockTable.bySid.has(sid)) {
                clockTable.push(clock);
            }
        });
    }
    getFieldEdits() {
        const doc = this.doc;
        const updates = this.encoder.encode(doc, this.clockTable);
        const clockTable = this.clockTable;
        const deletedIds = doc.deletes;
        const length = deletedIds.length;
        const deletes = new Set();
        for (let i = 0; i < length; i++) {
            const id = deletedIds[i];
            const field = `${clockTable.getBySid(id.sid).index}_${id.time.toString(36)}`;
            deletes.add(field);
        }
        return {
            updates,
            deletes,
        };
    }
}
export class PartialEditFactory {
    decoder;
    encoder;
    constructor(decoder, encoder) {
        this.decoder = decoder;
        this.encoder = encoder;
    }
    startPartialEdit(clockBlob) {
        const reader = this.decoder.dec.reader;
        reader.reset(clockBlob);
        const clockTable = ClockTable.decode(reader);
        const partialEdit = new PartialEdit(this.decoder, this.encoder, clockTable);
        return partialEdit;
    }
}
//# sourceMappingURL=PartialEdit.js.map