| Server IP : 159.203.156.69 / Your IP : 216.73.217.172 Web Server : nginx/1.24.0 System : Linux main-ubuntu 6.8.0-71-generic #71-Ubuntu SMP PREEMPT_DYNAMIC Tue Jul 22 16:52:38 UTC 2025 x86_64 User : root ( 0) PHP Version : 8.3.6 Disable Function : NONE MySQL : OFF | cURL : ON | WGET : ON | Perl : ON | Python : OFF | Sudo : ON | Pkexec : OFF Directory : /var/www/tanviranik.com/node_modules/vinext/dist/server/ |
Upload File : |
import { VINEXT_CACHE_HEADER, VINEXT_MOUNTED_SLOTS_HEADER } from "./headers.js";
import { encodeCacheTag } from "../utils/encode-cache-tag.js";
import { buildAppPageCacheValue } from "./isr-cache.js";
import { VINEXT_RSC_VARY_HEADER } from "./app-rsc-cache-busting.js";
import { readStreamAsText } from "../utils/text-stream.js";
import { mergeMiddlewareResponseHeaders } from "./middleware-response-headers.js";
import { buildCachedRevalidateCacheControl } from "./cache-control.js";
//#region src/server/app-page-cache.ts
const NO_STORE_CACHE_CONTROL = "no-store, must-revalidate";
function buildAppPageCacheTags(pathname, extraTags) {
const tags = [
pathname,
`_N_T_${pathname}`,
"_N_T_/layout"
];
const segments = pathname.split("/");
let built = "";
for (let index = 1; index < segments.length; index++) {
const segment = segments[index];
if (segment) {
built += `/${segment}`;
tags.push(`_N_T_${built}/layout`);
}
}
tags.push(`_N_T_${built}/page`);
for (const tag of extraTags) if (!tags.includes(tag)) tags.push(tag);
return tags.map(encodeCacheTag);
}
function buildAppPageCacheControl(cacheState, revalidateSeconds, expireSeconds) {
return buildCachedRevalidateCacheControl(cacheState, revalidateSeconds, expireSeconds);
}
function buildAppPageCachedHeaders(options) {
const headers = new Headers({
"Cache-Control": options.cacheControl,
"Content-Type": options.contentType,
Vary: VINEXT_RSC_VARY_HEADER,
[VINEXT_CACHE_HEADER]: options.cacheState
});
if (options.mountedSlotsHeader) headers.set(VINEXT_MOUNTED_SLOTS_HEADER, options.mountedSlotsHeader);
mergeMiddlewareResponseHeaders(headers, options.middlewareHeaders ?? null);
return headers;
}
function getCachedAppPageValue(entry) {
return entry?.value.value && entry.value.value.kind === "APP_PAGE" ? entry.value.value : null;
}
function resolveAppPageCacheWritePolicy(options) {
let revalidateSeconds = options.revalidateSeconds;
let expireSeconds = options.expireSeconds;
const requestCacheLife = options.requestCacheLife;
if (requestCacheLife?.revalidate !== void 0) revalidateSeconds = revalidateSeconds === null ? requestCacheLife.revalidate : Math.min(revalidateSeconds, requestCacheLife.revalidate);
if (requestCacheLife?.expire !== void 0) expireSeconds = requestCacheLife.expire;
if (revalidateSeconds === null || revalidateSeconds <= 0 || !Number.isFinite(revalidateSeconds)) return null;
return {
expireSeconds,
revalidateSeconds
};
}
function buildAppPageCachedResponse(cachedValue, options) {
const status = options.middlewareStatus ?? (cachedValue.status || 200);
const revalidateSeconds = options.cacheControl?.revalidate ?? options.revalidateSeconds;
const expireSeconds = options.cacheControl === void 0 ? void 0 : options.cacheControl.expire ?? options.expireSeconds;
const cacheControl = buildAppPageCacheControl(options.cacheState, revalidateSeconds, expireSeconds);
if (options.isRscRequest) {
if (!cachedValue.rscData) return null;
const rscHeaders = buildAppPageCachedHeaders({
cacheControl,
cacheState: options.cacheState,
contentType: "text/x-component; charset=utf-8",
middlewareHeaders: options.middlewareHeaders,
mountedSlotsHeader: options.mountedSlotsHeader
});
return new Response(cachedValue.rscData, {
status,
headers: rscHeaders
});
}
if (typeof cachedValue.html !== "string" || cachedValue.html.length === 0) return null;
const htmlHeaders = buildAppPageCachedHeaders({
cacheControl,
cacheState: options.cacheState,
contentType: "text/html; charset=utf-8",
middlewareHeaders: options.middlewareHeaders
});
return new Response(cachedValue.html, {
status,
headers: htmlHeaders
});
}
async function readAppPageCacheResponse(options) {
const isrKey = options.isRscRequest ? options.isrRscKey(options.cleanPathname, options.mountedSlotsHeader, options.renderMode) : options.isrHtmlKey(options.cleanPathname);
try {
const cached = await options.isrGet(isrKey);
const cachedValue = getCachedAppPageValue(cached);
if (cachedValue && !cached?.isStale) {
const hitResponse = buildAppPageCachedResponse(cachedValue, {
cacheState: "HIT",
cacheControl: cached?.value.cacheControl,
expireSeconds: options.expireSeconds,
isRscRequest: options.isRscRequest,
middlewareHeaders: options.middlewareHeaders,
middlewareStatus: options.middlewareStatus,
mountedSlotsHeader: options.mountedSlotsHeader,
revalidateSeconds: options.revalidateSeconds
});
if (hitResponse) {
options.isrDebug?.(options.isRscRequest ? "HIT (RSC)" : "HIT (HTML)", options.cleanPathname);
options.clearRequestContext();
return hitResponse;
}
options.isrDebug?.("MISS (empty cached entry)", options.cleanPathname);
}
if (cached?.isStale && cachedValue) {
const regenerationKey = options.isRscRequest ? options.isrRscKey(options.cleanPathname, options.mountedSlotsHeader, options.renderMode) : options.isrHtmlKey(options.cleanPathname);
options.scheduleBackgroundRegeneration(regenerationKey, async () => {
const revalidatedPage = await options.renderFreshPageForCache();
const revalidateSeconds = revalidatedPage.cacheControl?.revalidate ?? options.revalidateSeconds;
const expireSeconds = revalidatedPage.cacheControl?.expire ?? options.expireSeconds;
const writes = [options.isrSet(options.isrRscKey(options.cleanPathname, options.mountedSlotsHeader, options.renderMode), buildAppPageCacheValue("", revalidatedPage.rscData, 200), revalidateSeconds, revalidatedPage.tags, expireSeconds)];
if (!options.isRscRequest) writes.push(options.isrSet(options.isrHtmlKey(options.cleanPathname), buildAppPageCacheValue(revalidatedPage.html, void 0, 200), revalidateSeconds, revalidatedPage.tags, expireSeconds));
await Promise.all(writes);
options.isrDebug?.("regen complete", options.cleanPathname);
});
const staleResponse = buildAppPageCachedResponse(cachedValue, {
cacheState: "STALE",
cacheControl: cached.value.cacheControl,
expireSeconds: options.expireSeconds,
isRscRequest: options.isRscRequest,
middlewareHeaders: options.middlewareHeaders,
middlewareStatus: options.middlewareStatus,
mountedSlotsHeader: options.mountedSlotsHeader,
revalidateSeconds: options.revalidateSeconds
});
if (staleResponse) {
options.isrDebug?.(options.isRscRequest ? "STALE (RSC)" : "STALE (HTML)", options.cleanPathname);
options.clearRequestContext();
return staleResponse;
}
options.isrDebug?.("STALE MISS (empty stale entry)", options.cleanPathname);
}
if (!cached) options.isrDebug?.("MISS (no cache entry)", options.cleanPathname);
} catch (isrReadError) {
console.error("[vinext] ISR cache read error:", isrReadError);
}
return null;
}
function finalizeAppPageHtmlCacheResponse(response, options) {
if (!response.body) return response;
const [streamForClient, streamForCache] = response.body.tee();
const htmlKey = options.isrHtmlKey(options.cleanPathname);
const rscKey = options.isrRscKey(options.cleanPathname, null);
const clientHeaders = new Headers(response.headers);
if (options.preserveClientResponseHeaders !== true) {
clientHeaders.set("Cache-Control", NO_STORE_CACHE_CONTROL);
clientHeaders.set(VINEXT_CACHE_HEADER, "MISS");
}
const cachePromise = (async () => {
try {
const cachedHtml = await readStreamAsText(streamForCache);
if (options.capturedDynamicUsageBeforeContextCleanup?.() === true || options.consumeDynamicUsage()) {
options.isrDebug?.("HTML cache write skipped (dynamic usage during render)", htmlKey);
return;
}
const cachePolicy = resolveAppPageCacheWritePolicy({
expireSeconds: options.expireSeconds,
requestCacheLife: options.getRequestCacheLife?.(),
revalidateSeconds: options.revalidateSeconds
});
if (!cachePolicy) {
options.isrDebug?.("HTML cache write skipped (no cache policy)", htmlKey);
return;
}
const pageTags = options.getPageTags();
const writes = [options.isrSet(htmlKey, buildAppPageCacheValue(cachedHtml, void 0, 200), cachePolicy.revalidateSeconds, pageTags, cachePolicy.expireSeconds)];
if (options.capturedRscDataPromise) writes.push(options.capturedRscDataPromise.then((rscData) => options.isrSet(rscKey, buildAppPageCacheValue("", rscData, 200), cachePolicy.revalidateSeconds, pageTags, cachePolicy.expireSeconds)));
await Promise.all(writes);
options.isrDebug?.("HTML cache written", htmlKey);
} catch (cacheError) {
console.error("[vinext] ISR cache write error:", cacheError);
}
})();
options.waitUntil?.(cachePromise);
return new Response(streamForClient, {
status: response.status,
statusText: response.statusText,
headers: clientHeaders
});
}
function finalizeAppPageRscCacheResponse(response, options) {
if (!scheduleAppPageRscCacheWrite(options)) return response;
if (options.preserveClientResponseHeaders === true) return response;
const clientHeaders = new Headers(response.headers);
clientHeaders.set("Cache-Control", NO_STORE_CACHE_CONTROL);
clientHeaders.set(VINEXT_CACHE_HEADER, "MISS");
return new Response(response.body, {
status: response.status,
statusText: response.statusText,
headers: clientHeaders
});
}
function scheduleAppPageRscCacheWrite(options) {
const capturedRscDataPromise = options.capturedRscDataPromise;
if (!capturedRscDataPromise || options.dynamicUsedDuringBuild) return false;
const rscKey = options.isrRscKey(options.cleanPathname, options.mountedSlotsHeader, options.renderMode);
const cachePromise = (async () => {
try {
const rscData = await capturedRscDataPromise;
if (options.consumeDynamicUsage()) {
options.isrDebug?.("RSC cache write skipped (dynamic usage during render)", rscKey);
return;
}
const cachePolicy = resolveAppPageCacheWritePolicy({
expireSeconds: options.expireSeconds,
requestCacheLife: options.getRequestCacheLife?.(),
revalidateSeconds: options.revalidateSeconds
});
if (!cachePolicy) {
options.isrDebug?.("RSC cache write skipped (no cache policy)", rscKey);
return;
}
await options.isrSet(rscKey, buildAppPageCacheValue("", rscData, 200), cachePolicy.revalidateSeconds, options.getPageTags(), cachePolicy.expireSeconds);
options.isrDebug?.("RSC cache written", rscKey);
} catch (cacheError) {
console.error("[vinext] ISR RSC cache write error:", cacheError);
}
})();
options.waitUntil?.(cachePromise);
return true;
}
//#endregion
export { buildAppPageCacheTags, buildAppPageCachedResponse, finalizeAppPageHtmlCacheResponse, finalizeAppPageRscCacheResponse, readAppPageCacheResponse, scheduleAppPageRscCacheWrite };
//# sourceMappingURL=app-page-cache.js.map