All files / json-crdt-patch/codec/clock ClockEncoder.ts

96.87% Statements 31/32
66.66% Branches 2/3
100% Functions 6/6
100% Lines 30/30

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51175x 175x       127264x 127264x       175x 2857x   2857x 2857x     8368x 8368x 8368x 8368x 8368x       1033184x 1033184x 1033184x 1033184x 118896x 118896x 118896x 118896x   1033184x 1033184x 1033184x 1033184x       2222x   2222x 30780x 30780x   2222x      
import {type ITimestampStruct, type IClockVector, tick, Timestamp} from '../../clock';
import {RelativeTimestamp} from './RelativeTimestamp';
 
class ClockTableEntry {
  constructor(
    public index: number,
    public clock: ITimestampStruct,
  ) {}
}
 
export class ClockEncoder {
  public readonly table: Map<number, ClockTableEntry> = new Map<number, ClockTableEntry>();
  /** Start from 1, as 0 is reserved for system session ID. */
  protected index: number = 1;
  public clock: IClockVector | null = null;
 
  public reset(clock: IClockVector) {
    this.index = 1;
    this.clock = clock;
    const entry = new ClockTableEntry(this.index++, tick(clock, -1));
    this.table.clear();
    this.table.set(clock.sid, entry);
  }
 
  public append(ts: ITimestampStruct): RelativeTimestamp {
    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;
    Iif (timeDiff < 0) throw new Error('TIME_TRAVEL');
    return new RelativeTimestamp(entry.index, timeDiff);
  }
 
  public toJson(): number[] {
    const out: number[] = [];
    // biome-ignore lint: using .forEach() on Map is the fastest way to iterate
    this.table.forEach((entry) => {
      const clock = entry.clock;
      out.push(clock.sid, clock.time);
    });
    return out;
  }
}