Press n or j to go to the next uncovered block, b, p or k for the previous block.
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 | 8x 8x 4x 4x 12x 22x 12x 12x 12x 2x 2x 10x 10x 6x 6x 6x 6x 10x 10x 10x 10x 4x 2x 2x 2x 6x 6x 6x | export type CacheOptions = {
// maxAge typically represents private cache, such as browser
maxAge: number
// sMaxAge typically represents shared cache, such as CDN
sMaxAge: number
}
const cacheDisabled = import.meta.env.VITE_CACHE_DISABLED === 'true'
Iif (cacheDisabled) {
console.warn('Cache is disabled')
}
/**
* Fetches a resource while applying a cacheable mechanism with a specified TTL (time-to-live).
*
* @param {Request<unknown, IncomingRequestCfProperties>} request - The request object containing the resource to fetch and properties related to the Cloudflare environment.
* @param {number} ttl - The time-to-live (TTL) value for the cacheable mechanism.
* @return {Promise<Response>} A promise that resolves to a Response object.
*/
export async function fetchCacheable(
request: Request<unknown, IncomingRequestCfProperties>,
ttl: number
): Promise<Response> {
Iif (cacheDisabled) {
return fetch(request)
}
return fetch(request, { cf: { cacheTtl: ttl } })
}
/**
* Ensures that the specified cache directive in the directives list does not exceed a given maximum value.
* If the directive is not present in the list, it is added with the maximum value specified.
* If the directive is already present and its value exceeds the specified maximum, it is updated to the maximum value.
*
* @param {string[]} directives - The list of cache directive strings to inspect and modify.
* @param {'max-age' | 's-maxage'} directive - The cache directive type to search for and enforce a maximum value.
* @param {number} maxMaxAge - The maximum allowed value for the specified directive.
*/
function ensureMaxCacheDirectiveValue(directives: string[], directive: 'max-age' | 's-maxage', maxMaxAge: number) {
const directiveIndex = directives.findIndex(
(directivePair) => directivePair.split('=')[0].trim().toLowerCase() === directive
)
Iif (directiveIndex === -1) {
directives.push(`${directive}=${maxMaxAge}`)
} else {
const oldValue = Number(directives[directiveIndex].split('=')[1])
if (Number.isNaN(oldValue)) {
console.warn(`Invalid ${directive} directive value: ${oldValue}`)
return
}
const newValue = Math.min(maxMaxAge, oldValue)
directives[directiveIndex] = `${directive}=${newValue}`
}
}
/**
* Ensures that the cache-control header contains the specified maximum age values for 'max-age' and 's-maxage' directives.
* If these values exceed the given maximums, they are updated accordingly.
*
* @param {string} cacheControlHeaderValue - The existing value of the cache-control header.
* @param {Object} param - Configuration options for controlling cache directive values.
* @param {number} [param.sMaxAge] - The maximum allowed value for the 's-maxage' directive.
* @param {number} [param.maxAge] - The maximum allowed value for the 'max-age' directive.
* @return {string} - The updated cache-control header value with updated or unchanged directive values.
*/
function ensureCacheControlMaxAge(cacheControlHeaderValue: string, { sMaxAge, maxAge }: CacheOptions): string {
const cacheControlDirectives = cacheControlHeaderValue.split(/\s*,\s*/)
ensureMaxCacheDirectiveValue(cacheControlDirectives, 'max-age', maxAge)
ensureMaxCacheDirectiveValue(cacheControlDirectives, 's-maxage', sMaxAge)
return cacheControlDirectives.join(', ')
}
/**
* Creates a new `Response` object with an updated `cache-control` header. If the original response does not
* have a `cache-control` header, this method handles the behavior based on the value of `ifNoCacheControlBehavior`.
*
* @param {Response} oldResponse - The original response object whose `cache-control` header may be modified.
* @param {'skip'|'set'} [ifNoCacheControlBehavior='skip'] - Determines behavior when the original response lacks a `cache-control` header.
* - `'skip'`: Returns the response without adding a `cache-control` header.
* - `'set'`: Sets a default `cache-control` header with pre-defined `max-age` and `s-maxage` values.
* @param {CacheOptions} cacheOptions - The cache options object.
* @return {Response} A new `Response` instance with the updated `cache-control` header or the original behavior based on the inputs.
*/
export function createResponseWithMaxAge(
oldResponse: Response,
cacheOptions: CacheOptions,
ifNoCacheControlBehavior: 'skip' | 'set' = 'skip'
): Response {
Iif (cacheDisabled) {
return oldResponse
}
const response = new Response(oldResponse.body, oldResponse)
const oldCacheControlHeader = oldResponse.headers.get('cache-control')
if (!oldCacheControlHeader) {
if (ifNoCacheControlBehavior === 'skip') {
return response
}
response.headers.set('cache-control', `max-age=${cacheOptions.maxAge}, s-maxage=${cacheOptions.sMaxAge}`)
return response
}
const cacheControlHeader = ensureCacheControlMaxAge(oldCacheControlHeader, cacheOptions)
response.headers.set('cache-control', cacheControlHeader)
return response
}
|