or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

docs

core-caching.mdevents.mdhooks.mdindex.mdstorage.md
tile.json

hooks.mddocs/

Hook System

Response processing hooks allow modification of cached data before storage. The hook system enables data transformation, compression, metadata addition, and custom processing of responses before they are cached.

Capabilities

Adding Hooks

Register hooks to process responses before caching.

/**
 * Add a response processing hook
 * @param name - Hook identifier (commonly 'onResponse')
 * @param fn - Hook function that processes the cache value
 */
addHook(name: string, fn: Function): void;

Usage Examples:

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

const cacheableRequest = new CacheableRequest(request);

// Add hook for response decompression
cacheableRequest.addHook("onResponse", async (value, response) => {
  if (response.headers["content-encoding"] === "gzip") {
    const buffer = await gunzip(value.body);
    value.body = buffer.toString();
  }
  return value;
});

// Add hook for metadata enrichment
cacheableRequest.addHook("onResponse", (value, response) => {
  // Add remote address to cached data
  if (response.connection) {
    value.remoteAddress = response.connection.remoteAddress;
  }
  
  // Add timestamp
  value.cachedAt = new Date().toISOString();
  
  return value;
});

const cachedHttp = cacheableRequest.request();

Removing Hooks

Remove previously registered hooks.

/**
 * Remove a registered hook
 * @param name - Hook identifier to remove
 * @returns True if hook was removed, false if not found
 */
removeHook(name: string): boolean;

Usage Examples:

// Remove specific hook
const removed = cacheableRequest.removeHook("onResponse");
if (removed) {
  console.log("Hook removed successfully");
} else {
  console.log("Hook not found");
}

Retrieving Hooks

Get reference to registered hook functions.

/**
 * Get a registered hook function
 * @param name - Hook identifier
 * @returns Hook function or undefined if not found
 */
getHook(name: string): Function | undefined;

Usage Examples:

// Check if hook exists
const hook = cacheableRequest.getHook("onResponse");
if (hook) {
  console.log("onResponse hook is registered");
} else {
  console.log("No onResponse hook found");
}

Running Hooks

Execute hooks manually (primarily used internally).

/**
 * Execute a registered hook
 * @param name - Hook identifier
 * @param value - Cache value to process
 * @param response - HTTP response object
 * @returns Promise resolving to processed cache value
 */
runHook(name: string, value: CacheValue, response: any): Promise<CacheValue>;

Usage Examples:

// Manually run hook (advanced usage)
const processedValue = await cacheableRequest.runHook("onResponse", cacheValue, response);

Hook Function Signatures

Standard hook function patterns and expected signatures.

/**
 * Standard response hook function signature
 * @param value - Cache value to be stored
 * @param response - HTTP response object
 * @returns Modified cache value or Promise<CacheValue>
 */
type ResponseHook = (
  value: CacheValue,
  response: any
) => CacheValue | Promise<CacheValue>;

Common Hook Patterns:

// Synchronous transformation
cacheableRequest.addHook("onResponse", (value, response) => {
  // Transform body to JSON
  if (typeof value.body === "string") {
    try {
      value.parsedBody = JSON.parse(value.body);
    } catch (e) {
      value.parseError = e.message;
    }
  }
  return value;
});

// Asynchronous processing
cacheableRequest.addHook("onResponse", async (value, response) => {
  // Compress response body
  if (value.body.length > 1024) {
    value.body = await compress(value.body);
    value.compressed = true;
  }
  return value;
});

// Conditional processing
cacheableRequest.addHook("onResponse", (value, response) => {
  // Only process successful responses
  if (value.statusCode >= 200 && value.statusCode < 300) {
    value.success = true;
    value.processedAt = Date.now();
  }
  return value;
});

Multiple Hooks

Managing multiple hooks for complex processing pipelines.

interface HookChain {
  /** Hooks are executed in the order they were added */
  executionOrder: "sequential";
  
  /** Each hook receives the output of the previous hook */
  chaining: "piped";
}

Usage Examples:

const cacheableRequest = new CacheableRequest(request);

// Hook 1: Parse JSON
cacheableRequest.addHook("onResponse", (value, response) => {
  if (response.headers["content-type"]?.includes("application/json")) {
    try {
      value.json = JSON.parse(value.body.toString());
    } catch (e) {
      value.jsonError = e.message;
    }
  }
  return value;
});

// Hook 2: Extract metadata
cacheableRequest.addHook("onResponse", (value, response) => {
  if (value.json) {
    value.metadata = {
      recordCount: Array.isArray(value.json) ? value.json.length : 1,
      hasData: Boolean(value.json),
    };
  }
  return value;
});

// Hook 3: Compress large responses
cacheableRequest.addHook("onResponse", async (value, response) => {
  if (value.body.length > 10000) {
    value.body = await compress(value.body);
    value.compressed = true;
  }
  return value;
});

Error Handling in Hooks

Proper error handling within hook functions.

type SafeHook = (value: CacheValue, response: any) => CacheValue | Promise<CacheValue>;

Usage Examples:

// Error handling in hooks
cacheableRequest.addHook("onResponse", async (value, response) => {
  try {
    // Potentially failing operation
    value.processed = await riskyOperation(value.body);
  } catch (error) {
    // Don't throw - just add error info
    value.processingError = error.message;
    console.warn("Hook processing failed:", error);
  }
  
  // Always return the value
  return value;
});

// Conditional hook execution
cacheableRequest.addHook("onResponse", (value, response) => {
  // Only process if certain conditions are met
  if (value.statusCode === 200 && value.body) {
    try {
      value.enhanced = enhanceData(value.body);
    } catch (error) {
      value.enhancementError = error.message;
    }
  }
  return value;
});

Types

interface CacheValue {
  url: string;
  statusCode: number;
  body: Buffer | string;
  cachePolicy: CachePolicyObject;
  
  /** Hook functions can add any additional properties */
  [key: string]: any;
}

type HookFunction = (
  value: CacheValue,
  response: any
) => CacheValue | Promise<CacheValue>;