"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.ClockEncoder = void 0;
const clock_1 = require("../../clock");
const RelativeTimestamp_1 = require("./RelativeTimestamp");
class ClockTableEntry {
    constructor(index, clock) {
        this.index = index;
        this.clock = clock;
    }
}
class ClockEncoder {
    constructor() {
        this.table = new Map();
        /** Start from 1, as 0 is reserved for system session ID. */
        this.index = 1;
        this.clock = null;
    }
    reset(clock) {
        this.index = 1;
        this.clock = clock;
        const entry = new ClockTableEntry(this.index++, (0, clock_1.tick)(clock, -1));
        this.table.clear();
        this.table.set(clock.sid, entry);
    }
    append(ts) {
        const time = ts.time;
        const sid = ts.sid;
        let entry = this.table.get(sid);
        if (!entry) {
            let clock = this.clock.peers.get(sid);
            if (!clock)
                clock = new clock_1.Timestamp(sid, this.clock.time - 1);
            entry = new ClockTableEntry(this.index++, clock);
            this.table.set(sid, entry);
        }
        const clock = entry.clock;
        const timeDiff = clock.time - time;
        if (timeDiff < 0)
            throw new Error('TIME_TRAVEL');
        return new RelativeTimestamp_1.RelativeTimestamp(entry.index, timeDiff);
    }
    toJson() {
        const out = [];
        this.table.forEach((entry) => {
            const clock = entry.clock;
            out.push(clock.sid, clock.time);
        });
        return out;
    }
}
exports.ClockEncoder = ClockEncoder;
//# sourceMappingURL=ClockEncoder.js.map