mirror of
https://seed.radicle.dev/rad:z4V1sjrXqjvFdnCUbxPFqd5p4DtH5.git
synced 2026-11-15 19:30:38 +08:00
Decouple stats from tree endpoint response
This commit is contained in:
@@ -6,6 +6,7 @@ import type {
|
||||
ProjectListQuery,
|
||||
Remote,
|
||||
Tree,
|
||||
TreeStats,
|
||||
} from "./lib/project.js";
|
||||
import type {
|
||||
SuccessResponse,
|
||||
@@ -82,6 +83,7 @@ export type {
|
||||
Review,
|
||||
Revision,
|
||||
Scope,
|
||||
TreeStats,
|
||||
Tree,
|
||||
Verdict,
|
||||
};
|
||||
|
||||
+30
-10
@@ -102,11 +102,13 @@ const treeEntrySchema = object({
|
||||
|
||||
export type TreeEntry = z.infer<typeof treeEntrySchema>;
|
||||
|
||||
export interface TreeStats {
|
||||
commits: number;
|
||||
branches: number;
|
||||
contributors: number;
|
||||
}
|
||||
const treeStatsSchema = object({
|
||||
commits: number(),
|
||||
branches: number(),
|
||||
contributors: number(),
|
||||
});
|
||||
|
||||
export type TreeStats = z.infer<typeof treeStatsSchema>;
|
||||
|
||||
export type Tree = z.infer<typeof treeSchema>;
|
||||
|
||||
@@ -115,11 +117,6 @@ const treeSchema = object({
|
||||
lastCommit: commitHeaderSchema,
|
||||
name: string(),
|
||||
path: string(),
|
||||
stats: object({
|
||||
commits: number(),
|
||||
branches: number(),
|
||||
contributors: number(),
|
||||
}),
|
||||
});
|
||||
|
||||
export type Remote = z.infer<typeof remoteSchema>;
|
||||
@@ -153,6 +150,7 @@ export class Client {
|
||||
// persisted and new instances are frequently created.
|
||||
static #cache = {
|
||||
tree: new LRUCache<string, Tree>({ max: 300 }),
|
||||
stats: new LRUCache<string, TreeStats>({ max: 300 }),
|
||||
blob: new LRUCache<string, Blob>({ max: 500 }),
|
||||
};
|
||||
|
||||
@@ -275,6 +273,28 @@ export class Client {
|
||||
return tree;
|
||||
}
|
||||
|
||||
public async getTreeStatsBySha(
|
||||
id: string,
|
||||
sha: string,
|
||||
options?: RequestOptions,
|
||||
): Promise<TreeStats> {
|
||||
const cacheKey = `tree:stats:${sha}`;
|
||||
const cachedTree = Client.#cache.stats.get(cacheKey);
|
||||
if (cachedTree) {
|
||||
return cachedTree;
|
||||
}
|
||||
const tree = await this.#fetcher.fetchOk(
|
||||
{
|
||||
method: "GET",
|
||||
path: `projects/${id}/stats/tree/${sha}`,
|
||||
options,
|
||||
},
|
||||
treeStatsSchema,
|
||||
);
|
||||
Client.#cache.stats.set(cacheKey, tree);
|
||||
return tree;
|
||||
}
|
||||
|
||||
public async getAllRemotes(
|
||||
id: string,
|
||||
options?: RequestOptions,
|
||||
|
||||
@@ -236,11 +236,4 @@ const commitSchema = object({
|
||||
|
||||
type Commits = z.infer<typeof commitsSchema>;
|
||||
|
||||
const commitsSchema = object({
|
||||
commits: array(commitHeaderSchema),
|
||||
stats: object({
|
||||
commits: number(),
|
||||
branches: number(),
|
||||
contributors: number(),
|
||||
}),
|
||||
});
|
||||
const commitsSchema = array(commitHeaderSchema);
|
||||
|
||||
@@ -53,6 +53,10 @@ describe("project", () => {
|
||||
await api.project.getTree(sourceBrowsingRid, aliceMainHead);
|
||||
});
|
||||
|
||||
test("#getTreeStats(id, sha)", async () => {
|
||||
await api.project.getTreeStatsBySha(sourceBrowsingRid, aliceMainHead);
|
||||
});
|
||||
|
||||
test("#getTree(id, sha, path)", async () => {
|
||||
await api.project.getTree(sourceBrowsingRid, aliceMainHead, "src");
|
||||
});
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
Project,
|
||||
Remote,
|
||||
Tree,
|
||||
TreeStats,
|
||||
} from "@httpd-client";
|
||||
import type { Route } from "@app/lib/router";
|
||||
|
||||
@@ -29,8 +30,8 @@
|
||||
export let peers: Remote[];
|
||||
export let project: Project;
|
||||
export let revision: string | undefined;
|
||||
export let totalCommitCount: number;
|
||||
export let tree: Tree;
|
||||
export let stats: TreeStats;
|
||||
export let seeding: boolean;
|
||||
|
||||
const api = new HttpdClient(baseUrl);
|
||||
@@ -54,8 +55,7 @@
|
||||
page,
|
||||
perPage: COMMITS_PER_PAGE,
|
||||
});
|
||||
allCommitHeaders = response.commits;
|
||||
totalCommitCount = response.stats.commits;
|
||||
allCommitHeaders = response;
|
||||
} catch (e) {
|
||||
error = e;
|
||||
}
|
||||
@@ -117,6 +117,7 @@
|
||||
branches={branchesWithRoute}
|
||||
{revision}
|
||||
{tree}
|
||||
{stats}
|
||||
filesLinkActive={false}
|
||||
historyLinkActive={true} />
|
||||
</div>
|
||||
@@ -135,11 +136,11 @@
|
||||
{/each}
|
||||
</div>
|
||||
|
||||
{#if loading || allCommitHeaders.length < totalCommitCount}
|
||||
{#if loading || allCommitHeaders.length < stats.commits}
|
||||
<div class="more">
|
||||
{#if loading}
|
||||
<Loading small={page !== 0} center />
|
||||
{:else if allCommitHeaders.length < totalCommitCount}
|
||||
{:else if allCommitHeaders.length < stats.commits}
|
||||
<Button size="large" variant="outline" on:click={loadMore}>More</Button>
|
||||
{/if}
|
||||
</div>
|
||||
|
||||
@@ -1,5 +1,11 @@
|
||||
<script lang="ts">
|
||||
import type { BaseUrl, Project, Remote, Tree } from "@httpd-client";
|
||||
import type {
|
||||
BaseUrl,
|
||||
Project,
|
||||
Remote,
|
||||
Tree,
|
||||
TreeStats,
|
||||
} from "@httpd-client";
|
||||
import type { BlobResult } from "./router";
|
||||
import type { Route } from "@app/lib/router";
|
||||
|
||||
@@ -24,6 +30,7 @@
|
||||
export let project: Project;
|
||||
export let revision: string | undefined;
|
||||
export let tree: Tree;
|
||||
export let stats: TreeStats;
|
||||
export let seeding: boolean;
|
||||
|
||||
let mobileFileTree = false;
|
||||
@@ -125,6 +132,7 @@
|
||||
branches={branchesWithRoute}
|
||||
{revision}
|
||||
{tree}
|
||||
{stats}
|
||||
filesLinkActive={true}
|
||||
historyLinkActive={false} />
|
||||
</div>
|
||||
|
||||
@@ -1,5 +1,11 @@
|
||||
<script lang="ts">
|
||||
import type { BaseUrl, Project, Remote, Tree } from "@httpd-client";
|
||||
import type {
|
||||
BaseUrl,
|
||||
Project,
|
||||
Remote,
|
||||
Tree,
|
||||
TreeStats,
|
||||
} from "@httpd-client";
|
||||
import { type Route } from "@app/lib/router";
|
||||
|
||||
import BranchSelector from "./BranchSelector.svelte";
|
||||
@@ -16,6 +22,7 @@
|
||||
export let historyLinkActive: boolean;
|
||||
export let revision: string | undefined;
|
||||
export let tree: Tree;
|
||||
export let stats: TreeStats;
|
||||
export let project: Project;
|
||||
|
||||
let selectedBranch: string | undefined;
|
||||
@@ -121,7 +128,7 @@
|
||||
<div class="title-counter">
|
||||
Commits
|
||||
<div class="counter" class:selected={historyLinkActive}>
|
||||
{tree.stats.commits}
|
||||
{stats.commits}
|
||||
</div>
|
||||
</div>
|
||||
</Button>
|
||||
|
||||
@@ -18,6 +18,7 @@ import type {
|
||||
Project,
|
||||
Remote,
|
||||
Tree,
|
||||
TreeStats,
|
||||
} from "@httpd-client";
|
||||
|
||||
import * as Syntax from "@app/lib/syntax";
|
||||
@@ -117,6 +118,7 @@ export type ProjectLoadedRoute =
|
||||
branches: string[];
|
||||
revision: string | undefined;
|
||||
tree: Tree;
|
||||
stats: TreeStats;
|
||||
path: string;
|
||||
rawPath: (commit?: string) => string;
|
||||
blobResult: BlobResult;
|
||||
@@ -133,8 +135,8 @@ export type ProjectLoadedRoute =
|
||||
branches: string[];
|
||||
revision: string | undefined;
|
||||
tree: Tree;
|
||||
stats: TreeStats;
|
||||
commitHeaders: CommitHeader[];
|
||||
totalCommitCount: number;
|
||||
seeding: boolean;
|
||||
};
|
||||
}
|
||||
@@ -443,6 +445,8 @@ async function loadTreeView(
|
||||
branchMap,
|
||||
);
|
||||
|
||||
const stats = await api.project.getTreeStatsBySha(route.project, commit);
|
||||
|
||||
const path = route.path || "/";
|
||||
|
||||
const [tree, blobResult] = await Promise.all([
|
||||
@@ -460,6 +464,7 @@ async function loadTreeView(
|
||||
rawPath,
|
||||
revision: route.revision,
|
||||
tree,
|
||||
stats,
|
||||
path,
|
||||
blobResult,
|
||||
seeding,
|
||||
@@ -533,8 +538,9 @@ async function loadHistoryView(
|
||||
);
|
||||
}
|
||||
|
||||
const [tree, commitsResponse, seeding] = await Promise.all([
|
||||
const [tree, stats, commitHeaders, seeding] = await Promise.all([
|
||||
api.project.getTree(route.project, commitId),
|
||||
api.project.getTreeStatsBySha(route.project, commitId),
|
||||
await api.project.getAllCommits(project.id, {
|
||||
parent: commitId,
|
||||
page: 0,
|
||||
@@ -553,8 +559,8 @@ async function loadHistoryView(
|
||||
branches: Object.keys(branchMap || {}),
|
||||
revision: route.revision,
|
||||
tree,
|
||||
commitHeaders: commitsResponse.commits,
|
||||
totalCommitCount: commitsResponse.stats.commits,
|
||||
stats,
|
||||
commitHeaders,
|
||||
seeding,
|
||||
},
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user