Skip to content

Commit 08e22c3

Browse files
authored
Merge pull request #1015 from Zarmaijemimah/feature/network-optimization
Feature/network optimization
2 parents 769d1bc + a735b4d commit 08e22c3

3 files changed

Lines changed: 965 additions & 0 deletions

File tree

Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
/**
2+
* Shared RequestCache instance for the entire application.
3+
*
4+
* Single source of truth for all cached API requests, with optimized
5+
* defaults for the clips application.
6+
*/
7+
8+
import { RequestCache } from "./RequestCache";
9+
import { fetchAnalytics } from "./FetchAnalytics";
10+
11+
/**
12+
* Global request cache with production-tuned settings:
13+
* - 60s fresh TTL for most API responses
14+
* - 5-minute stale window for background revalidation
15+
* - 200-entry LRU cache (enough for a long session browsing clips)
16+
* - 6 concurrent requests max (browser default)
17+
*/
18+
export const requestCache = new RequestCache({
19+
ttlMs: 60_000, // 1 minute fresh
20+
staleTtlMs: 5 * 60_000, // 5 minutes stale-while-revalidate
21+
maxEntries: 200,
22+
maxConcurrent: 6,
23+
analytics: fetchAnalytics,
24+
});
25+
26+
/**
27+
* Convenience wrapper around requestCache.fetch with type safety.
28+
*/
29+
export async function cachedFetch<T>(
30+
url: string,
31+
options: RequestInit & {
32+
priority?: "high" | "normal" | "low";
33+
tags?: string[];
34+
ttlMs?: number;
35+
forceRefresh?: boolean;
36+
} = {}
37+
): Promise<T> {
38+
const { priority, tags, ttlMs, forceRefresh, ...fetchOptions } = options;
39+
40+
return requestCache.fetch(
41+
url,
42+
(signal) =>
43+
fetch(url, { ...fetchOptions, signal }).then((res) => {
44+
if (!res.ok) {
45+
throw new Error(`HTTP ${res.status}: ${res.statusText}`);
46+
}
47+
return res.json();
48+
}),
49+
{ priority, tags, ttlMs, forceRefresh }
50+
);
51+
}
52+
53+
/**
54+
* Invalidate cache entries by tag.
55+
* Use after mutations to ensure stale data is refreshed.
56+
*
57+
* @example
58+
* ```ts
59+
* // After creating a clip
60+
* await createClip(data);
61+
* invalidateCacheTags(['clips', 'projects']);
62+
* ```
63+
*/
64+
export function invalidateCacheTags(...tags: string[]): number {
65+
return requestCache.invalidateTags(...tags);
66+
}
67+
68+
/**
69+
* Get cache statistics for monitoring.
70+
*/
71+
export function getCacheStats() {
72+
return requestCache.stats();
73+
}

0 commit comments

Comments
 (0)