nuxt-multi-cache
Version:
SSR route, component and data cache for Nuxt.js
84 lines (83 loc) • 2.13 kB
JavaScript
import { hash } from "ohash";
import { ssrRenderSlotInner } from "vue/server-renderer";
import {
decodeComponentCacheItem,
handleRawCacheData
} from "../../../helpers/cacheItem.js";
import { logger } from "../../../helpers/logger.js";
export function getCacheKey(props, vnode, debug) {
const componentName = getComponentName(vnode);
const hasProps = Object.keys(vnode.props || {}).length > 0;
const cacheKeyBase = props.cacheKey || (hasProps ? hash(vnode.props) : "");
if (!componentName) {
if (debug) {
logger.info("Skipped caching component because component has no name.", {
props
});
}
return;
}
if (cacheKeyBase) {
return `${componentName}::${cacheKeyBase}`;
}
return componentName;
}
export function getComponentName(vnode) {
if (typeof vnode.type === "object") {
if ("__name" in vnode.type) {
return vnode.type.__name;
} else if ("name" in vnode.type) {
return vnode.type.name;
}
}
}
function isPromise(p) {
if (typeof p === "object" && typeof p.then === "function") {
return true;
}
return false;
}
async function unrollBuffer(buffer) {
let ret = "";
for (let i = 0; i < buffer.length; i++) {
let item = buffer[i];
if (isPromise(item)) {
item = await item;
}
if (typeof item === "string") {
ret += item;
} else {
ret += await unrollBuffer(item);
}
}
return ret;
}
export function renderSlot(slots, parent) {
const buffer = [];
const push = (v) => {
buffer.push(v);
};
ssrRenderSlotInner(
// Slots of this wrapper component.
slots,
// Chose the default slot.
"default",
// Slot props are not supported.
{},
// No fallback render function.
null,
// Method that pushes markup fragments or promises to our buffer.
push,
// This wrapper component's parent.
parent
);
return unrollBuffer(buffer);
}
export async function getCachedComponent(storage, cacheKey) {
const cachedRaw = handleRawCacheData(
await storage.getItemRaw(cacheKey)
);
if (cachedRaw) {
return decodeComponentCacheItem(cachedRaw);
}
}