MCPcopy Create free account
hub / github.com/SpecterOps/Nemesis / cachedFetch

Function cachedFetch

projects/frontend/src/utils/fileCache.js:152–227  ·  view source on GitHub ↗
(url, options = {})

Source from the content-addressed store, hash-verified

150 * Drop-in replacement for fetch() for /api/files/* endpoints
151 */
152export async function cachedFetch(url, options = {}) {
153 // Parse URL
154 const urlObj = new URL(url, window.location.origin);
155
156 // Only cache GET requests to /api/files/*
157 const shouldCache =
158 (!options.method || options.method === 'GET') &&
159 urlObj.pathname.startsWith('/api/files/') &&
160 !urlObj.searchParams.has('name'); // Don't cache downloads
161
162 if (!shouldCache) {
163 return fetch(url, options);
164 }
165
166 const cacheKey = fileCache.getCacheKey(url);
167
168 // Check cache first
169 const cachedResponse = await fileCache.get(url);
170 if (cachedResponse) {
171 return cachedResponse;
172 }
173
174 // Check if there's already a pending request for this URL
175 if (fileCache.pendingRequests.has(cacheKey)) {
176 log('[FileCache] Deduplicating request:', cacheKey);
177 // Wait for the pending request to complete
178 await fileCache.pendingRequests.get(cacheKey);
179 // Get a fresh copy from cache (each caller gets their own Response object)
180 const cached = await fileCache.get(url);
181 if (cached) {
182 return cached;
183 }
184 // If not in cache (caching may have failed), fallback to direct fetch
185 warn('[FileCache] Deduplicated request cache miss, falling back to direct fetch:', cacheKey);
186 return fetch(url, options);
187 }
188
189 // Fetch from network
190 log('[FileCache] Fetching from network:', cacheKey);
191
192 const fetchPromise = (async () => {
193 const response = await fetch(url, options);
194
195 // Cache successful responses
196 if (response.ok) {
197 await fileCache.set(url, response);
198 }
199
200 // Signal completion (don't return the response itself to avoid stream issues)
201 return response.ok;
202 })();
203
204 // Store the promise so concurrent requests can reuse it
205 fileCache.pendingRequests.set(cacheKey, fetchPromise);
206
207 try {
208 const success = await fetchPromise;
209 if (success) {

Callers 3

useLazyFileContentFunction · 0.90
FileViewerFunction · 0.90
fetchFileDataFunction · 0.90

Calls 6

logFunction · 0.85
getCacheKeyMethod · 0.80
setMethod · 0.80
deleteMethod · 0.80
warnFunction · 0.70
getMethod · 0.45

Tested by

no test coverage detected