From 6551a1d336081fae169bcff1dd4a8d5cd20f5d32 Mon Sep 17 00:00:00 2001 From: "google-labs-jules[bot]" <161369871+google-labs-jules[bot]@users.noreply.github.com> Date: Sat, 1 Aug 2026 04:31:17 +0000 Subject: [PATCH 1/2] perf: cache historical github year in review data Co-authored-by: is0692vs <135803462+is0692vs@users.noreply.github.com> --- src/lib/githubYearInReview.ts | 24 ++++++++++++++++-------- 1 file changed, 16 insertions(+), 8 deletions(-) diff --git a/src/lib/githubYearInReview.ts b/src/lib/githubYearInReview.ts index 23c4538d..1c09206e 100644 --- a/src/lib/githubYearInReview.ts +++ b/src/lib/githubYearInReview.ts @@ -89,12 +89,12 @@ type GitHubCommit = { -async function graphql(query: string, token: string, variables: Record): Promise { +async function graphql(query: string, token: string, variables: Record, cacheOpt: RequestCache = "no-store"): Promise { const res = await fetch(GITHUB_GRAPHQL, { method: "POST", headers: headers(token), body: JSON.stringify({ query, variables }), - cache: "no-store", + cache: cacheOpt, }); if (res.status === 403) { @@ -144,7 +144,8 @@ async function fetchCommitDatesForTopRepos( token: string, fromIso: string, toIso: string, - repositories?: ContributionsByRepoNode[] + repositories?: ContributionsByRepoNode[], + cacheOpt?: RequestCache ): Promise { const candidates = (repositories || []) .filter((repo) => repo.contributions.totalCount > 0) @@ -193,7 +194,7 @@ async function fetchCommitDatesForTopRepos( }`; try { - const response = await graphql>(query, token, variables); + const response = await graphql>(query, token, variables, cacheOpt); const dates: string[] = []; for (let i = 0; i < candidates.length; i++) { @@ -252,12 +253,15 @@ export async function fetchYearInReviewData(username: string, year: number, toke const to = new Date(Date.UTC(year, 11, 31, 23, 59, 59)); try { + const currentYear = new Date().getFullYear(); + const cacheOpt: RequestCache = year < currentYear ? "force-cache" : "no-store"; + const response = await graphql(YEAR_IN_REVIEW_QUERY, token, { login: username, from: from.toISOString(), to: to.toISOString(), maxRepositories: 10, - }); + }, cacheOpt); if (!response.user) { throw new UserNotFoundError(username); @@ -270,7 +274,8 @@ export async function fetchYearInReviewData(username: string, year: number, toke token, from.toISOString(), to.toISOString(), - collection.commitContributionsByRepository + collection.commitContributionsByRepository, + cacheOpt ); const commitDates = await commitDatesPromise; @@ -292,12 +297,15 @@ export async function fetchCommitActivityHeatmap(username: string, year: number, const from = new Date(Date.UTC(year, 0, 1, 0, 0, 0)); const to = new Date(Date.UTC(year, 11, 31, 23, 59, 59)); + const currentYear = new Date().getFullYear(); + const cacheOpt: RequestCache = year < currentYear ? "force-cache" : "no-store"; + const reposResponse = await graphql(YEAR_IN_REVIEW_QUERY, token, { login: username, from: from.toISOString(), to: to.toISOString(), maxRepositories: 10, - }); + }, cacheOpt); if (!reposResponse.user) { throw new UserNotFoundError(username); @@ -316,7 +324,7 @@ export async function fetchCommitActivityHeatmap(username: string, year: number, url.searchParams.set("until", to.toISOString()); url.searchParams.set("per_page", "100"); - const res = await fetch(url.toString(), { headers: headers(token), cache: "no-store" }); + const res = await fetch(url.toString(), { headers: headers(token), cache: cacheOpt }); if (res.status === 403) { handleRateLimit(res); } From 111bb7e0c968e0e5f82401310bceab8d4ed93e21 Mon Sep 17 00:00:00 2001 From: "google-labs-jules[bot]" <161369871+google-labs-jules[bot]@users.noreply.github.com> Date: Sat, 1 Aug 2026 04:35:01 +0000 Subject: [PATCH 2/2] perf: cache historical github year in review data Co-authored-by: is0692vs <135803462+is0692vs@users.noreply.github.com> --- src/lib/__tests__/githubYearInReview.test.ts | 89 ++++++++++++++++++++ 1 file changed, 89 insertions(+) diff --git a/src/lib/__tests__/githubYearInReview.test.ts b/src/lib/__tests__/githubYearInReview.test.ts index f89b1ac8..faf39809 100644 --- a/src/lib/__tests__/githubYearInReview.test.ts +++ b/src/lib/__tests__/githubYearInReview.test.ts @@ -265,6 +265,95 @@ describe("fetchYearInReviewData success paths", () => { }); }); + +describe("fetchYearInReviewData caching logic", () => { + const currentYear = new Date().getFullYear(); + + beforeEach(() => { + mockFetch.mockResolvedValue(jsonResponse({ + data: { + user: { + id: "U_123", + contributionsCollection: { + totalCommitContributions: 10, + totalPullRequestContributions: 5, + totalIssueContributions: 2, + totalPullRequestReviewContributions: 1, + contributionCalendar: { + totalContributions: 18, + weeks: [] + }, + commitContributionsByRepository: [], + pullRequestContributionsByRepository: [], + issueContributionsByRepository: [] + } + } + } + })); + }); + + it("should use cache: 'no-store' for the current year", async () => { + await fetchYearInReviewData("testuser", currentYear, "mock-token"); + expect(mockFetch).toHaveBeenCalledWith("https://api.github.com/graphql", expect.objectContaining({ + cache: "no-store" + })); + }); + + it("should use cache: 'force-cache' for a past year", async () => { + await fetchYearInReviewData("testuser", currentYear - 1, "mock-token"); + expect(mockFetch).toHaveBeenCalledWith("https://api.github.com/graphql", expect.objectContaining({ + cache: "force-cache" + })); + }); +}); + +describe("fetchCommitActivityHeatmap caching logic", () => { + const currentYear = new Date().getFullYear(); + + beforeEach(() => { + // 1st call for repos + mockFetch.mockResolvedValueOnce(jsonResponse({ + data: { + user: { + id: "U_123", + contributionsCollection: { + commitContributionsByRepository: [{ + repository: { owner: { login: "own" }, name: "repo" }, + contributions: { totalCount: 1 } + }] + } + } + } + })); + // 2nd call for commits + mockFetch.mockResolvedValueOnce(jsonResponse([{ + commit: { author: { date: "2023-01-01T12:00:00Z" } } + }])); + }); + + it("should use cache: 'no-store' for the current year", async () => { + await fetchCommitActivityHeatmap("testuser", currentYear, "mock-token"); + expect(mockFetch).toHaveBeenCalledWith("https://api.github.com/graphql", expect.objectContaining({ + cache: "no-store" + })); + // URL will have the parameters + expect(mockFetch).toHaveBeenCalledWith(expect.stringContaining("https://api.github.com/repos/own/repo/commits"), expect.objectContaining({ + cache: "no-store" + })); + }); + + it("should use cache: 'force-cache' for a past year", async () => { + await fetchCommitActivityHeatmap("testuser", currentYear - 1, "mock-token"); + expect(mockFetch).toHaveBeenCalledWith("https://api.github.com/graphql", expect.objectContaining({ + cache: "force-cache" + })); + expect(mockFetch).toHaveBeenCalledWith(expect.stringContaining("https://api.github.com/repos/own/repo/commits"), expect.objectContaining({ + cache: "force-cache" + })); + }); +}); + + describe("fetchCommitActivityHeatmap", () => { it("successfully fetches and builds commit activity heatmap", async () => { mockFetch.mockImplementation((url: string | URL | Request) => {