web: adopt Cache Components, Partial Prefetching and ensureStatic
web / ci (push) Successful in 2m2s

This commit is contained in:
ponas committed 2026-10-13 23:59:14 +02:00
1 parent 3a0c2fd82b
commit db286434ba
70 files changed
+1285 -316

No files matched your search

+37 -1
View File
@@ -19,6 +19,12 @@ export type MockCms = {
url: string;
state: MockState;
graphqlRequests: number;
// GraphQL requests per operation name, served at /__mock/requests so tests
// can tell which queries a re-render actually sent
requestsByOperation: Record<string, number>;
// call once `next build` is done; /__mock/requests then also reports the
// requests made since
markBuildDone(): void;
close(): Promise<void>;
};
@@ -34,11 +40,16 @@ function readBody(req: http.IncomingMessage): Promise<string> {
export async function startMockCms(): Promise<MockCms> {
const state: MockState = { newsHeadlineVersion: "v1" };
let fixtures: Fixtures | null = null; // built once we know our own URL
let requestsAtBuild: Record<string, number> = {};
const mock: MockCms = {
url: "",
state,
graphqlRequests: 0,
requestsByOperation: {},
markBuildDone: () => {
requestsAtBuild = { ...mock.requestsByOperation };
},
close: () =>
new Promise((resolve, reject) =>
server.close((err) => (err ? reject(err) : resolve()))
@@ -56,6 +67,20 @@ export async function startMockCms(): Promise<MockCms> {
return;
}
if (req.method === "GET" && req.url === "/__mock/requests") {
const sinceBuild = Object.fromEntries(
Object.entries(mock.requestsByOperation).map(([name, count]) => [
name,
count - (requestsAtBuild[name] ?? 0),
])
);
res.writeHead(200, { "content-type": "application/json" });
res.end(
JSON.stringify({ total: mock.requestsByOperation, sinceBuild })
);
return;
}
if (req.method === "POST" && req.url === "/__mock/state") {
Object.assign(state, JSON.parse(await readBody(req)));
res.writeHead(200, { "content-type": "application/json" });
@@ -84,6 +109,10 @@ export async function startMockCms(): Promise<MockCms> {
const name =
body.operationName ??
/(?:query|mutation)\s+(\w+)/.exec(body.query ?? "")?.[1];
if (name) {
mock.requestsByOperation[name] =
(mock.requestsByOperation[name] ?? 0) + 1;
}
const resolve = name ? fixtures?.[name] : undefined;
res.writeHead(200, { "content-type": "application/json" });
if (!resolve) {
@@ -96,7 +125,14 @@ export async function startMockCms(): Promise<MockCms> {
);
return;
}
res.end(JSON.stringify({ data: resolve(body.variables ?? {}, state) }));
// decide the answer first: a slow CMS returns what it had when asked
const answer = JSON.stringify({
data: resolve(body.variables ?? {}, state),
});
if (name === "newsBySlug" && state.newsDelayMs) {
await new Promise((r) => setTimeout(r, state.newsDelayMs));
}
res.end(answer);
return;
}