Skip to content

Commit 158a94e

Browse files
committed
cache requests to github api in store and remove token
1 parent dfe74b3 commit 158a94e

File tree

5 files changed

+70
-22
lines changed

5 files changed

+70
-22
lines changed
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
import { writable } from 'svelte/store';
2+
3+
export const contributorsStore = writable([]);

src/lib/utils/cache.ts

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
import { writable, get } from 'svelte/store';
2+
import type { CacheEntry } from '$lib/utils/types';
3+
4+
export const contributorsStore = writable<Map<string, CacheEntry<unknown>>>(new Map());
5+
6+
const CACHE_TTL = 60 * 60 * 1000;
7+
8+
export async function fetchWithCache<T>(url: string): Promise<T> {
9+
const now = Date.now();
10+
11+
const cache = get(contributorsStore);
12+
13+
const cached = cache.get(url);
14+
if (cached && cached.expiresAt > now) {
15+
console.log('Fetching data from store');
16+
return cached.data as T;
17+
}
18+
19+
console.log('Fetching data from API');
20+
21+
const response = await fetch(url);
22+
23+
const rateLimit = response.headers.get('X-RateLimit-Limit');
24+
const rateRemaining = response.headers.get('X-RateLimit-Remaining');
25+
const resetTime = response.headers.get('X-RateLimit-Reset');
26+
27+
if (rateLimit && rateRemaining) {
28+
console.log(
29+
`Rate limit: ${rateLimit}, Remaining: ${rateRemaining} ${new Date(Date.now()).toLocaleTimeString([], { hour: '2-digit', minute: '2-digit' })}`
30+
);
31+
}
32+
33+
if (resetTime) {
34+
const resetDate = new Date(parseInt(resetTime) * 1000);
35+
console.log(`Rate limit resets at: ${resetDate}`);
36+
}
37+
38+
if (!response.ok) {
39+
console.error(`Failed to fetch from ${url}:`, response.statusText);
40+
throw new Error(`Failed to fetch from ${url}`);
41+
}
42+
43+
const data = await response.json();
44+
45+
contributorsStore.update((currentCache) => {
46+
currentCache.set(url, { data, expiresAt: now + CACHE_TTL });
47+
return new Map(currentCache);
48+
});
49+
50+
return data;
51+
}

src/lib/utils/types.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,11 @@ export type Contributor = {
3333
html_url: string;
3434
};
3535

36+
export type CacheEntry<T> = {
37+
data: T;
38+
expiresAt: number;
39+
};
40+
3641
export type BlogPost = {
3742
tags: string[];
3843
keywords: string[];

src/routes/(home)/+page.server.ts

Lines changed: 3 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,37 +1,21 @@
1-
import features from '$lib/data/features';
21
import { fetchMarkdownPosts } from '$lib/utils/index_posts';
32
import type { Contributor } from '$lib/utils/types';
3+
import { fetchWithCache } from '$lib/utils/cache';
44

5-
const GITHUB_TOKEN = import.meta.env.VITE_GITHUB_TOKEN;
65
const BASE_URL = 'https://api.github.com';
76

8-
async function fetchWithAuth(url: string) {
9-
const response = await fetch(url, {
10-
headers: {
11-
Authorization: `Bearer ${GITHUB_TOKEN}`
12-
}
13-
});
14-
15-
if (!response.ok) {
16-
console.error(`Failed to fetch from ${url}:`, response.statusText);
17-
throw new Error(`Failed to fetch from ${url}`);
18-
}
19-
20-
return response.json();
21-
}
22-
237
export async function load() {
248
const allPosts = await fetchMarkdownPosts();
259
const posts = allPosts
2610
.sort((a, b) => new Date(b.meta.date).getTime() - new Date(a.meta.date).getTime())
2711
.slice(0, 6);
2812

29-
const repos = await fetchWithAuth(`${BASE_URL}/orgs/torrust/repos`);
13+
const repos = await fetchWithCache<{ name: string }[]>(`${BASE_URL}/orgs/torrust/repos`);
3014
const gitHubRepos = repos.map((repo: { name: string }) => repo.name);
3115

3216
const contributorResponses = await Promise.all(
3317
gitHubRepos.map((repo: string) =>
34-
fetchWithAuth(`${BASE_URL}/repos/torrust/${repo}/contributors`)
18+
fetchWithCache<Contributor[]>(`${BASE_URL}/repos/torrust/${repo}/contributors`)
3519
)
3620
);
3721

@@ -41,7 +25,6 @@ export async function load() {
4125
);
4226

4327
return {
44-
features,
4528
posts,
4629
allContributors: uniqueContributors
4730
};

src/routes/(home)/+page.svelte

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,15 +8,21 @@
88
export let data: {
99
posts: BlogPost[];
1010
allContributors: Contributor[];
11-
gitHubRepos: string[];
1211
};
1312
1413
let filteredPosts = data.posts;
14+
let showContributors = true; // A state to control visibility of Contributors component
15+
let errorMessage = '';
1516
</script>
1617

1718
<Hero />
1819
<WhyContribute />
19-
<Contributors contributors={data.allContributors} />
20+
21+
{#if showContributors}
22+
<Contributors contributors={data.allContributors} />
23+
{:else}
24+
<p>{errorMessage}</p>
25+
{/if}
2026

2127
{#if filteredPosts && filteredPosts.length > 0}
2228
<div class="container">

0 commit comments

Comments
 (0)