/** * @fileoverview TTL cache for parsed `roy-agent tasks tree` envelopes. * * Mirrors `operations-cache.ts`: * 1. Don't spawn the host CLI on every page request. * 2. Coalesce concurrent requests for the same filter combination. * 3. Return past-TTL data while a background refresh runs (for live * UIs that want to display something fast). * * Cache keys are derived from the `TasksTreeFilter` object via a stable * JSON.stringify so functionally-equal filters (e.g. `{ status: undefined, * priority: "high" }` vs `{ priority: "high" }`) hit the same entry. * * v0.8.10+: the cache enforces a hard `maxEntries` cap. Without this, * long-lived hosts that page through every filter combination (the * frontend polls with shifting depth/status/priority/tags) leak * entries forever — see Task #2537 (roy-agent 4 GiB OOM). */ import type { TasksTreeEnvelope, TasksTreeFilter, TasksTreeSource } from "./cli-tasks-tree-adapter.js"; type SourceFn = (filter: TasksTreeFilter) => Promise; export interface TasksTreeCacheOptions { source: SourceFn | TasksTreeSource; /** Time-to-live in milliseconds. Default 5000. */ ttlMs?: number; /** * v0.8.10+: hard cap on the number of cached entries (one per unique * filter combination). Past this limit, the cache sweeps the oldest * stale entries before inserting a new one. Default 64. */ maxEntries?: number; /** Optional: clock for tests. */ now?: () => number; } export declare class TasksTreeCache { private readonly entries; private readonly ttlMs; private readonly source; private readonly now; private readonly maxEntries; constructor(opts: TasksTreeCacheOptions); /** * Fetch (or read from cache). Concurrent calls for the same filter * coalesce. `allowStale: true` returns the cached value past TTL but * triggers a background refresh. */ get(filter: TasksTreeFilter, opts?: { allowStale?: boolean; }): Promise; /** Drop every entry. */ clear(): void; /** Number of cached entries (test introspection). */ size(): number; /** * Sweep entries that are past their TTL once we exceed `maxEntries`. * See OperationsCache.evictStale for the same rationale. * * v2.0.5 (Task #2700): the previous threshold `size <= maxEntries` * left the cache oscillating between `maxEntries` and `maxEntries + 1` * (off-by-one — see OperationsCache for details). The fix: evict * until `size < maxEntries` so the upcoming insert never pushes us * past the cap. */ private evictStale; private refresh; } export {}; //# sourceMappingURL=tasks-tree-cache.d.ts.map