Skip to content
40 linesCodeBlameRaw
1/**
2 * Each entry's last commit for the file list, waited on only so long. An
3 * answer not yet kept walks history, which can take seconds on a large or
4 * busy repository; the page goes out without it then, the column empty,
5 * while the walk finishes in the background (waitUntil) so the next view
6 * has it from the cache. A history too long for one walk is read over
7 * several views: the repos service keeps each walk's progress and goes on
8 * from it (services/repos/src/last_commits.rs). The page's stream never
9 * waits on it past its own timeout.
10 */
11import { waitUntil } from "cloudflare:workers";
12
13import type { RepoPath, Viewer } from "@g1t/contracts";
14
15import type { FileCommits } from "./commit-people";
16import { repos } from "./services.server";
17
18/** How long the page waits for the column. */
19const WAIT_MS = 3_000;
20
21export function lastCommitsFor(path: RepoPath, viewer: Viewer, ref: string | null, treePath: string): Promise<FileCommits | null> {
22 const walk = repos
23 .lastCommits(path, viewer, ref, treePath)
24 // The rows show a commit's subject and age, never who made it: their
25 // addresses stay on the server.
26 .then((found): FileCommits | null =>
27 found.ok
28 ? {
29 complete: found.value.complete,
30 entries: found.value.entries.map(({ name, commit }) => ({
31 name,
32 commit: { hash: commit.hash, message: commit.message, authoredAt: commit.authoredAt },
33 })),
34 }
35 : null,
36 )
37 .catch(() => null);
38 waitUntil(walk);
39 return Promise.race([walk, new Promise<null>((resolve) => setTimeout(() => resolve(null), WAIT_MS))]);
40}