Radish alpha
r
Radicle web interface
Radicle
Git (anonymous pull)
Log in to clone via SSH
Decouple stats from tree endpoint response
Sebastian Martinez committed 2 years ago
commit 70b16e58619eb21ca64210dd54965d1f35d0c56a
parent eef0c1b0c75cf253695df1d06cc4ad60c7965b82
8 files changed +71 -30
modified httpd-client/index.ts
@@ -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,
};
modified httpd-client/lib/project.ts
@@ -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,
modified httpd-client/lib/project/commit.ts
@@ -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);
modified httpd-client/tests/project.test.ts
@@ -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");
  });
modified src/views/projects/History.svelte
@@ -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>
modified src/views/projects/Source.svelte
@@ -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>
modified src/views/projects/Source/Header.svelte
@@ -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>
modified src/views/projects/router.ts
@@ -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,
    },
  };