import { tick, Timestamp } from '../../clock';
import { RelativeTimestamp } from './RelativeTimestamp';
class ClockTableEntry {
    index;
    clock;
    constructor(index, clock) {
        this.index = index;
        this.clock = clock;
    }
}
export class ClockEncoder {
    table = new Map();
    /** Start from 1, as 0 is reserved for system session ID. */
    index = 1;
    clock = null;
    reset(clock) {
        this.index = 1;
        this.clock = clock;
        const entry = new ClockTableEntry(this.index++, 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 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(entry.index, timeDiff);
    }
    toJson() {
        const out = [];
        this.table.forEach((entry) => {
            const clock = entry.clock;
            out.push(clock.sid, clock.time);
        });
        return out;
    }
}
//# sourceMappingURL=ClockEncoder.js.map