From 088372a821bcea806982818df9751e60012f23ff Mon Sep 17 00:00:00 2001 From: "nekomimi.pet" Date: Sat, 1 Aug 2026 19:03:21 -0400 Subject: [PATCH] fetch only recent open issues and pulls for watched repos so large repositories load --- src/lib/api/issues.ts | 18 ++++++++++++++++++ src/lib/api/pulls.ts | 16 ++++++++++++++++ src/pages/watching.tsx | 16 ++++++++++------ 3 files changed, 44 insertions(+), 6 deletions(-) diff --git a/src/lib/api/issues.ts b/src/lib/api/issues.ts index a5fc126..986b969 100644 --- a/src/lib/api/issues.ts +++ b/src/lib/api/issues.ts @@ -300,6 +300,24 @@ export const listIssues = async (repo: RepoContext): Promise => () => listIssuesFromBacklinks(repo), ); +// Dashboard surfaces only need the newest few open issues. Skipping the +// updated-at sort keeps pagination incremental so large repositories do not +// require hydrating and state-resolving every issue. +export const listRecentOpenIssues = async ( + repo: RepoContext, + limit: number, +): Promise => { + const page = await listBacklinkedRecordsPage( + repo.repoDid, + ['sh.tangled.repo.issue:repoDid', 'sh.tangled.repo.issue:repo'], + { offset: 0, limit, state: 'open' }, + getLatestIssueState, + undefined, + hydrateIssueBacklinks, + ); + return page.items; +}; + export const listIssuesPage = async ( repo: RepoContext, options: StatefulPageOptions<'open' | 'closed'>, diff --git a/src/lib/api/pulls.ts b/src/lib/api/pulls.ts index c5c0f61..176b7b5 100644 --- a/src/lib/api/pulls.ts +++ b/src/lib/api/pulls.ts @@ -323,6 +323,22 @@ export const listPulls = async (repo: RepoContext): Promise => () => listPullsFromBacklinks(repo), ); +// See listRecentOpenIssues: incremental pagination for dashboard summaries. +export const listRecentOpenPulls = async ( + repo: RepoContext, + limit: number, +): Promise => { + const page = await listBacklinkedRecordsPage( + repo.repoDid, + 'sh.tangled.repo.pull:target.repo', + { offset: 0, limit, state: 'open' }, + getLatestPullStatus, + undefined, + hydratePullBacklinks, + ); + return page.items; +}; + export const listPullsPage = async ( repo: RepoContext, options: StatefulPageOptions<'open' | 'closed' | 'merged'>, diff --git a/src/pages/watching.tsx b/src/pages/watching.tsx index 2842a53..c13de50 100644 --- a/src/pages/watching.tsx +++ b/src/pages/watching.tsx @@ -4,8 +4,8 @@ import { For, Show, createEffect, createMemo, createSignal, onCleanup, type Comp import { ErrorState } from '../components/common'; import { getRepoDefaultBranch, getRepoByUri, getRepoLog, type CommitEntry, type GitHashValue, type RepoContext } from '../lib/api/repos'; -import { listIssues, type IssueSummary } from '../lib/api/issues'; -import { listPulls, type PullSummary } from '../lib/api/pulls'; +import { listRecentOpenIssues, type IssueSummary } from '../lib/api/issues'; +import { listRecentOpenPulls, type PullSummary } from '../lib/api/pulls'; import { listWatchRecords, type WatchRecord } from '../lib/api/watches'; import { useAuth } from '../lib/auth'; import { createQuery, useQueryClient } from '../lib/atproto-query'; @@ -30,22 +30,26 @@ const commitDate = (commit: CommitEntry): string | undefined => commit.author?.W const commitMessage = (message: string): string => message.split('\n')[0]?.trim() || 'untitled commit'; +const WATCHED_WORK_LIMIT = 3; + const loadWatchedRepo = async (watch: WatchRecord): Promise => { try { const repo = await getRepoByUri(watch.value.repo); const branch = await getRepoDefaultBranch(repo).catch(() => undefined); const ref = branch?.name ?? branch?.branch ?? branch?.reference?.name ?? 'HEAD'; + // Only the newest few open items are shown, so page the APIs instead of + // listing every issue and pull request in the repository. const [issues, pulls, log] = await Promise.all([ - listIssues(repo).catch(() => []), - listPulls(repo).catch(() => []), + listRecentOpenIssues(repo, WATCHED_WORK_LIMIT).catch(() => []), + listRecentOpenPulls(repo, WATCHED_WORK_LIMIT).catch(() => []), getRepoLog(repo, ref, { limit: 30 }).catch(() => ({ commits: [] } as { commits: CommitEntry[] })), ]); return { watch, repo, - issues: issues.filter((issue) => issue.state === 'open'), - pulls: pulls.filter((pull) => pull.state === 'open'), + issues, + pulls, commits: log.commits.slice(0, 30), }; } catch { -- 2.51.2