```ts
type Nullable<T> = T | null;

export class LruCache<K, V> {
  capacity: number;
  cacheMap: Map<K, { value: V; latestUsed: Date }>;
  oldestKey: K | null;

  constructor(capacity: number) {
    if (capacity <= 0 || !Number.isInteger(capacity)) {
      throw new Error("Capacity must be a positive integer.");
    }
    this.capacity = capacity;
    this.cacheMap = new Map<K, { value: V; latestUsed: Date }>();
    this.oldestKey = null;
  }

  get(key: K): V | undefined {
    if (!this.cacheMap.has(key)) return undefined;

    const entry = this.cacheMap.get(key);
    entry.latestUsed = new Date(); // Update usage time

    if (this.oldestKey === key) {
      let nextOldestKey = null;
      for (const [k, _] of this.cacheMap.entries()) {
        if (k !== key && (nextOldestKey === null || _.latestUsed.getTime() < entry.latestUsed.getTime())) {
          nextOldestKey = k;
        }
      }
      this.oldestKey = nextOldestKey;
    }

    return entry.value;
  }

  set(key: K, value: V): void {
    if (!this.cacheMap.has(key) && this.size === this.capacity) {
      const oldestEntryKey = this.oldestKey;
      if (oldestEntryKey !== null) {
        this.cacheMap.delete(oldestEntryKey);
      } else {
        throw new Error("Cache is full and cannot accommodate any more entries.");
      }
    }

    this.cacheMap.set(key, { value: value, latestUsed: new Date() });

    if (!this.size || key === this.oldestKey) return;

    let nextOldestKey = null;
    for (const [k, _] of this.cacheMap.entries()) {
      if (k !== key && (nextOldestKey === null || _.latestUsed.getTime() < entry.latestUsed.getTime())) {
        nextOldestKey = k;
      }
    }

    this.oldestKey = nextOldestKey;
  }

  get size(): number {
    return this.cacheMap.size;
  }
}
```