Re-use project-level data when browsing source code

We make source code browsing faster by re-using project-level data when
navigating between files. This comes at a cost: Project info (like the
issue counter), remotes and branches are only updated when the page is
hard-refreshed or the user navigates away from the source code view.
This commit is contained in:
Thomas Scholtes
2024-02-28 14:15:58 +00:00
committed by Rūdolfs Ošiņš
parent dcced2e06d
commit 69429cb08f
3 changed files with 51 additions and 13 deletions
+3 -2
View File
@@ -1,7 +1,7 @@
import type { BaseUrl } from "@httpd-client";
import type { LoadedRoute, Route } from "@app/lib/router/definitions";
import { writable } from "svelte/store";
import { get, writable } from "svelte/store";
import * as mutexExecutor from "@app/lib/mutexExecutor";
import * as utils from "@app/lib/utils";
@@ -101,9 +101,10 @@ async function navigate(
window.history.replaceState(newRoute, "");
}
currentUrl = new URL(window.location.href);
const currentLoadedRoute = get(activeRouteStore);
const loadedRoute = await loadExecutor.run(async () => {
return loadRoute(newRoute);
return loadRoute(newRoute, currentLoadedRoute);
});
// Only let the last request through.
+5 -2
View File
@@ -62,7 +62,10 @@ export type LoadedRoute =
| NodesLoadedRoute
| SessionRoute;
export async function loadRoute(route: Route): Promise<LoadedRoute> {
export async function loadRoute(
route: Route,
previousLoaded: LoadedRoute,
): Promise<LoadedRoute> {
if (route.resource === "nodes") {
return await loadNodeRoute(route.params);
} else if (route.resource === "home") {
@@ -77,7 +80,7 @@ export async function loadRoute(route: Route): Promise<LoadedRoute> {
route.resource === "project.patches" ||
route.resource === "project.patch"
) {
return await loadProjectRoute(route);
return await loadProjectRoute(route, previousLoaded);
} else {
return route;
}
+43 -9
View File
@@ -1,4 +1,8 @@
import type { ErrorRoute, NotFoundRoute } from "@app/lib/router/definitions";
import type {
ErrorRoute,
LoadedRoute,
NotFoundRoute,
} from "@app/lib/router/definitions";
import type {
BaseUrl,
Blob,
@@ -254,6 +258,7 @@ async function isLocalNodeSeeding(route: ProjectRoute): Promise<boolean> {
export async function loadProjectRoute(
route: ProjectRoute,
previousLoaded: LoadedRoute,
): Promise<ProjectLoadedRoute | ErrorRoute | NotFoundRoute> {
const api = new HttpdClient(route.node);
const rawPath = (commit?: string) =>
@@ -263,7 +268,7 @@ export async function loadProjectRoute(
try {
if (route.resource === "project.source") {
return await loadTreeView(route);
return await loadTreeView(route, previousLoaded);
} else if (route.resource === "project.history") {
return await loadHistoryView(route);
} else if (route.resource === "project.commit") {
@@ -374,20 +379,49 @@ async function loadIssuesView(
async function loadTreeView(
route: ProjectTreeRoute,
): Promise<ProjectLoadedRoute> {
previousLoaded: LoadedRoute,
): Promise<ProjectLoadedRoute | NotFoundRoute> {
const api = new HttpdClient(route.node);
const rawPath = (commit?: string) =>
`${route.node.scheme}://${route.node.hostname}:${route.node.port}/raw/${
route.project
}${commit ? `/${commit}` : ""}`;
const [project, peers, branchMap, seeding] = await Promise.all([
api.project.getById(route.project),
api.project.getAllRemotes(route.project),
getPeerBranches(api, route.project, route.peer),
let projectPromise: Promise<Project>;
let peersPromise: Promise<Remote[]>;
if (
previousLoaded.resource === "project.source" &&
previousLoaded.params.project.id === route.project &&
previousLoaded.params.peer === route.peer
) {
projectPromise = Promise.resolve(previousLoaded.params.project);
peersPromise = Promise.resolve(previousLoaded.params.peers);
} else {
projectPromise = api.project.getById(route.project);
peersPromise = api.project.getAllRemotes(route.project);
}
const [project, peers, seeding] = await Promise.all([
projectPromise,
peersPromise,
isLocalNodeSeeding(route),
]);
let branchMap: Record<string, string>;
if (route.peer) {
const peer = peers.find(peer => peer.id === route.peer);
if (!peer) {
return {
resource: "notFound",
params: { title: `Peer ${route.peer} could not be found` },
};
} else {
branchMap = peer.heads;
}
} else {
branchMap = { [project.defaultBranch]: project.head };
}
if (route.route) {
const { revision, path } = detectRevision(
route.route,
@@ -400,7 +434,7 @@ async function loadTreeView(
const commit = parseRevisionToOid(
route.revision,
project.defaultBranch,
branchMap || { [project.defaultBranch]: project.head },
branchMap,
);
const path = route.path || "/";
@@ -416,7 +450,7 @@ async function loadTreeView(
project,
peers,
peer: route.peer,
branches: Object.keys(branchMap || {}),
branches: Object.keys(branchMap),
rawPath,
revision: route.revision,
tree,