37 lines · 1.3 KB
import { useEffect, useState } from "react";
import { getLastCommits } from "~/fns/code";
import type { CommitBrief } from "~/lib/code-intel";

const MAX_CONTINUATIONS = 40;
const CONTINUE_DELAY_MS = 250;

export type LastCommitsState = { commits: Record<string, CommitBrief | null>; complete: boolean } | null;

/**
 * Lazily loads the latest commit per directory entry after the tree renders. The server walks
 * history in bounded chunks, so this keeps asking until every entry resolves or the cap is hit.
 */
export function useLastCommits(owner: string, repo: string, sha: string, path: string): LastCommitsState {
  const [state, setState] = useState<LastCommitsState>(null);
  useEffect(() => {
    let cancelled = false;
    setState(null);
    async function load() {
      for (let attempt = 0; attempt <= MAX_CONTINUATIONS && !cancelled; attempt++) {
        const page = await getLastCommits({ data: { owner, repo, ref: sha, path } });
        if (cancelled) return;
        setState(page);
        if (page.complete) return;
        await new Promise((resolve) => setTimeout(resolve, CONTINUE_DELAY_MS));
      }
    }
    load().catch(() => {
      if (!cancelled) setState({ commits: {}, complete: true });
    });
    return () => {
      cancelled = true;
    };
  }, [owner, repo, sha, path]);
  return state;
}