Big News: Socket raises $60M Series C at a $1B valuation to secure software supply chains for AI-driven development.Announcement
Sign In

@isdk/proxy

Package Overview
Dependencies
Maintainers
1
Versions
7
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@isdk/proxy

A framework-agnostic, high-performance hybrid caching middleware with SWR, request collapsing, and stale-if-error support.

Source
npmnpm
Version
0.2.0
Version published
Weekly downloads
13
-79.03%
Maintainers
1
Weekly downloads
 
Created
Source

@isdk/proxy

A high-performance, developer-friendly cache proxy engine for Node.js designed to handle the complexity of HTTP response caching in data-intensive applications.

Why @isdk/proxy?

In scenarios like high-concurrency API proxies, web crawlers, or microservices, cache management often requires compromises between "speed" and "capacity". @isdk/proxy solves this with its unique architecture:

  • Two-Pass Pipeline: Features a decoupled pipeline for "Gatekeeping" (determining cacheability) and "Fingerprinting" (generating cache keys). Both stages use the same configuration logic, achieving full semantic orthogonality.
  • Metadata Residency: Metadata (Headers, Status, Policy) always resides in memory, ensuring nanosecond-level cache validity assessment regardless of response body size.
  • Request Coalescing: Prevents cache stampedes by ensuring only one concurrent request is sent to the origin when a hot cache expires.
  • Environment Agnostic: Built on Web Standard Request/Response objects. Works anywhere.

Core Features

  • 🚀 Hybrid Multi-tier Cache: L1 (LRU memory) for instant response, L2 (content-addressable disk cacache) for persistent storage.
  • 📥 HTTP POST & Multi-method Support: Full support for caching POST, PUT, and other non-GET methods with intelligent body fingerprinting.
  • 🎯 Granular Interception: Surgical precision in cache control via rules for specific paths or fields.
  • 🌊 Native Streaming: Built entirely on stream pipelines to prevent OOM when proxying large files.
  • 🧠 Intelligent Metadata Residency: Metadata (Headers, Status, Policy) stays in memory for instant policy decisions.
  • 🔄 Stale-While-Revalidate (SWR): Returns stale data instantly while updating the cache in the background.
  • 🛡️ Request Coalescing: Merges concurrent requests for the same resource to protect upstream servers.
  • 🚑 High Resiliency: Automatically returns stale cache on backend failure (staleIfError) or forces caching regardless of origin directives (forceCache).
  • 🕵️ Transparent Status: Injects x-proxy-cache header (HIT, STALE, MISS, STALE_IF_ERROR) for easy debugging.

Installation

pnpm add @isdk/proxy

Quick Start: Core Coordination

The primary way to use @isdk/proxy is through the fetchWithCache function, which can wrap any HTTP request logic.

Basic Usage (GET Request)

import { SmartCache, createCachedFetch } from '@isdk/proxy';

// 1. Initialize hybrid cache instance
const cache = new SmartCache({
  storagePath: './.cache',
  maxMemorySize: 1024 * 1024 // 1MB memory threshold
});

// 2. Create a pre-configured cached fetcher
const myFetch = createCachedFetch({
  cache,
  config: {
    staleIfError: true,
  },
  backgroundUpdate: true // Enable SWR
});

// 3. Use it!
const response = await myFetch(new Request('https://api.example.com/data'), (req) => fetch(req));
console.log(response.headers.get('x-proxy-cache'));

Advanced: POST Requests & Field Filtering

Configure methods to enable POST caching and use field filters to ensure cache key stability.

const myPostFetch = createCachedFetch({
  cache,
  config: {
    methods: ['GET', 'POST'],
    // Query filtering: defaults to all, here excluding 'timestamp'
    query: ['*', '!timestamp'],
    // Body filtering: field-level matching for JSON
    body: {
      match: { 'action': 'query', 'version': true },
      maxLength: 1024 // Limit body read length
    },
    rules: [
      { methods: ['POST'], path: '/api/v1/query' }
    ],
    forceCache: true
  }
});

Configuration Reference

ProxySiteConfig

OptionTypeDescription
pathMatchPatternsPath gatekeeping. Supports Glob, Regex, or Negation.
methodsMatchPatternsAllowed HTTP methods. Default ['GET', 'HEAD'].
rulesProxyCacheRule[]Granular rules. Matched rules are deeply merged with site-level config.
queryFieldConfigQuery parameter filtering. Defaults to all.
headersFieldConfigHeader filtering. Defaults to none.
cookiesFieldConfigCookie filtering. Defaults to none.
bodyBodyConfigBody matching & extraction.
staleIfErrorbooleanReturn stale cache on backend errors.
forceCachebooleanForce caching regardless of origin directives.
offlinebooleanStrict offline mode: Read-only cache.

MatchPatterns Syntax

@isdk/proxy provides powerful matching capabilities with negation support:

TypeExampleDescription
Negation['*', '!/api/private/**']Exclude matching (starts with !).
Glob/**/*.jsonPath-style glob matching.
Regex String"/^api\\/v\\d/"Automatically converted to RegExp object.
Boolean (Field)true / falseRequired / forbidden.

[!TIP] Exclusion Priority: In a MatchPatterns array, if any ! pattern matches, the overall result is false.

Advanced Matching & Boundary Cases

@isdk/proxy distinguishes between two complementary matching modes: MatchPatterns Mode and Record Mode. Understanding their differences is crucial for robust configuration.

1. MatchPatterns Mode

  • Types: string | RegExp | Array
  • Semantic: Existence Filter. "At least one field in the request must match this pattern."
  • Logic: Based on some logic.
Config ExampleSemanticResult for Empty Request
['*']Pass if any field exists.❌ Blocked (No keys to match)
['id', 'name']Must contain 'id' or 'name'.❌ Blocked
['*', '!sid']Must contain fields other than 'sid'.❌ Blocked
[] (Empty Array)Block all (No key can match an empty array).❌ Blocked

[!TIP] MatchPatterns is best for Whitelists or coarse Blacklists. e.g., query: ['id'] means "the request must have an id parameter and will be cached based ONLY on that id."

2. Record Mode

  • Types: Record<string, ProxyMatchPatterns | boolean>
  • Semantic: Field Validation. Logic declarations for specific keys.
  • Logic: Based on AND logic.
Config ExampleSemanticResult for Empty Request
{} (Empty Object)No validation rules.✅ Pass
{ sid: true }Explicitly requires 'sid' to exist.❌ Blocked
{ sid: false }Explicitly requires 'sid' to NOT exist.✅ Pass
{ lang: 'en' }Requires 'lang' to exist and match 'en'.❌ Blocked

3. Boundary Cases Summary

ConfigurationMatching ResultRecommended Usage
undefinedPass (Ignored)Default: no gatekeeping check for this category.
{} (Empty Object)Pass (Valid)No rules defined means everything is allowed.
[] (Empty Array)Fail (Invalid)No key can pass an empty matching set.
Empty RequestDepends on Categoryquery passes by default; headers/cookies fail by default.

Architecture: Two-Pass Logic

  • First Pass: Gatekeeping Uses path, methods, etc., to determine if the request is eligible for caching.
  • Second Pass: Fingerprinting Uses the same field configurations to implicitly perform data extraction. For example, if query is ['*', '!token'], the extraction phase automatically strips token before hashing.

Adapters

  • Node.js Server: @isdk/proxy-server.
  • Crawlee Adapter: @isdk/proxy-crawlee.
  • MSW Adapter: @isdk/proxy-msw.

API Reference

A high-level factory function for end users. It automatically maintains the concurrency tracker in an internal closure and returns a production-ready Fetch instance with built-in cache stampede protection.

  • options.cache: A SmartCache instance.
  • options.config: Global configuration object (ProxyConfig).
  • options.backgroundUpdate: Whether to enable SWR (Stale-While-Revalidate). Defaults to true.
  • options.onBackgroundUpdate: Callback that receives the background update Promise when triggered.
  • options.activeCacheWrites: Optional. Shared concurrency tracker Map.
  • Returns: A wrapped fetch function (request, fetcher) => Promise<Response>.

createFetchWithCache(activeCacheWrites?)

A single-responsibility utility for isolating the activeCacheWrites concurrency tracker. Use this if you are building middleware and want to avoid manual tracker management.

  • activeCacheWrites: Optional. An external Map<string, Promise<void>>.
  • Returns: A fetchWithCache variant bound to the tracker.

fetchWithCache(request, fetcher, options)

The low-level core coordination function.

  • request: Web Standard Request object.
  • fetcher: Origin request callback (req: Request) => Promise<Response>.
  • options.activeCacheWrites: Required. Shared lock state Map.
  • options.cache: SmartCache instance.
  • options.config: ProxySiteConfig configuration.
  • options.backgroundUpdate: Whether to enable SWR.

SmartCache

The core engine managing multi-tier hybrid storage.

  • new SmartCache(options)
  • options.maxMemorySize: Threshold (in bytes) for storing response bodies in memory (L1). Bodies larger than this stream directly to disk (default 1048576, i.e., 1MB).
  • options.storagePath: Physical path for the disk L2 cache (cacache).

Utility Functions

isMatch(pattern, value, usePrefix?, defaultIfNoPositives?, ignoreCase?)

Universal matching function supporting Regex, Glob, Negation patterns, and simple strings.

  • pattern: string | RegExp | (string | RegExp)[]
  • value: The string to test.
  • usePrefix: Whether to use prefix matching for simple strings (default: false).
  • defaultIfNoPositives: Return value when no positive patterns match (default: true).
  • ignoreCase: Whether to perform case-insensitive matching (default: true).
import { isMatch } from '@isdk/proxy';

isMatch('/api/v[12]/.*', '/api/v1/users');           // Regex
isMatch('/api/**/*.json', '/api/v1/data.json');       // Glob
isMatch(['*', '!/private/**'], '/api/data');         // Negation: Allow all except private
isMatch(['!id'], 'id', false, false);                // Returns false (no positive match)

isGlob(pattern)

Checks if a string is a Glob pattern.

  • pattern: string
  • Returns: boolean
import { isGlob } from '@isdk/proxy';

isGlob('/api/*.json'); // true
isGlob('/api/v1');     // false

getSiteConfig(urlString, proxyConfig)

Retrieves site-specific cache configuration based on the URL. It first tries to match hostnames or path prefixes in sites, otherwise falls back to proxyConfig.

  • urlString: The complete request URL.
  • proxyConfig: The ProxyConfig object containing sites and global rules.
  • Returns: A ProxySiteConfig object.
import { getSiteConfig } from '@isdk/proxy';

const config = getSiteConfig('https://api.example.com/data', {
  methods: ['GET'],
  sites: {
    'api.example.com': { forceCache: true }, // Hostname match
    '/internal/': { offline: true }          // Path prefix match
  }
});
import { getSiteConfig } from '@isdk/proxy';

const config = getSiteConfig('https://api.example.com/data', {
  methods: ['GET'],
  sites: {
    'api.example.com': { forceCache: true }, // Hostname match
    '/internal/': { offline: true }          // Path prefix match
  }
});

isAllowed(key, config, defaultAllowed?)

Determines if a specific key (e.g., header name) is allowed in fingerprinting.

  • key: The key name.
  • config: ProxyMatchPatterns configuration.
  • defaultAllowed: Default policy if no patterns match.
import { isAllowed } from '@isdk/proxy';

isAllowed('id', ['id', 'name']);           // true (Whitelist)
isAllowed('auth', ['*', '!auth']);         // false (Blacklist)
isAllowed('other', ['!id'], false, false); // false (Default denied)

extractData(source, config, defaultAllowed?)

Extracts and normalizes data from source objects. Used for fingerprinting.

  • source: The original data object.
  • config: ProxyFieldConfig or ProxyMatchPatterns.
  • defaultAllowed: Default extraction policy.
import { extractData } from '@isdk/proxy';

const headers = { 'Content-Type': 'application/json', 'X-Token': 'abc' };

// Array mode: filter Keys
extractData(headers, ['content-type']); // { 'content-type': ['application/json'] }

// Object mode: precise Value matching
extractData(headers, {
  'content-type': '/^application\/.*/'
}); // { 'content-type': ['application/json'] }

prefetch(options)

Prefetch function to populate the cache with a specified list of URLs.

  • options.urls: PrefetchRequest[].

  • options.config: Full ProxyConfig.

  • options.cache: SmartCache instance.

  • options.concurrency: Concurrency limit (default 3).

  • options.onProgress: Progress callback (completed, total, url) => void.

  • Returns: Promise<PrefetchResult>

    • succeeded: Number of successfully prefetched requests.
    • failed: Number of failures.
    • errors: List of failure details { url, error }[].
import { prefetch } from '@isdk/proxy';

const result = await prefetch({
  urls: [{ url: 'https://api.com/page1' }],
  config,
  cache,
  onProgress: (c, t, url) => console.log(`${c}/${t}: ${url}`)
});
console.log(`Succeeded: ${result.succeeded}, Failed: ${result.failed}`);

Error Handling: OfflineCacheMissError

Thrown when offline: true is enabled and the request misses the cache.

  • name: OfflineCacheMissError
  • code: 512 (Custom status code)
import { OfflineCacheMissError } from '@isdk/proxy';

try {
  await myFetch(request);
} catch (e) {
  if (e instanceof OfflineCacheMissError) {
    // Handle cache miss
  }
}

Cache Status Headers

Responses managed by @isdk/proxy include the x-proxy-cache header:

  • HIT: Cache hit.
  • MISS: Cache miss, fetched from origin.
  • STALE: Stale hit (triggered background SWR update).
  • STALE_IF_ERROR: Origin failed, returned stale cache as fallback.

License

MIT

Keywords

cache

FAQs

Package last updated on 12 May 2026

Did you know?

Socket

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Install

Related posts