The rain's column maths and fade colour move from MatrixRain into shell/rain.ts, and the request-once swarm name loader from useSwarmName into shell/swarm-name.ts. Both are plain functions with their input passed in, so tests cover them; the components keep the DOM and canvas work.
28 lines
1,007 B
TypeScript
28 lines
1,007 B
TypeScript
// Loading the swarm's display name from `GET /api/swarm`, once. The header and
|
|
// the start page both ask for it and it does not change within a page visit,
|
|
// so the loader remembers the first request and every caller shares it. The
|
|
// label is cosmetic, so a failed request, an error response or an unconfigured
|
|
// name all answer `null` instead of throwing: callers fall back to their own
|
|
// default, as an operator who never set a name sees.
|
|
|
|
type Fetch = (url: string) => Promise<{
|
|
ok: boolean;
|
|
json: () => Promise<unknown>;
|
|
}>;
|
|
|
|
export function createSwarmNameLoader(
|
|
fetchImpl: Fetch,
|
|
): () => Promise<string | null> {
|
|
let pending: Promise<string | null> | null = null;
|
|
return () => {
|
|
if (pending === null) {
|
|
pending = (async () => {
|
|
const r = await fetchImpl("/api/swarm");
|
|
if (!r.ok) return null;
|
|
const data = (await r.json()) as { name?: string | null };
|
|
return data.name || null;
|
|
})().catch(() => null);
|
|
}
|
|
return pending;
|
|
};
|
|
}
|