Core caching functionality that wraps HTTP request functions with intelligent cache support. Provides RFC 7234 compliant HTTP caching with automatic revalidation and configurable cache behavior.
Main wrapper class that adds caching capabilities to any HTTP request function.
/**
* Creates a cacheable request wrapper around an HTTP request function
* @param cacheRequest - HTTP request function to wrap (e.g., http.request)
* @param cacheAdapter - Optional Keyv instance or storage adapter
*/
class CacheableRequest {
cache: Keyv;
cacheRequest: RequestFn;
hooks: Map<string, Function>;
constructor(cacheRequest: RequestFn, cacheAdapter?: any);
request(): CacheableRequestFunction;
addHook(name: string, fn: Function): void;
removeHook(name: string): boolean;
getHook(name: string): Function | undefined;
runHook(name: string, ...args: any[]): Promise<CacheValue>;
}Usage Examples:
import CacheableRequest from "cacheable-request";
import { request } from "node:http";
import { request as httpsRequest } from "node:https";
// Basic setup with default in-memory cache
const cacheableRequest = new CacheableRequest(request);
const cachedHttp = cacheableRequest.request();
// With HTTPS
const cacheableHttps = new CacheableRequest(httpsRequest);
const cachedHttps = cacheableHttps.request();
// With custom cache adapter
import { Keyv } from "keyv";
const cache = new Keyv("redis://localhost:6379");
const cacheableWithRedis = new CacheableRequest(request, cache);Creates cacheable HTTP requests with configurable caching options.
/**
* Creates a cacheable HTTP request
* @param options - Request options or URL string
* @param callback - Optional response callback
* @returns Event emitter for request lifecycle
*/
type CacheableRequestFunction = (
options: CacheableOptions,
callback?: (response: CacheResponse) => void
) => Emitter;
type CacheableOptions = Options & RequestOptions | string | URL;
interface Options {
/** Enable/disable caching for this request (default: true) */
cache?: boolean;
/** Delete expired entries instead of revalidating (default: false) */
strictTtl?: boolean;
/** Maximum TTL in milliseconds */
maxTtl?: number;
/** Fallback to network on cache errors (default: false) */
automaticFailover?: boolean;
/** Force refresh even if cached (default: false) */
forceRefresh?: boolean;
/** Include remote address in response data */
remoteAddress?: boolean;
/** URL string for the request */
url?: string;
/** Request headers */
headers?: Record<string, string | string[] | undefined>;
/** Request body for POST/PUT/PATCH */
body?: Buffer;
}Usage Examples:
// String URL
const req1 = cacheableRequest("https://api.example.com/users");
// URL object
const url = new URL("https://api.example.com/users");
const req2 = cacheableRequest(url);
// Options object
const req3 = cacheableRequest({
hostname: "api.example.com",
port: 443,
path: "/users",
method: "GET",
cache: true,
maxTtl: 60000, // 1 minute max TTL
headers: {
"User-Agent": "MyApp/1.0"
}
});
// With callback
const req4 = cacheableRequest("https://api.example.com/users", (response) => {
console.log("Cached:", response.fromCache);
console.log("Status:", response.statusCode);
});Fine-grained control over caching behavior for individual requests.
interface CachingBehavior {
/** Completely bypass cache for this request */
cache: false;
/** Use cache with strict TTL enforcement */
strictTtl: true;
maxTtl: number;
/** Force refresh from origin server */
forceRefresh: true;
/** Automatic failover on cache errors */
automaticFailover: true;
}Usage Examples:
// Bypass cache completely
const freshData = cacheableRequest({
hostname: "api.example.com",
path: "/live-data",
cache: false
});
// Strict TTL with 5 minute maximum
const shortCached = cacheableRequest({
hostname: "api.example.com",
path: "/user-data",
strictTtl: true,
maxTtl: 300000 // 5 minutes
});
// Force refresh existing cache
const refreshed = cacheableRequest({
hostname: "api.example.com",
path: "/cached-data",
forceRefresh: true
});
// With automatic failover
const reliable = cacheableRequest({
hostname: "api.example.com",
path: "/important-data",
automaticFailover: true
});Handling cached and fresh responses with cache metadata.
type CacheResponse = ServerResponse | typeof ResponseLike;
interface CachedResponse extends CacheResponse {
/** Indicates if response came from cache */
fromCache: boolean;
/** Cache policy information */
cachePolicy: CachePolicy;
/** Standard HTTP response properties */
statusCode: number;
headers: IncomingHttpHeaders;
url: string;
}Usage Examples:
const req = cacheableRequest("https://api.example.com/data", (response) => {
if (response.fromCache) {
console.log("Served from cache");
console.log("Cache age:", response.cachePolicy.age());
} else {
console.log("Fresh from server");
console.log("Cacheable:", response.cachePolicy.storable());
}
let data = "";
response.on("data", chunk => data += chunk);
response.on("end", () => {
console.log("Response data:", data);
});
});type RequestFn = typeof request;
interface CacheValue {
url: string;
statusCode: number;
body: Buffer | string;
cachePolicy: CachePolicyObject;
[key: string]: any;
}
interface UrlOption {
path: string;
pathname?: string;
search?: string;
}