CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/npm-cacheable-request

Wrap native HTTP requests with RFC compliant cache support

Pending

Quality

Pending

Does it follow best practices?

Impact

Pending

No eval scenarios have been run

Overview
Eval results
Files

storage.mddocs/

Storage Configuration

Configuration and setup of cache storage adapters using Keyv. Cacheable Request supports various storage backends including in-memory, Redis, SQLite, MongoDB, and custom adapters for flexible cache persistence.

Capabilities

Default In-Memory Storage

Built-in memory storage that requires no additional configuration.

/**
 * Creates cacheable request with default in-memory storage
 * Uses Keyv with namespace 'cacheable-request'
 */
class CacheableRequest {
  cache: Keyv;
  constructor(cacheRequest: RequestFn);
}

Usage Examples:

import CacheableRequest from "cacheable-request";
import { request } from "node:http";

// Default in-memory cache
const cacheableRequest = new CacheableRequest(request);

// Access the cache instance
console.log(cacheableRequest.cache); // Keyv instance with Map store

Keyv Storage Adapters

Integration with official Keyv storage adapters for persistent caching.

/**
 * Creates cacheable request with custom Keyv storage adapter
 * @param cacheRequest - HTTP request function
 * @param cacheAdapter - Keyv instance or compatible storage adapter
 */
constructor(cacheRequest: RequestFn, cacheAdapter: Keyv | any);

Usage Examples:

import CacheableRequest from "cacheable-request";
import { Keyv } from "keyv";
import KeyvRedis from "@keyv/redis";
import KeyvSQLite from "@keyv/sqlite";

// Redis storage
const redisStore = new KeyvRedis("redis://localhost:6379");
const cacheableRedis = new CacheableRequest(request, redisStore);

// SQLite storage
const sqliteStore = new KeyvSQLite("cache.sqlite");
const cacheableSQLite = new CacheableRequest(request, sqliteStore);

// Pre-configured Keyv instance
const keyv = new Keyv({
  store: new KeyvRedis("redis://localhost:6379"),
  namespace: "my-app-cache",
  ttl: 3600000 // 1 hour default TTL
});
const cacheableCustom = new CacheableRequest(request, keyv);

Storage Adapter Types

Supported storage adapters and their use cases.

interface StorageOptions {
  /** In-memory storage (default) */
  memory: Map;
  
  /** Redis for distributed caching */
  redis: string | KeyvRedis;
  
  /** SQLite for persistent local caching */
  sqlite: string | KeyvSQLite;
  
  /** MongoDB for document-based caching */
  mongodb: string | KeyvMongoDB;
  
  /** PostgreSQL for relational caching */
  postgresql: string | KeyvPostgreSQL;
  
  /** MySQL for relational caching */
  mysql: string | KeyvMySQL;
  
  /** Memcached for distributed memory caching */
  memcached: string | KeyvMemcached;
}

Usage Examples:

// Redis with connection string
const redisCache = new CacheableRequest(
  request,
  new KeyvRedis("redis://user:pass@localhost:6379/0")
);

// SQLite with file path
const sqliteCache = new CacheableRequest(
  request,
  new KeyvSQLite("./cache/requests.sqlite")
);

// MongoDB with connection string
import KeyvMongoDB from "@keyv/mongo";
const mongoCache = new CacheableRequest(
  request,
  new KeyvMongoDB("mongodb://localhost:27017/cache")
);

Custom Storage Adapters

Using custom storage solutions that implement the Map interface.

/**
 * Custom storage adapter requirements
 * Must implement basic Map interface methods
 */
interface CustomStorageAdapter {
  get(key: string): Promise<any> | any;
  set(key: string, value: any, ttl?: number): Promise<boolean> | boolean;
  delete(key: string): Promise<boolean> | boolean;
  clear(): Promise<void> | void;
}

Usage Examples:

// Custom LRU cache adapter
import QuickLRU from "quick-lru";

const lruCache = new QuickLRU({ maxSize: 1000 });
const cacheableLRU = new CacheableRequest(request, lruCache);

// Custom adapter implementation
class CustomAdapter {
  private store = new Map();
  
  async get(key) {
    return this.store.get(key);
  }
  
  async set(key, value, ttl) {
    this.store.set(key, value);
    if (ttl) {
      setTimeout(() => this.store.delete(key), ttl);
    }
    return true;
  }
  
  async delete(key) {
    return this.store.delete(key);
  }
  
  async clear() {
    this.store.clear();
  }
}

const customCache = new CacheableRequest(request, new CustomAdapter());

Storage Configuration Options

Advanced configuration options for storage adapters.

interface KeyvOptions {
  /** Storage adapter instance */
  store?: any;
  
  /** Namespace for cache keys */
  namespace?: string;
  
  /** Default TTL in milliseconds */
  ttl?: number;
  
  /** Custom serialization */
  serialize?: (data: any) => string;
  deserialize?: (data: string) => any;
  
  /** Adapter-specific options */
  [key: string]: any;
}

Usage Examples:

import { Keyv } from "keyv";
import KeyvRedis from "@keyv/redis";

// Advanced Keyv configuration
const keyv = new Keyv({
  store: new KeyvRedis("redis://localhost:6379"),
  namespace: "cacheable-request-v2",
  ttl: 1800000, // 30 minutes default
  serialize: JSON.stringify,
  deserialize: JSON.parse
});

const cacheableRequest = new CacheableRequest(request, keyv);

// Multiple namespaces for different endpoints
const apiCache = new Keyv({
  store: new KeyvRedis("redis://localhost:6379"),
  namespace: "api-cache",
  ttl: 300000 // 5 minutes
});

const staticCache = new Keyv({
  store: new KeyvRedis("redis://localhost:6379"),
  namespace: "static-cache",
  ttl: 3600000 // 1 hour
});

const apiRequests = new CacheableRequest(request, apiCache);
const staticRequests = new CacheableRequest(request, staticCache);

Cache Access and Management

Direct access to the underlying cache for management operations.

interface CacheableRequest {
  /** Direct access to Keyv cache instance */
  cache: Keyv;
}

interface CacheManagement {
  /** Get cached value directly */
  get(key: string): Promise<any>;
  
  /** Set cached value directly */
  set(key: string, value: any, ttl?: number): Promise<boolean>;
  
  /** Delete cached value */
  delete(key: string): Promise<boolean>;
  
  /** Clear entire cache */
  clear(): Promise<void>;
}

Usage Examples:

const cacheableRequest = new CacheableRequest(request, redisStore);

// Direct cache operations
await cacheableRequest.cache.set("custom-key", { data: "value" }, 60000);
const cached = await cacheableRequest.cache.get("custom-key");
await cacheableRequest.cache.delete("custom-key");

// Cache statistics (if supported by adapter)
if (cacheableRequest.cache.store.stats) {
  console.log("Cache stats:", cacheableRequest.cache.store.stats());
}

// Clear entire cache
await cacheableRequest.cache.clear();

Error Handling for Storage

Handling storage-related errors and failover strategies.

interface StorageErrorHandling {
  /** Enable automatic failover on storage errors */
  automaticFailover: boolean;
  
  /** Storage error event handling */
  onStorageError: (error: Error) => void;
}

Usage Examples:

import { Keyv } from "keyv";
import KeyvRedis from "@keyv/redis";

// Setup with error handling
const keyv = new Keyv({
  store: new KeyvRedis("redis://localhost:6379")
});

// Listen for storage errors
keyv.on("error", (error) => {
  console.error("Cache storage error:", error);
  // Handle Redis connection issues, etc.
});

const cacheableRequest = new CacheableRequest(request, keyv);

// Use automatic failover for requests
const req = cacheableRequest({
  hostname: "api.example.com",
  path: "/data",
  automaticFailover: true // Falls back to network on cache errors
});

Types

interface Keyv {
  get(key: string): Promise<any>;
  set(key: string, value: any, ttl?: number): Promise<boolean>;
  delete(key: string): Promise<boolean>;
  clear(): Promise<void>;
  on(event: string, listener: Function): this;
}

interface StorageAdapter {
  get(key: string): any;
  set(key: string, value: any, ttl?: number): any;
  delete(key: string): boolean;
  clear?(): void;
}

Install with Tessl CLI

npx tessl i tessl/npm-cacheable-request

docs

core-caching.md

events.md

hooks.md

index.md

storage.md

tile.json