UNPKG

@fortedigital/nextjs-cache-handler

Version:
152 lines (149 loc) 5.84 kB
"use strict"; var __create = Object.create; var __defProp = Object.defineProperty; var __getOwnPropDesc = Object.getOwnPropertyDescriptor; var __getOwnPropNames = Object.getOwnPropertyNames; var __getProtoOf = Object.getPrototypeOf; var __hasOwnProp = Object.prototype.hasOwnProperty; var __export = (target, all) => { for (var name in all) __defProp(target, name, { get: all[name], enumerable: true }); }; var __copyProps = (to, from, except, desc) => { if (from && typeof from === "object" || typeof from === "function") { for (let key of __getOwnPropNames(from)) if (!__hasOwnProp.call(to, key) && key !== except) __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable }); } return to; }; var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps( // If the importer is in node compatibility mode or this is not an ESM // file that has been converted to a CommonJS file using a Babel- // compatible transform (i.e. "__esModule" has not been set), then set // "default" to the CommonJS "module.exports" for node compatibility. isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target, mod )); var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod); // src/functions/functions.ts var functions_exports = {}; __export(functions_exports, { neshClassicCache: () => neshClassicCache }); module.exports = __toCommonJS(functions_exports); // src/functions/nesh-classic-cache.ts var import_strict = __toESM(require("assert/strict"), 1); var import_node_crypto = require("crypto"); var import_work_async_storage_external = require("next/dist/server/app-render/work-async-storage.external.js"); var import_constants = require("next/dist/lib/constants"); function hashCacheKey(url) { const MAIN_KEY_PREFIX = "nesh-pages-cache-v1"; const cacheString = JSON.stringify([MAIN_KEY_PREFIX, url]); return (0, import_node_crypto.createHash)("sha256").update(cacheString).digest("hex"); } function serializeArguments(object) { return JSON.stringify(object); } function serializeResult(object) { return Buffer.from(JSON.stringify(object), "utf-8").toString("base64"); } function deserializeResult(string) { return JSON.parse(Buffer.from(string, "base64").toString("utf-8")); } function neshClassicCache(callback, commonOptions) { if (commonOptions?.resultSerializer && !commonOptions?.resultDeserializer) { throw new Error( "neshClassicCache: if you provide a resultSerializer, you must provide a resultDeserializer." ); } if (commonOptions?.resultDeserializer && !commonOptions?.resultSerializer) { throw new Error( "neshClassicCache: if you provide a resultDeserializer, you must provide a resultSerializer." ); } const commonRevalidate = commonOptions?.revalidate ?? false; const commonArgumentsSerializer = commonOptions?.argumentsSerializer ?? serializeArguments; const commonResultSerializer = commonOptions?.resultSerializer ?? serializeResult; const commonResultDeserializer = commonOptions?.resultDeserializer ?? deserializeResult; async function cachedCallback(options, ...args) { const store = import_work_async_storage_external.workAsyncStorage.getStore(); (0, import_strict.default)( !store?.incrementalCache, "neshClassicCache must be used in a Next.js Pages directory." ); const cacheHandler = globalThis?.__incrementalCache?.cacheHandler; (0, import_strict.default)( cacheHandler, "neshClassicCache must be used in a Next.js Pages directory." ); const { responseContext, tags = [], revalidate = commonRevalidate, cacheKey, argumentsSerializer = commonArgumentsSerializer, resultDeserializer = commonResultDeserializer, resultSerializer = commonResultSerializer } = options ?? {}; (0, import_strict.default)( revalidate === false || revalidate > 0 && Number.isInteger(revalidate), "neshClassicCache: revalidate must be a positive integer or false." ); responseContext?.setHeader( "Cache-Control", `public, s-maxage=${revalidate}, stale-while-revalidate` ); const uniqueTags = /* @__PURE__ */ new Set(); for (const tag of tags) { if (typeof tag === "string") { uniqueTags.add(tag); } else { console.warn( `neshClassicCache: Invalid tag: ${tag}. Skipping it. Expected a string.` ); } } const allTags = Array.from(uniqueTags); const key = hashCacheKey( `nesh-classic-cache-${cacheKey ?? argumentsSerializer(args)}` ); const cacheData = await cacheHandler.get(key, { revalidate, tags: allTags, kind: "FETCH", fetchUrl: "neshClassicCache" }); if (cacheData?.value?.kind === "FETCH" && cacheData.lifespan && cacheData.lifespan.staleAt > Date.now() / 1e3) { return resultDeserializer(cacheData.value.data.body); } const data = await callback(...args); cacheHandler.set( key, { kind: "FETCH", data: { body: resultSerializer(data), headers: {}, url: "neshClassicCache" }, revalidate: revalidate || import_constants.CACHE_ONE_YEAR }, { revalidate, tags, fetchCache: true, fetchUrl: "neshClassicCache" } ); if (cacheData?.value?.kind === "FETCH" && cacheData?.lifespan && cacheData.lifespan.expireAt > Date.now() / 1e3) { return resultDeserializer(cacheData.value.data.body); } return data; } return cachedCallback; } // Annotate the CommonJS export names for ESM import in node: 0 && (module.exports = { neshClassicCache });