Skip to content

v4.0.0

Latest

Choose a tag to compare

@kuitos kuitos released this 04 Apr 16:55
· 6 commits to master since this release
974a7eb

πŸš€ v4.0.0

A major release that modernizes the entire stack and ships features the community has been asking for β€” while making the cache API significantly cleaner.

πŸ’₯ Breaking Changes

Node.js >= 18 and axios >= 1.0.0 required

v4 drops support for legacy runtimes. Upgrade Node and axios before updating.

Cache options consolidated: enabledByDefault & cacheFlag removed

The old multi-knob cache config (enabledByDefault, cacheFlag) is replaced by a single cacheable predicate:

cacheAdapterEnhancer(adapter, {
  cacheable: (config) => config.method === 'get',
});

Quick migration recipes:

// v3: opt-in caching
cacheAdapterEnhancer(adapter, { enabledByDefault: false });
// v4:
cacheAdapterEnhancer(adapter, {
  cacheable: (config) => (config.cache ?? false) && config.method === 'get',
});

// v3: custom cacheFlag
cacheAdapterEnhancer(adapter, { enabledByDefault: false, cacheFlag: 'useCache' });
// v4:
cacheAdapterEnhancer(adapter, {
  cacheable: (config) => config.method === 'get' ? (config.useCache ?? false) : false,
});

πŸ“– See the full Migration Guide (v3 β†’ v4) for all scenarios.

Cache export is now built on tiny-lru instead of lru-cache

If you relied on lru-cache-specific APIs, switch to the cache-like contract: get(key), set(key, value), delete(key).

✨ New Features

πŸ”‘ Custom cache key generation (#116)

Pass a keyGenerator to control how cache keys are built β€” useful for method-aware or body-sensitive caching strategies.

// Cache POST requests with body-aware keys
cacheAdapterEnhancer(adapter, {
  cacheable: (config) => config.method === 'get' || config.method === 'post',
  keyGenerator: (config) => `${config.method}:${config.url}:${JSON.stringify(config.data)}`,
});

🏷️ Cache hit indicator (#119)

Cached responses now carry __fromCache: true, so your app can easily tell whether data came from cache or a fresh request.

const response = await http.get('/users');
if (response.__fromCache) {
  console.log('Served from cache');
}

🎯 Cacheable predicate (#118)

The new cacheable option gives you full control over which requests should be cached β€” replacing the old enabledByDefault + cacheFlag combo.

// Only cache GET requests to specific API paths
cacheAdapterEnhancer(adapter, {
  cacheable: (config) => config.method === 'get' && config.url?.startsWith('/api/'),
});

// Per-request cache instance
import Cache from 'axios-extensions/Cache';
const userCache = new Cache({ ttl: 60000, max: 50 });

cacheAdapterEnhancer(adapter, {
  cacheable: (config) => {
    if (config.url?.startsWith('/api/users')) return userCache;
    return config.method === 'get';
  },
});

⏱️ Per-request throttle threshold override (#120)

throttleAdapterEnhancer now accepts a threshold on individual requests, overriding the global default.

const http = axios.create({
  adapter: throttleAdapterEnhancer(axios.defaults.adapter, { threshold: 1000 }),
});

// This specific request gets a longer throttle window
http.get('/slow-endpoint', { threshold: 5000 });

// This one uses the default 1000ms
http.get('/fast-endpoint');

πŸ› Bug Fixes

  • Fix process undefined crash in non-browser environments (#115)
  • Fix axios 1.x adapter config compatibility (#114)

πŸ”§ Internal

  • Build & test stack migrated to Vite + Vitest (#111, #117)
  • Source files included in build output for proper source map support (#105)
  • Release pipeline migrated to semantic-release (#122)

Full Changelog: v3.1.7...v4.0.0