johnandersen777.bsky.social/knotless
git that lives in your Atmosphere account
Forked from chadtmiller.com/knotless
0
0
import type * as listRepos from '#lib/lexicons/dev/knotless/listRepos.ts';
import type * as searchCode from '#lib/lexicons/dev/knotless/searchCode.ts';
import type * as searchOwners from '#lib/lexicons/dev/knotless/searchOwners.ts';
import type { Answer } from '#lib/data.ts';
import type { PageLoad } from './$types';
import { xrpc } from '#lib/data.ts';
/** What a code search found, or why it found nothing. */
export type CodeFound =
| { kind: 'found'; answer: Answer<typeof searchCode.main> }
| { kind: 'off' }
| { kind: 'bad'; message: string }
| { kind: 'missing'; repo: string }
| { kind: 'none' };
/** `repo:owner/name` in a query, which searches that repository's code alone. */
const REPO = /(?:^|\s)repo:(\S+?)\/(\S+)(?=\s|$)/;
/**
* What the results page shows of `q`: its code, with `type=code`, else
* the repositories that match it, or every one, newest first, those about
* `topic` alone when one is named, and the owners whose handles hold it.
* Code is searched in one repository when `q` names it as
* `repo:owner/name`. None of either, without an index. Each kind is
* counted, for a search, by asking for the other kind too.
*/
export const load: PageLoad = async (event) => {
const q = (event.url.searchParams.get('q') ?? '').trim();
const topic = (event.url.searchParams.get('topic') ?? '').trim() || undefined;
const type = event.url.searchParams.get('type') === 'code' ? 'code' : 'repositories';
// The page is cached as the repositories are.
const quiet = { ...event, setHeaders: () => {} };
// Each kind's count beside it, for a search: the other kind asked too.
// Repositories are asked for with the words alone, not a code search's `lang:`.
const words = type === 'code' ? q.replace(/(^|\s)-?lang:("[^"]*"|\S+)/g, ' ').trim() : q;
const listed = (e: typeof event) =>
words || type === 'repositories'
? xrpc<typeof listRepos.main>(e, 'dev.knotless.listRepos', { q: words, topic }, true)
: null;
if (type === 'code') {
const cursor = event.url.searchParams.get('cursor') ?? undefined;
const [found, repos] = await Promise.all([
code(event, q, undefined, cursor),
REPO.test(q) ? null : listed(quiet)
]);
const counts = {
code: found.kind === 'found' ? found.answer.fileCount : undefined,
...reposCounted(repos)
};
return { query: q, topic, type, code: found, counts, repos: [], owners: [], indexed: true };
}
const [found, owners, files] = await Promise.all([
listed(event),
q ? xrpc<typeof searchOwners.main>(quiet, 'dev.knotless.searchOwners', { q }, true) : null,
q && !topic ? code(quiet, q, 1) : null
]);
// Each with its owner, as the list shows it; whose fork it is, it does not.
const repos =
found?.repos.flatMap(({ forkOf: _, owner, ...r }) => (owner ? [{ ...r, owner }] : [])) ?? [];
const none: CodeFound = { kind: 'none' };
const counts = {
code: files?.kind === 'found' ? files.answer.fileCount : undefined,
...(q ? reposCounted(found) : {})
};
return {
query: q,
topic,
type,
code: none,
counts,
repos,
owners: owners?.owners ?? [],
indexed: found !== null
};
};
/** How many repositories a page of them counts, `more` when there are others after it. */
function reposCounted(found: Answer<typeof listRepos.main> | null) {
return found ? { repos: found.repos.length, more: found.cursor !== undefined } : {};
}
/**
* The code `q` finds, after the files `cursor` says the pages before
* held: asked here rather than by `xrpc`, as a query Zoekt
* cannot read, or a server that searches no code, is said on the page
* rather than failing it.
*/
async function code(
event: Parameters<PageLoad>[0],
q: string,
limit?: number,
cursor?: string
): Promise<CodeFound> {
const named = REPO.exec(q);
const rest = named ? q.replace(named[0], ' ').trim() : q;
if (!rest) return { kind: 'none' };
const params = new URLSearchParams({ q: rest });
if (named) params.set('repo', `at://${named[1]}/dev.knotless.repo/${named[2]}`);
if (limit) params.set('limit', String(limit));
if (cursor) params.set('cursor', cursor);
const res = await event.fetch(`/xrpc/dev.knotless.searchCode?${params}`, { cache: 'no-cache' });
if (res.ok) return { kind: 'found', answer: await res.json() };
if (res.status === 501) return { kind: 'off' };
// The repository `repo:` names is no one's.
if (res.status === 404 && named) return { kind: 'missing', repo: `${named[1]}/${named[2]}` };
const failure: { message?: string } | null = await res.json().catch(() => null);
return { kind: 'bad', message: failure?.message ?? res.statusText };
}