Skip to content

feat: add in-browser caching for mostly-static API data#22

Merged
avishek0769 merged 4 commits into
avishek0769:mainfrom
icancodefyi:feat/in-browser-caching
Jun 2, 2026
Merged

feat: add in-browser caching for mostly-static API data#22
avishek0769 merged 4 commits into
avishek0769:mainfrom
icancodefyi:feat/in-browser-caching

Conversation

@icancodefyi
Copy link
Copy Markdown
Contributor

  • In-memory Map cache with TTL support
  • Stale-while-revalidate for allowlisted GET endpoints
  • Cache invalidation on sign-out, API key/chat mutations, message send, and ingestion completion
  • Cache keys scoped by user ID

Closes #20

Copilot AI review requested due to automatic review settings May 25, 2026 19:45
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Note

Copilot was unable to run its full agentic suite in this review.

Adds a simple in-memory TTL cache utility for the application.

Changes:

  • Introduces a module-level Map-backed cache store with per-entry expiration timestamps.
  • Adds cache operations: get (with TTL eviction), set, clear, remove by key, and remove by substring match.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread src/lib/cache.ts
Comment on lines +18 to +20
export function setInCache<T>(key: string, value: T, ttlMs: number): void {
store.set(key, { value, expiresAt: Date.now() + ttlMs });
}
Comment thread src/lib/cache.ts Outdated
Comment on lines +8 to +15
export function getFromCache<T>(key: string): { value: T } | null {
const entry = store.get(key) as CacheEntry<T> | undefined;
if (!entry) return null;
if (Date.now() > entry.expiresAt) {
store.delete(key);
return null;
}
return { value: entry.value };
Comment thread src/lib/cache.ts Outdated
Comment on lines +8 to +15
export function getFromCache<T>(key: string): { value: T } | null {
const entry = store.get(key) as CacheEntry<T> | undefined;
if (!entry) return null;
if (Date.now() > entry.expiresAt) {
store.delete(key);
return null;
}
return { value: entry.value };
Comment thread src/lib/cache.ts
expiresAt: number;
}

const store = new Map<string, CacheEntry<unknown>>();
Comment thread src/lib/cache.ts Outdated
Comment on lines +30 to +36
export function removeMatchingFromCache(pattern: string): void {
for (const key of store.keys()) {
if (key.includes(pattern)) {
store.delete(key);
}
}
}
- In-memory Map cache with TTL support
- Stale-while-revalidate for allowlisted GET endpoints
- Cache invalidation on sign-out, API key/chat mutations, message send, and ingestion completion
- Cache keys scoped by user ID

Closes avishek0769#20
@icancodefyi icancodefyi force-pushed the feat/in-browser-caching branch from df9965c to ac2fc1f Compare May 25, 2026 19:50
@avishek0769
Copy link
Copy Markdown
Owner

All good. Maybe it will be better to have a global setInterval which sweeps the expired cache after every 5 mins, to avoid too much cache to get stored.

@avishek0769 avishek0769 added medium This is issue is not easy to solve but not hard SSoC26 Social Summer of Code - 2026 labels May 26, 2026
Replace the lazy size-gated expiration sweep (which only ran when
the cache reached 200 entries and only on insert) with a global
setInterval that sweeps all expired entries every 5 minutes,
regardless of cache size. The timer is properly stopped and
restarted on clearCache() to ensure clean session transitions.

This addresses review feedback suggesting a periodic cleanup
strategy to keep memory usage bounded over long sessions.
@icancodefyi
Copy link
Copy Markdown
Contributor Author

@avishek0769 please take a look at the changes

@avishek0769
Copy link
Copy Markdown
Owner

Looks fine.

@avishek0769 avishek0769 merged commit 3ab3dc9 into avishek0769:main Jun 2, 2026
1 check passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

medium This is issue is not easy to solve but not hard SSoC26 Social Summer of Code - 2026

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Add in-browser caching for mostly-static API data

3 participants