this repo has no description
3
fork

Configure Feed

Select the types of activity you want to include in your feed.

feat: cache bust the api routes

+72 -11
+42 -6
public/app.js
··· 8 8 const noGraph = document.getElementById("no-graph"); 9 9 const rankChart = document.getElementById("rank-chart"); 10 10 const verifiedOnlyToggle = document.getElementById("verified-only-toggle"); 11 + 12 + // Auto-refresh timer 13 + let autoRefreshTimer = null; 14 + const AUTO_REFRESH_INTERVAL = 2 * 60 * 1000; // 2 minutes in milliseconds 11 15 12 16 // Track verified user stats 13 17 let verifiedUserStats = { ··· 98 102 storyList.innerHTML = '<div class="loading">Loading stories...</div>'; 99 103 100 104 // Fetch total stories count first 101 - fetch("/api/stats/total-stories") 105 + fetch(`/api/stats/total-stories?_=${Date.now()}`) 102 106 .then((response) => response.json()) 103 107 .then((data) => { 104 108 if (data && typeof data.count !== "undefined") { ··· 111 115 }); 112 116 113 117 // Fetch verified user stats for the top row 114 - fetch("/api/stats/verified-users") 118 + fetch(`/api/stats/verified-users?_=${Date.now()}`) 115 119 .then((response) => response.json()) 116 120 .then((data) => { 117 121 verifiedUserStats = data; 122 + updateTopRowStats(); // Update UI with the new stats 118 123 }) 119 124 .catch((error) => { 120 125 console.error("Error fetching verified user stats:", error); 121 126 }); 122 127 123 - fetch("/api/stories") 128 + fetch(`/api/stories?_=${Date.now()}`) 124 129 .then((response) => { 125 130 if (!response.ok) { 126 131 throw new Error("Network response was not ok"); ··· 266 271 rankChart.style.display = "none"; 267 272 noGraph.innerHTML = '<div class="loading">Loading graph data...</div>'; 268 273 269 - fetch(`/api/story/${storyId}/snapshots`) 274 + fetch(`/api/story/${storyId}/snapshots?_=${Date.now()}`) 270 275 .then((response) => { 271 276 if (!response.ok) { 272 277 throw new Error("Failed to fetch snapshot data"); ··· 398 403 } 399 404 400 405 // Get total stories from the API 401 - fetch("/api/stats/total-stories") 406 + fetch(`/api/stats/total-stories?_=${Date.now()}`) 402 407 .then((response) => response.json()) 403 408 .then((data) => { 404 409 currentFrontpageCountEl.textContent = ··· 451 456 452 457 // Event listeners 453 458 // Add event listeners 454 - refreshButton.addEventListener("click", fetchStories); 459 + refreshButton.addEventListener("click", () => { 460 + fetchStories(); 461 + // Reset auto-refresh timer when manually refreshing 462 + resetAutoRefreshTimer(); 463 + }); 455 464 456 465 // Toggle verified users only 457 466 verifiedOnlyToggle.addEventListener("change", (e) => { ··· 502 511 `; 503 512 document.head.appendChild(style); 504 513 514 + // Auto-refresh function to periodically update data 515 + function startAutoRefreshTimer() { 516 + // Clear any existing timer first 517 + if (autoRefreshTimer) { 518 + clearTimeout(autoRefreshTimer); 519 + } 520 + 521 + // Set new timer 522 + autoRefreshTimer = setTimeout(() => { 523 + console.log("Auto-refreshing data..."); 524 + fetchStories(); 525 + // Set up the next refresh 526 + startAutoRefreshTimer(); 527 + }, AUTO_REFRESH_INTERVAL); 528 + } 529 + 530 + // Reset the auto-refresh timer 531 + function resetAutoRefreshTimer() { 532 + if (autoRefreshTimer) { 533 + clearTimeout(autoRefreshTimer); 534 + } 535 + startAutoRefreshTimer(); 536 + } 537 + 505 538 // Initial data fetch 506 539 fetchStories(); 540 + 541 + // Set up auto-refresh 542 + startAutoRefreshTimer(); 507 543 508 544 // We'll initialize the chart on demand rather than empty 509 545 });
+30 -5
src/index.ts
··· 93 93 })); 94 94 95 95 return new Response(JSON.stringify(alerts), { 96 - headers: { "Content-Type": "application/json" }, 96 + headers: { 97 + "Content-Type": "application/json", 98 + "Cache-Control": "no-store, no-cache, must-revalidate, proxy-revalidate", 99 + "Pragma": "no-cache", 100 + "Expires": "0" 101 + }, 97 102 }); 98 103 } catch (error) { 99 104 console.error("Failed to fetch alerts:", error); ··· 118 123 timestamp: Math.floor(Date.now() / 1000), 119 124 }), 120 125 { 121 - headers: { "Content-Type": "application/json" }, 126 + headers: { 127 + "Content-Type": "application/json", 128 + "Cache-Control": "no-store, no-cache, must-revalidate, proxy-revalidate", 129 + "Pragma": "no-cache", 130 + "Expires": "0" 131 + }, 122 132 }, 123 133 ); 124 134 } catch (error) { ··· 167 177 timestamp: Math.floor(Date.now() / 1000), 168 178 }), 169 179 { 170 - headers: { "Content-Type": "application/json" }, 180 + headers: { 181 + "Content-Type": "application/json", 182 + "Cache-Control": "no-store, no-cache, must-revalidate, proxy-revalidate", 183 + "Pragma": "no-cache", 184 + "Expires": "0" 185 + }, 171 186 }, 172 187 ); 173 188 } catch (error) { ··· 206 221 })); 207 222 208 223 return new Response(JSON.stringify(graphData), { 209 - headers: { "Content-Type": "application/json" }, 224 + headers: { 225 + "Content-Type": "application/json", 226 + "Cache-Control": "no-store, no-cache, must-revalidate, proxy-revalidate", 227 + "Pragma": "no-cache", 228 + "Expires": "0" 229 + }, 210 230 }); 211 231 } catch (error) { 212 232 console.error("Failed to fetch snapshots for story:", error); ··· 221 241 }, 222 242 "/health": () => { 223 243 return new Response(JSON.stringify({ status: "ok" }), { 224 - headers: { "Content-Type": "application/json" }, 244 + headers: { 245 + "Content-Type": "application/json", 246 + "Cache-Control": "no-store, no-cache, must-revalidate, proxy-revalidate", 247 + "Pragma": "no-cache", 248 + "Expires": "0" 249 + }, 225 250 }); 226 251 }, 227 252 "/slack": (res: Request) => {