nuxt-multi-cache
Version:
SSR route, component and data cache for Nuxt.js
90 lines (89 loc) • 2.73 kB
JavaScript
import { getResponseHeaders, getResponseStatus } from "h3";
import {
encodeRouteCacheKey,
getCacheKeyWithPrefix,
getMultiCacheContext,
getMultiCacheRouteHelper
} from "../../helpers/server.js";
import { encodeRouteCacheItem } from "../../helpers/cacheItem.js";
import { logger } from "../../helpers/logger.js";
import { useMultiCacheApp } from "../utils/useMultiCacheApp.js";
import { useRuntimeConfig } from "#imports";
function isPureObject(value) {
const proto = Object.getPrototypeOf(value);
return !proto || proto.isPrototypeOf(Object);
}
function stringify(value) {
if (typeof value === "string") {
return value;
}
try {
if (isPureObject(value) || Array.isArray(value)) {
return JSON.stringify(value);
}
if (typeof value.toJSON === "function") {
return stringify(value.toJSON());
}
} catch (_e) {
}
}
export async function onAfterResponse(event, response) {
if (event.__MULTI_CACHE_SERVED_FROM_CACHE) {
return;
}
if (!response?.body) {
return;
}
const responseData = stringify(response.body);
if (!responseData) {
return;
}
const multiCache = getMultiCacheContext(event);
if (!multiCache?.route) {
return;
}
const routeHelper = getMultiCacheRouteHelper(event);
if (!routeHelper?.cacheable) {
return;
}
const statusCode = getResponseStatus(event);
if (statusCode !== 200) {
return;
}
const { serverOptions, state } = useMultiCacheApp();
let responseHeaders = getResponseHeaders(event);
responseHeaders["content-encoding"] = void 0;
if (serverOptions.route?.alterCachedHeaders) {
responseHeaders = serverOptions.route.alterCachedHeaders(responseHeaders);
}
const cacheKey = serverOptions?.route?.buildCacheKey ? serverOptions.route.buildCacheKey(event) : getCacheKeyWithPrefix(encodeRouteCacheKey(event.path), event);
const expires = routeHelper.getExpires("maxAge");
const staleIfErrorExpires = routeHelper.getExpires("staleIfError");
const staleWhileRevalidate = !!routeHelper.staleWhileRevalidate;
const cacheItem = encodeRouteCacheItem(
responseData,
responseHeaders,
statusCode,
expires,
staleIfErrorExpires,
staleWhileRevalidate,
routeHelper.tags
);
const debugEnabled = useRuntimeConfig().multiCache.debug;
if (debugEnabled) {
logger.info("Storing route in cache: " + event.path, {
cacheKey,
expires,
staleIfErrorExpires,
cacheTags: routeHelper.tags,
staleWhileRevalidate,
statusCode
});
}
await multiCache.route.setItemRaw(cacheKey, cacheItem, {
ttl: routeHelper.maxAge
});
if (event.__MULTI_CACHE_REVALIDATION_KEY) {
state.removeKeyBeingRevalidated(event.__MULTI_CACHE_REVALIDATION_KEY);
}
}