CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/npm-metro-cache

Cache layers for Metro bundler with multi-layered caching system supporting local file storage and remote HTTP caching

Pending
Quality

Pending

Does it follow best practices?

Impact

Pending

No eval scenarios have been run

SecuritybySnyk

Pending

The risk profile of this skill

Overview
Eval results
Files

http-stores.mddocs/

HTTP Storage

HTTP/HTTPS-based remote cache stores with compression, retry logic, and proxy support for distributed caching scenarios. Enables teams to share cached build artifacts across development environments.

Capabilities

HttpStore

Full-featured HTTP cache store with compression, authentication, and comprehensive retry logic for reliable remote caching.

/**
 * Remote HTTP/HTTPS cache store with compression and retry support
 * Supports both read and write operations to remote cache servers
 * @template T - Type of cached values
 */
class HttpStore<T> {
  /**
   * Create a new HTTP store instance
   * @param options - Configuration options for HTTP endpoints and behavior
   */
  constructor(options: HttpOptions);
  
  /**
   * Retrieve cached value via HTTP GET request
   * @param key - Cache key as Buffer (sent as hex in URL path)
   * @returns Promise resolving to cached value or null if not found
   * @throws HttpError for HTTP errors, NetworkError for connectivity issues
   */
  get(key: Buffer): Promise<T | null>;
  
  /**
   * Store value via HTTP PUT request with gzip compression
   * @param key - Cache key as Buffer (sent as hex in URL path)
   * @param value - Value to cache (JSON serializable or Buffer)
   * @returns Promise that resolves when storage is complete
   * @throws HttpError for HTTP errors, NetworkError for connectivity issues
   */
  set(key: Buffer, value: T): Promise<void>;
  
  /**
   * Clear operation is not implemented for HTTP stores
   * @returns void (no-op)
   */
  clear(): void;
  
  /**
   * Reference to HttpError class for error handling
   */
  static HttpError: typeof HttpError;
  
  /**
   * Reference to NetworkError class for error handling
   */
  static NetworkError: typeof NetworkError;
}

Usage Examples:

const { HttpStore } = require("metro-cache");

// Basic HTTP store
const httpStore = new HttpStore({
  endpoint: "https://cache.company.com/api/v1/cache"
});

// HTTP store with authentication and custom settings
const authenticatedStore = new HttpStore({
  endpoint: "https://secure-cache.example.com/cache",
  timeout: 10000,
  headers: {
    "Authorization": "Bearer " + process.env.CACHE_TOKEN,
    "X-Team-ID": "frontend-team"
  },
  maxAttempts: 3,
  retryStatuses: new Set([502, 503, 504])
});

// Different endpoints for read vs write operations
const asymmetricStore = new HttpStore({
  getOptions: {
    endpoint: "https://read-cache.example.com/get",
    timeout: 5000
  },
  setOptions: {
    endpoint: "https://write-cache.example.com/put", 
    timeout: 15000,
    headers: { "Authorization": "Bearer " + writeToken }
  }
});

// Usage
try {
  const result = await httpStore.get(cacheKey);
  if (result === null) {
    const computed = processData();
    await httpStore.set(cacheKey, computed);
  }
} catch (error) {
  if (error instanceof HttpStore.HttpError) {
    console.log("HTTP error:", error.code, error.message);
  } else if (error instanceof HttpStore.NetworkError) {
    console.log("Network error:", error.code, error.message);
  }
}

HttpGetStore

Read-only HTTP cache store that converts errors to warnings, ideal for optional remote cache access that shouldn't break builds.

/**
 * Read-only HTTP cache store that warns on connection errors
 * Extends HttpStore but converts all errors to warnings and returns null
 * Perfect for optional remote caches that shouldn't break builds
 * @template T - Type of cached values
 */
class HttpGetStore<T> extends HttpStore<T> {
  /**
   * Create a new read-only HTTP store instance
   * @param options - HTTP configuration options
   */
  constructor(options: HttpOptions);
  
  /**
   * Retrieve cached value with error handling that converts errors to warnings
   * @param key - Cache key as Buffer
   * @returns Promise resolving to cached value or null (never throws)
   */
  get(key: Buffer): Promise<T | null>;
  
  /**
   * No-op set operation (read-only store)
   * @returns Promise resolving to undefined immediately
   */
  set(): Promise<void>;
}

Usage Examples:

const { HttpGetStore } = require("metro-cache");

// Read-only cache that won't break builds if unavailable
const optionalCache = new HttpGetStore({
  endpoint: "https://shared-cache.example.com/readonly",
  timeout: 3000  // Short timeout since it's optional
});

// Always succeeds - errors become warnings
const cached = await optionalCache.get(key);
if (cached !== null) {
  console.log("Found in shared cache");
  return cached;
}

// Continue with normal processing if cache unavailable
const result = processData();
// Note: set() is a no-op for HttpGetStore
return result;

HTTP Configuration

HttpOptions Type

/**
 * Configuration options for HTTP cache stores
 * Can specify unified options or separate read/write configurations
 */
type HttpOptions = EndpointOptions | {
  getOptions: EndpointOptions;
  setOptions: EndpointOptions;
};

/**
 * Configuration for a single HTTP endpoint
 */
interface EndpointOptions {
  /**
   * HTTP endpoint URL (required)
   */
  endpoint: string;
  
  /**
   * IP family preference (4 for IPv4, 6 for IPv6)
   */
  family?: 4 | 6;
  
  /**
   * Request timeout in milliseconds (default: 5000)
   */
  timeout?: number;
  
  /**
   * TLS client key for mutual authentication
   */
  key?: string | Array<string> | Buffer | Array<Buffer>;
  
  /**
   * TLS client certificate for mutual authentication
   */
  cert?: string | Array<string> | Buffer | Array<Buffer>;
  
  /**
   * TLS certificate authority certificates
   */
  ca?: string | Array<string> | Buffer | Array<Buffer>;
  
  /**
   * URL query parameters to include in requests
   */
  params?: URLSearchParams;
  
  /**
   * HTTP headers to include in requests
   */
  headers?: { [string]: string };
  
  /**
   * Additional HTTP status codes to treat as successful
   */
  additionalSuccessStatuses?: Array<number>;
  
  /**
   * Whether to include detailed error information in exceptions
   */
  debug?: boolean;
  
  /**
   * Maximum number of retry attempts (default: 1)
   */
  maxAttempts?: number;
  
  /**
   * Whether to retry on network connectivity errors
   */
  retryNetworkErrors?: boolean;
  
  /**
   * HTTP status codes that should trigger retries
   */
  retryStatuses?: Set<number>;
  
  /**
   * Unix socket path for HTTP requests
   */
  socketPath?: string;
  
  /**
   * HTTP proxy URL
   */
  proxy?: string;
}

Protocol Details

Request Format

  • GET Requests: {endpoint}/{keyAsHex}?{params}
  • PUT Requests: {endpoint}/{keyAsHex}?{params} with gzipped body
  • Compression: All data is compressed with gzip (level 9)
  • Content Encoding: Responses are automatically decompressed

Data Serialization

HTTP stores handle data serialization automatically:

  • JavaScript Objects: JSON serialized then gzipped
  • Buffer Data: Binary data prefixed with null byte (0x00) then gzipped
  • Response Handling: Automatic detection of JSON vs binary data

Error Handling

HTTP stores provide comprehensive error handling:

  • 404 Responses: Treated as cache miss (returns null)
  • HTTP Errors: Thrown as HttpError with status code
  • Network Errors: Thrown as NetworkError with error code
  • Retry Logic: Configurable exponential backoff for transient failures

Retry Configuration

The retry system uses exponential backoff with full jitter (via the exponential-backoff npm package):

  • Backoff Strategy: Exponential with full jitter
  • Maximum Delay: 30 seconds between attempts
  • Retry Conditions: Based on error type and configured status codes
  • Network Errors: Only retried if retryNetworkErrors is true

docs

cache-management.md

file-stores.md

http-stores.md

index.md

utilities.md

tile.json