Something went wrong. Try again.
csr tangled client in solid-js forked from ptr.pet/untangled
Something went wrong. Try again.
5.4 kB · 185 lines
TSX
at main
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186import { useQueryClient } from '../lib/atproto-query';import { useAuth } from './auth';import { getRepo, getRepoBranches, getRepoDefaultBranch, getRepoTags, getRepoForkCount, getRepoTree, getRepoLog, getRepoLanguages, type RepoContext,} from './api/repos';import { getIssue, getRepoIssueCount } from './api/issues';import { fetchPullRoundPatch, getPull, getRepoPullCount } from './api/pulls';import { getString } from './api/strings';import { getRepoStarSummary } from './api/stars';import { repoQueryKey, issueQueryKey, pullQueryKey, pullPatchQueryKey, issuesQueryKey, pullsQueryKey } from './api/keys';import { resolveDefaultBranchName } from '../pages/repo/code-helpers';
export const PRELOAD_HOVER_TIME = 30;
export const usePreloader = () => { const queryClient = useQueryClient();
return (queryKey: readonly unknown[], queryFn: () => Promise<any>, delayMs = PRELOAD_HOVER_TIME) => { let hoverTimer: ReturnType<typeof setTimeout> | undefined;
const onMouseEnter = () => { hoverTimer = setTimeout(() => { queryClient.prefetchQuery({ queryKey, queryFn }); }, delayMs); };
const onMouseLeave = () => { clearTimeout(hoverTimer); };
return { onMouseEnter, onMouseLeave }; };};
export const useRepoPreloader = () => { const queryClient = useQueryClient(); const auth = useAuth(); const preload = usePreloader();
return (owner: string, name: string) => { return preload( ['repo-prefetch', owner, name], async () => { const repo = await queryClient.fetchQuery({ queryKey: repoQueryKey(owner, name), queryFn: () => getRepo(owner, name), });
if (!repo) { return repo; }
const currentDid = auth.currentDid();
// Fetch branches and default-branch, and prefetch counts and tags concurrently const [branches, defaultBranchRes] = await Promise.all([ queryClient.fetchQuery({ queryKey: ['repo-branches', repo.repoDid], queryFn: () => getRepoBranches(repo), }), queryClient.fetchQuery({ queryKey: ['repo-default-branch', repo.repoDid], queryFn: () => getRepoDefaultBranch(repo), }), queryClient.prefetchQuery({ queryKey: ['repo-star-summary', repo.repoDid, currentDid], queryFn: () => getRepoStarSummary(repo, currentDid), }), queryClient.prefetchQuery({ queryKey: ['repo-fork-count', repo.repoDid], queryFn: () => getRepoForkCount(repo), }), queryClient.prefetchQuery({ queryKey: [...issuesQueryKey(repo.repoDid), 'count'], queryFn: () => getRepoIssueCount(repo), }), queryClient.prefetchQuery({ queryKey: [...pullsQueryKey(repo.repoDid), 'count'], queryFn: () => getRepoPullCount(repo), }), queryClient.prefetchQuery({ queryKey: ['repo-tags', repo.repoDid], queryFn: () => getRepoTags(repo), }), ]);
const defaultBranchName = defaultBranchRes?.name ?? defaultBranchRes?.branch ?? defaultBranchRes?.reference?.name ?? resolveDefaultBranchName(branches?.branches) ?? 'main';
// Now that we have the default branch name, prefetch tree, log and languages await Promise.all([ queryClient.prefetchQuery({ queryKey: ['repo-tree', repo.repoDid, defaultBranchName, ''], queryFn: async () => ({ tree: await getRepoTree(repo, defaultBranchName, ''), path: '', ref: defaultBranchName, }), }), queryClient.prefetchQuery({ queryKey: ['repo-log', repo.repoDid, defaultBranchName], queryFn: () => getRepoLog(repo, defaultBranchName), }), queryClient.prefetchQuery({ queryKey: ['repo-languages', repo.repoDid, defaultBranchName], queryFn: () => getRepoLanguages(repo, defaultBranchName), }), ]).catch(() => { // Ignore background prefetch errors });
return repo; } ); };};
export const useStringPreloader = () => { const preload = usePreloader(); return (actor: string, rkey: string) => { return preload(['string-detail', actor, rkey], () => getString(actor, rkey)); };};
export const useIssuePreloader = () => { const queryClient = useQueryClient(); const preload = usePreloader();
return ( repoLabel: string, kind: 'issue' | 'pull', uri: string, number?: string | number, repoContext?: RepoContext, ) => { const [owner, slug] = repoLabel.split('/'); const issueRef = String(number || uri.split('/').pop());
return preload( [kind, uri, 'prefetch'], async () => { const repo = repoContext || (await queryClient.fetchQuery({ queryKey: repoQueryKey(owner, slug), queryFn: () => getRepo(owner, slug), }));
if (!repo) { return; }
if (kind === 'issue') { await queryClient.prefetchQuery({ queryKey: issueQueryKey(repo.repoDid, issueRef), queryFn: () => getIssue(repo, issueRef), }); } else { const pullDetail = await queryClient.fetchQuery({ queryKey: pullQueryKey(repo.repoDid, issueRef), queryFn: () => getPull(repo, issueRef), });
const roundIndex = Math.max(0, pullDetail.pull.value.rounds.length - 1); await queryClient.prefetchQuery({ queryKey: pullPatchQueryKey(pullDetail.pull.uri, roundIndex), queryFn: () => fetchPullRoundPatch(pullDetail.pull, roundIndex), }); } }, ); };};