web: adopt Cache Components, Partial Prefetching and ensureStatic
web / ci (push) Successful in 2m2s
web / ci (push) Successful in 2m2s
This commit is contained in:
70 files changed
+1285
-316
No files matched your search
+52
-5
@@ -1,9 +1,16 @@
|
||||
import "server-only";
|
||||
|
||||
import { cacheExchange, createClient, fetchExchange } from "@urql/core";
|
||||
import {
|
||||
type AnyVariables,
|
||||
type TypedDocumentNode,
|
||||
cacheExchange,
|
||||
createClient,
|
||||
fetchExchange,
|
||||
stringifyDocument,
|
||||
} from "@urql/core";
|
||||
import { registerUrql } from "@urql/next/rsc";
|
||||
|
||||
import { CMS_CACHE_TAG } from "@/lib/revalidation";
|
||||
import { cmsCache, cmsCacheForToday } from "@/lib/cmsCache";
|
||||
|
||||
const wagtailBaseUrl = process.env.WAGTAIL_BASE_URL;
|
||||
if (!wagtailBaseUrl) {
|
||||
@@ -15,10 +22,50 @@ const makeClient = () => {
|
||||
return createClient({
|
||||
url: graphqlEndpoint,
|
||||
exchanges: [cacheExchange, fetchExchange],
|
||||
// Cache all queries in the Data Cache until revalidateTag(CMS_CACHE_TAG);
|
||||
// override per operation with the contexts in @/lib/revalidation
|
||||
fetchOptions: { cache: "force-cache", next: { tags: [CMS_CACHE_TAG] } },
|
||||
});
|
||||
};
|
||||
|
||||
// Uncached. Only for per-user (search) and token-scoped (preview) queries,
|
||||
// together with the `uncached` context; everything else goes through cmsQuery
|
||||
export const { getClient } = registerUrql(makeClient);
|
||||
|
||||
// Throws on GraphQL and network errors, which keeps them out of the cache
|
||||
async function runQuery(query: string, variables: AnyVariables) {
|
||||
const { data, error } = await getClient().query(query, variables);
|
||||
if (error) throw new Error(error.message);
|
||||
return data;
|
||||
}
|
||||
|
||||
// The cached functions take the query as text: their arguments are the cache
|
||||
// key, and urql adds bookkeeping properties to document objects it has seen
|
||||
async function cachedQuery(query: string, variables: AnyVariables) {
|
||||
"use cache";
|
||||
cmsCache();
|
||||
return runQuery(query, variables);
|
||||
}
|
||||
|
||||
async function cachedQueryForToday(query: string, variables: AnyVariables) {
|
||||
"use cache";
|
||||
cmsCacheForToday();
|
||||
return runQuery(query, variables);
|
||||
}
|
||||
|
||||
// Every cacheable CMS read goes through one of the two functions below, so
|
||||
// all of them carry the tag the CMS webhook purges
|
||||
|
||||
// Cached until the content is edited in the CMS
|
||||
export function cmsQuery<Data, Variables extends AnyVariables>(
|
||||
document: TypedDocumentNode<Data, Variables>,
|
||||
variables: Variables
|
||||
): Promise<Data | undefined> {
|
||||
return cachedQuery(stringifyDocument(document), variables);
|
||||
}
|
||||
|
||||
// For queries where the CMS decides by today's date what to return
|
||||
// (futureEvents): also purged at Oslo midnight
|
||||
export function cmsQueryForToday<Data, Variables extends AnyVariables>(
|
||||
document: TypedDocumentNode<Data, Variables>,
|
||||
variables: Variables
|
||||
): Promise<Data | undefined> {
|
||||
return cachedQueryForToday(stringifyDocument(document), variables);
|
||||
}
|
||||
Reference in new issue
Block a user