nuxt-multi-cache
Version:
SSR route, component and data cache for Nuxt.js
94 lines (93 loc) • 2.9 kB
JavaScript
import { useAsyncData, useDataCache, useNuxtApp } from "#imports";
function getClientSideCachedData(key, app) {
return app.static.data[key];
}
function valueOrMethod(value, result) {
if (typeof value === "function") {
return value(result);
}
return value;
}
function isValidMaxAge(v) {
return typeof v === "number" && v >= 1;
}
export function useCachedAsyncData(key, handler, providedOptions) {
const options = providedOptions && typeof providedOptions === "object" ? providedOptions : {};
if (import.meta.client) {
const app = useNuxtApp();
if (!app.static.data.__firstHydrationTime) {
app.static.data.__firstHydrationTime = Date.now();
}
return useAsyncData(
key,
async () => {
const result = await handler(app);
const data = options?.transform ? await options.transform(result) : result;
if (isValidMaxAge(options.clientMaxAge)) {
const cacheItem = {
data,
expires: Date.now() + options.clientMaxAge * 1e3
};
app.static.data[key] = cacheItem;
}
return data;
},
{
...options,
// Override this option because we call it manually.
transform: void 0,
// Also override this method because we need it.
// The custom type for the options omits this property.
getCachedData(key2, nuxtApp) {
const payloadData = nuxtApp.payload.data[key2];
if (payloadData && app.isHydrating) {
return payloadData;
}
if (!isValidMaxAge(options.clientMaxAge)) {
return;
}
if (payloadData) {
const firstHydrationTime = nuxtApp.static.data.__firstHydrationTime;
const expires = firstHydrationTime + options.clientMaxAge * 1e3;
if (expires > Date.now()) {
return payloadData;
}
}
const staticCache = getClientSideCachedData(key2, app);
if (staticCache) {
const expires = staticCache.expires;
if (expires > Date.now()) {
return staticCache.data;
}
}
return void 0;
}
}
);
}
return useAsyncData(
key,
async (app) => {
const { value, addToCache } = await useDataCache(
key,
app?.ssrContext?.event
);
if (value) {
return value;
}
const result = await handler(app);
const cacheTags = valueOrMethod(options?.serverCacheTags, result);
const maxAge = valueOrMethod(options?.serverMaxAge, result);
const data = options?.transform ? await options.transform(result) : result;
if (isValidMaxAge(maxAge)) {
await addToCache(data, cacheTags, maxAge);
}
return data;
},
{
...options,
transform: void 0,
getCachedData: void 0
}
);
}