type CacheEntry = {
  expiresAt: number
  value: Promise<unknown>
}

/** Short-lived read cache that also coalesces concurrent requests. */
export class WorkerListCache {
  private readonly entries = new Map<string, CacheEntry>()

  constructor(
    private readonly ttlMs: number,
    private readonly maxEntries = 256,
  ) {}

  getOrSet<T>(key: string, factory: () => Promise<T>): Promise<T> {
    const now = Date.now()
    const cached = this.entries.get(key)
    if (cached && cached.expiresAt > now) return cached.value as Promise<T>
    if (cached) this.entries.delete(key)

    const value = factory().catch((error) => {
      this.entries.delete(key)
      throw error
    })
    if (this.entries.size >= this.maxEntries) {
      const oldestKey = this.entries.keys().next().value
      if (oldestKey) this.entries.delete(oldestKey)
    }
    this.entries.set(key, { expiresAt: now + this.ttlMs, value })
    return value
  }
}
