fix: merge state indicator (#90)

The PR status should update upon merging.
This PR also updates the cache for the issue/pr counter.
This commit is contained in:
Maxwell
2026-02-26 11:06:48 +10:00
committed by GitHub
parent 4faeb7a2cd
commit a4fef17b19
4 changed files with 60 additions and 1 deletions
+13
View File
@@ -102,6 +102,19 @@ export async function deleteGithubCacheByPrefix(userId: string, prefix: string)
} while (cursor !== 0);
}
export async function deleteSharedCacheByPrefix(prefix: string) {
const pattern = `ghpub:${prefix}*`;
let cursor = 0;
do {
const result = await redis.scan(cursor, { match: pattern, count: 100 });
const keys = result[1];
cursor = Number(result[0]);
if (keys.length > 0) {
await redis.del(...keys);
}
} while (cursor !== 0);
}
export async function enqueueGithubSyncJob<TPayload>(
userId: string,
dedupeKey: string,
+25 -1
View File
@@ -5,6 +5,7 @@ import { $Session, getServerSession } from "./auth";
import {
claimDueGithubSyncJobs,
deleteGithubCacheByPrefix,
deleteSharedCacheByPrefix,
enqueueGithubSyncJob,
getGithubCacheEntry,
getSharedCacheEntry,
@@ -3279,7 +3280,7 @@ export async function getRepoIssuesPage(owner: string, repo: string): Promise<Re
openCount: 0,
closedCount: 0,
};
return readLocalFirstGitData({
const data = await readLocalFirstGitData({
authCtx,
cacheKey: buildRepoIssuesPageCacheKey(owner, repo),
cacheType: "repo_issues_page",
@@ -3291,6 +3292,15 @@ export async function getRepoIssuesPage(owner: string, repo: string): Promise<Re
return fetchRepoIssuesPageGraphQL(authCtx.token, owner, repo);
},
});
if (authCtx) {
const { updateCachedRepoPageDataNavCounts } = await import("@/lib/repo-data-cache");
updateCachedRepoPageDataNavCounts(authCtx.userId, owner, repo, {
openIssues: data.openCount,
}).catch(() => {});
}
return data;
}
export async function invalidateRepoPullRequestsCache(owner: string, repo: string) {
@@ -3306,6 +3316,7 @@ export async function invalidateAllPRBundlesForRepo(owner: string, repo: string)
const key = normalizeRepoKey(owner, repo);
await deleteGithubCacheByPrefix(authCtx.userId, `pr_bundle:${key}`);
await deleteGithubCacheByPrefix(authCtx.userId, `pull_request:${key}`);
await deleteSharedCacheByPrefix(`pr_bundle:${key}`);
}
export async function invalidatePullRequestCache(owner: string, repo: string, pullNumber: number) {
@@ -3339,6 +3350,8 @@ export async function invalidatePullRequestCache(owner: string, repo: string, pu
authCtx.userId,
`search_issues:${keyPart(`is:pr is:closed repo:${owner}/${repo}`)}`,
);
// Also invalidate the shared cache so all users see the updated state
await deleteSharedCacheByPrefix(`pr_bundle:${key}:${pullNumber}`);
}
export async function invalidateFileContentCache(
@@ -3670,6 +3683,17 @@ export async function getRepoPullRequestsWithStats(
).map(mapGraphQLPRNode)
: [];
if (wantCounts) {
getGitHubAuthContext().then(async (authCtx) => {
if (!authCtx) return;
const { updateCachedRepoPageDataNavCounts } =
await import("@/lib/repo-data-cache");
updateCachedRepoPageDataNavCounts(authCtx.userId, owner, repo, {
openPrs: counts.open,
}).catch(() => {});
});
}
return { prs, pageInfo, counts, mergedPreview, closedPreview };
} catch (error) {
rethrowKnownGitHubErrors(error);
+1
View File
@@ -12,6 +12,7 @@ export {
getCachedOverviewEvents,
getCachedOverviewCommitActivity,
getCachedOverviewCI,
updateCachedRepoPageDataNavCounts,
type ContributorAvatarsData,
type BranchRef,
} from "./repo-data-cache";
+21
View File
@@ -124,6 +124,27 @@ export async function setCachedRepoPageData<T>(
});
}
export async function updateCachedRepoPageDataNavCounts(
userId: string,
owner: string,
repo: string,
updates: { openPrs?: number; openIssues?: number },
): Promise<void> {
const key = userRepoKey(userId, owner, repo, "repo_page_data");
const existing = await redis.get<{
navCounts?: { openPrs: number; openIssues: number; activeRuns: number };
}>(key);
if (!existing || !existing.navCounts) return;
const updatedNavCounts = {
...existing.navCounts,
...(updates.openPrs !== undefined && { openPrs: updates.openPrs }),
...(updates.openIssues !== undefined && { openIssues: updates.openIssues }),
};
await redis.set(key, { ...existing, navCounts: updatedNavCounts }, { ex: TTL.medium });
}
export async function getCachedRepoTree<T>(owner: string, repo: string): Promise<T | null> {
return redis.get<T>(repoKey(owner, repo, "repo_file_tree"));
}