diff --git a/.changeset/slimy-eyes-kneel.md b/.changeset/slimy-eyes-kneel.md
new file mode 100644
index 0000000..373abe1
--- /dev/null
+++ b/.changeset/slimy-eyes-kneel.md
@@ -0,0 +1,5 @@
+---
+"neogrok": minor
+---
+
+Enhance the repositories list page, making it more performant on instances with large numbers of repositories, and make columns sortable by clicking on their headers
diff --git a/src/lib/server/zoekt-list-repositories.ts b/src/lib/server/zoekt-list-repositories.ts
index 8ba8f89..967e2d6 100644
--- a/src/lib/server/zoekt-list-repositories.ts
+++ b/src/lib/server/zoekt-list-repositories.ts
@@ -47,15 +47,18 @@ export async function listRepositories(
const statsSchema = v
.object({
+ Shards: v.number(),
Documents: v.number(),
IndexBytes: v.number(),
ContentBytes: v.number(),
})
- .map(({ Documents, IndexBytes, ContentBytes }) => ({
+ .map(({ Shards, Documents, IndexBytes, ContentBytes }) => ({
+ shardCount: Shards,
fileCount: Documents,
indexBytes: IndexBytes,
contentBytes: ContentBytes,
}));
+export type RepoStats = v.Infer;
const dateSchema = v.string().chain((str) => {
const date = new Date(str);
@@ -125,10 +128,10 @@ const listResultSchema = v.object({
})),
Stats: statsSchema,
})
- .map(({ Repository, IndexMetadata: { lastIndexed }, Stats }) => ({
+ .map(({ Repository, IndexMetadata, Stats }) => ({
...Repository,
- lastIndexed,
- stats: Stats,
+ ...IndexMetadata,
+ ...Stats,
})),
),
)
@@ -147,7 +150,5 @@ const listResultSchema = v.object({
const toISOStringWithoutMs = (d: Date) =>
d.toISOString().replace(/\.\d{3}Z$/, "Z");
-export type ListResults = ReadonlyDeep<
- v.Infer["List"]
->;
+export type ListResults = v.Infer["List"];
export type Repository = ListResults["repositories"][number];
diff --git a/src/routes/about/+page.svelte b/src/routes/about/+page.svelte
index 22516e8..a1903bf 100644
--- a/src/routes/about/+page.svelte
+++ b/src/routes/about/+page.svelte
@@ -107,20 +107,56 @@
the repositories indexed in the backing zoekt instance, including a variety
of data about them.
-
- Note that the search input on this page has the same semantics as the
- search input on the main search page: you are writing a full zoekt query, but instead of getting normal search results, you get repositories that
- contain any results matching the query. So, filters the table to repositories with "linux" in their name, while filters the table to repositories with linux in their
- contents.
-
+
+ Repository search
+
+ Note that the search input on this page has the same semantics as the
+ search input on the main search page: you are writing a full zoekt query, but instead of getting normal search results, you get repositories
+ that contain any results matching the query. So, filters the table to repositories with "linux" in their name, while filters the table to repositories with linux in their
+ contents.
+
+
+ To improve page performance on deployments with large numbers of
+ repositories, there is a repos input that limits the number of
+ displayed repositories in the same way that the files and
+ matches inputs on the search page do.
+
+
+
+ Repository stats
+
+ The tabulated data includes links to the repository and its indexed
+ branches, the times the repository was last indexed and that it was last
+ committed to, and data about the index shards and their contents.
+ The table can be sorted by clicking on column headers: the first click will
+ sort in ascending order, the second in descending, and the third will restore
+ the status quo.
+
+
+ Shards are what zoekt calls the files emitted from its indexer, and
+ they're all that's used by the zoekt-webserver backing neogrok to handle
+ neogrok's API requests; they contain the above-described repository metadata,
+ indexes used to quickly search repository content, and the repository content
+ itself (file names and contents). Indexing a repository typically results
+ in a single shard, but zoekt limits shard files to be about 100MiB in size,
+ so big repositories get more than one shard.
+
+
+ When you search repository contents (i.e. make a non-repo:
+ query), are in fact searching repository shards, and so for a
+ repository with more than one shard, you will see that the counts of
+ shards and associated data in the table go down when you enter a query
+ that matches content in only some of its shards.
+