Optimize bunker connections on mobile

This commit is contained in:
dtonon 2026-09-19 17:49:45 +02:00
parent 0f487eb33a
commit d4e644a964
14 changed files with 343 additions and 124 deletions

View file

@ -4,8 +4,12 @@ import { snapshot, type ForumShell } from "$lib/forum/snapshot";
export const ssr = SSR_ENABLED;
// Runs for every page, so the cache policy for rendered HTML is set here.
// Runs for every page, so the cache policy for rendered HTML is set here. A
// page rendered without its shell (relay down or refusing anonymous reads) is
// an empty placeholder the client fills in, not worth keeping in a shared cache.
export async function load({ fetch, setHeaders }) {
if (!browser) setHeaders({ "cache-control": CACHE_CONTROL });
return { shell: await snapshot<ForumShell>(fetch, "/api/shell") };
const shell = await snapshot<ForumShell>(fetch, "/api/shell");
if (!browser)
setHeaders({ "cache-control": shell ? CACHE_CONTROL : "no-store" });
return { shell };
}

View file

@ -1,11 +1,11 @@
import { json } from "@sveltejs/kit";
import { CACHE_CONTROL } from "$lib/config";
import { fetchProfiles } from "$lib/forum/profiles";
import { snapshotHandler } from "$lib/ssr/endpoint";
import { loadShell } from "$lib/ssr/shell";
import { profileQuery } from "$lib/ssr/relay";
import type { RequestHandler } from "./$types";
export async function GET({ setHeaders }) {
setHeaders({ "cache-control": CACHE_CONTROL });
export const GET: RequestHandler = snapshotHandler(async () => {
const shell = await loadShell();
return json({ profiles: await fetchProfiles(profileQuery, shell.admins) });
}
});

View file

@ -1,15 +1,16 @@
import { json } from "@sveltejs/kit";
import { MODE, GROUP_ID, CACHE_CONTROL } from "$lib/config";
import { MODE, GROUP_ID } from "$lib/config";
import { fetchGroups } from "$lib/forum/groups";
import { fetchOverview, overviewPubkeys } from "$lib/forum/overview";
import { fetchProfiles } from "$lib/forum/profiles";
import type { OverviewSnapshot } from "$lib/forum/snapshot";
import { snapshotHandler } from "$lib/ssr/endpoint";
import { forumQuery, profileQuery } from "$lib/ssr/relay";
import type { RequestHandler } from "./$types";
// Room activity and the latest discussions: every room in full mode, the
// single group in simple mode (mirrors LatestDiscussions' own room set).
export async function GET({ setHeaders }) {
setHeaders({ "cache-control": CACHE_CONTROL });
export const GET: RequestHandler = snapshotHandler(async () => {
const roomIds =
MODE === "full"
? (await fetchGroups(forumQuery)).map((g) => g.id)
@ -18,4 +19,4 @@ export async function GET({ setHeaders }) {
const profiles = await fetchProfiles(profileQuery, overviewPubkeys(overview));
const body: OverviewSnapshot = { roomIds, ...overview, profiles };
return json(body);
}
});

View file

@ -1,11 +1,12 @@
import { error, json } from "@sveltejs/kit";
import { CACHE_CONTROL, GROUP_ID, MODE } from "$lib/config";
import { GROUP_ID, MODE } from "$lib/config";
import { decodeProfileId, fetchProfiles } from "$lib/forum/profiles";
import { fetchUserPosts } from "$lib/forum/userPosts";
import { snapshotHandler } from "$lib/ssr/endpoint";
import { forumQuery, profileQuery } from "$lib/ssr/relay";
import type { RequestHandler } from "./$types";
export async function GET({ params, setHeaders }) {
setHeaders({ "cache-control": CACHE_CONTROL });
export const GET: RequestHandler = snapshotHandler(async ({ params }) => {
const pubkey = decodeProfileId(params.id);
if (!pubkey) error(404, "Not found");
const [profiles, posts] = await Promise.all([
@ -17,4 +18,4 @@ export async function GET({ params, setHeaders }) {
),
]);
return json({ pubkey, posts, profiles });
}
});

View file

@ -1,8 +1,8 @@
import { json } from "@sveltejs/kit";
import { CACHE_CONTROL } from "$lib/config";
import { snapshotHandler } from "$lib/ssr/endpoint";
import { loadShell } from "$lib/ssr/shell";
import type { RequestHandler } from "./$types";
export async function GET({ setHeaders }) {
setHeaders({ "cache-control": CACHE_CONTROL });
return json(await loadShell());
}
export const GET: RequestHandler = snapshotHandler(async () =>
json(await loadShell()),
);

View file

@ -1,14 +1,15 @@
import { error, json } from "@sveltejs/kit";
import { GROUP_ID, CACHE_CONTROL } from "$lib/config";
import { GROUP_ID } from "$lib/config";
import { fetchThread, threadAuthors } from "$lib/forum/thread";
import { fetchProfiles } from "$lib/forum/profiles";
import { snapshotHandler } from "$lib/ssr/endpoint";
import { forumQuery, profileQuery } from "$lib/ssr/relay";
import type { RequestHandler } from "./$types";
export async function GET({ params, setHeaders }) {
setHeaders({ "cache-control": CACHE_CONTROL });
export const GET: RequestHandler = snapshotHandler(async ({ params }) => {
if (!/^[0-9a-f]{64}$/.test(params.id)) error(404, "Not found");
const thread = await fetchThread(forumQuery, params.id, GROUP_ID);
if (!thread) error(404, "Not found");
const profiles = await fetchProfiles(profileQuery, threadAuthors(thread));
return json({ thread, profiles });
}
});

View file

@ -1,5 +1,5 @@
import { error, json } from "@sveltejs/kit";
import { MODE, GROUP_ID, CACHE_CONTROL } from "$lib/config";
import { MODE, GROUP_ID } from "$lib/config";
import { fetchGroups } from "$lib/forum/groups";
import {
fetchThreadPage,
@ -8,12 +8,13 @@ import {
} from "$lib/forum/threads";
import { fetchProfiles } from "$lib/forum/profiles";
import type { ThreadsSnapshot } from "$lib/forum/snapshot";
import { snapshotHandler } from "$lib/ssr/endpoint";
import { forumQuery, profileQuery } from "$lib/ssr/relay";
import type { RequestHandler } from "./$types";
// First page of a group's listing. Unknown rooms are a 404 so crawlers don't
// index empty shells; private rooms are simply empty to the anonymous server.
export async function GET({ params, url, setHeaders }) {
setHeaders({ "cache-control": CACHE_CONTROL });
export const GET: RequestHandler = snapshotHandler(async ({ params, url }) => {
const groupId = params.group;
if (MODE === "simple") {
if (groupId !== GROUP_ID) error(404, "Not found");
@ -41,4 +42,4 @@ export async function GET({ params, url, setHeaders }) {
profiles,
};
return json(body);
}
});

View file

@ -85,6 +85,12 @@ body {
font-size: 1.65rem;
color: var(--color-accent);
}
.prose :is(h2) {
font-size: 1.35rem;
}
.prose :is(h3) {
font-size: 1.15rem;
}
.prose :is(p) {
margin-top: 0;
}

View file

@ -1,7 +1,9 @@
import { CACHE_CONTROL, MODE, GROUP_ID } from "$lib/config";
import { MODE, GROUP_ID } from "$lib/config";
import { fetchGroups } from "$lib/forum/groups";
import { snapshotHandler } from "$lib/ssr/endpoint";
import { forumQuery } from "$lib/ssr/relay";
import { loadShell } from "$lib/ssr/shell";
import type { RequestHandler } from "./$types";
const THREADS_PER_ROOM = 1000;
@ -25,7 +27,7 @@ function xml(origin: string, entries: Entry[]): string {
// Public pages only: rooms the anonymous server can see, their threads, and
// the admin-authored resources.
export async function GET({ url, setHeaders }) {
export const GET: RequestHandler = snapshotHandler(async ({ url }) => {
const entries: Entry[] = [{ path: "/" }, { path: "/contacts" }];
const shell = await loadShell();
const admins = new Set(shell.admins);
@ -49,8 +51,7 @@ export async function GET({ url, setHeaders }) {
for (const e of ops)
entries.push({ path: `/thread/${e.id}`, lastmod: e.created_at });
}
setHeaders({ "cache-control": CACHE_CONTROL });
return new Response(xml(url.origin, entries), {
headers: { "content-type": "application/xml" },
});
}
});