Skip to content

Releases: jaredwray/cacheable

2026-06-27

Choose a tag to compare

@jaredwray jaredwray released this 27 Jun 18:16
268d910

Releasing 6 packages: cacheable@2.5.0 (minor), @cacheable/memory@2.2.0 (minor), @cacheable/net@2.1.0 (minor), @cacheable/utils@2.5.0 (minor), file-entry-cache@11.1.5 (patch), @cacheable/node-cache@3.1.1 (patch).

cacheable@2.5.0 — 2026-06-27

Add tag-based invalidation, per-store TTLs, and a shared static instance accessor.

Features

  • tag-based invalidation via CacheTags (639e42c, #1655)

    const cache = new Cacheable({ tags: true });
    await cache.set('page:/products', html, { tags: ['entity:42'] });
    await cache.tags.invalidateTag('entity:42');
    await cache.get('page:/products'); // undefined — detected stale and removed on read
  • support per-store TTL per operation on set, getOrSet, and wrap (2debaff, #1656)

    // expire faster in the in-memory primary than in the shared secondary
    await cache.set('key', 'value', { ttl: { primary: '10s', secondary: '5m' } });
    await cache.getOrSet('key', async () => 'value', { ttl: { primary: '10s', secondary: '5m' } });
  • support per-store TTL overrides from a BEFORE_SET hook (0be0680, #1657)

    cache.onHook(CacheableHooks.BEFORE_SET, (item) => {
      item.ttl = { primary: '10s', secondary: '1h' }; // different expirations per store
    });
  • add getStaticInstance shared singleton accessor (917bd83, #1665)

    const cache = Cacheable.getStaticInstance({ ttl: '1h' });
    await cache.set('key', 'value');
    // anywhere else, Cacheable.getStaticInstance() returns the same instance

Documentation

  • correct primary/secondary iteration guidance (9178ad2, #1659)

Contributors

Full List of Changes

  • feat(cacheable): tag-based invalidation via CacheTags by @jaredwray in #1655
  • cacheable - feat: support per-store TTL per operation by @jaredwray in #1656
  • docs(cacheable): correct primary/secondary iteration guidance by @jaredwray in #1659
  • feat(cacheable): support per-store TTL overrides via hooks by @jaredwray in #1657
  • feat(cacheable): add getStaticInstance shared singleton accessor by @jaredwray in #1665

Full diff: 2026-05-27...2026-06-27


@cacheable/memory@2.2.0 — 2026-06-27

Add a getOrSet cache-aside helper, opt-in statistics, and strongly-typed hooks.

Features

  • add getOrSet cache-aside helper to CacheableMemory (13da777, #1661)

    const cache = new CacheableMemory();
    const getUser = () => ({ id: 1, name: 'Alice' });
    const a = cache.getOrSet('user:1', getUser, { ttl: '1h' }); // computes + stores
    const b = cache.getOrSet('user:1', getUser, { ttl: '1h' }); // served from cache
  • add opt-in statistics tracking via the shared Stats engine (4c82353, #1662)

    const cache = new CacheableMemory({ stats: true });
    cache.set('a', 1);
    cache.get('a'); cache.get('b');
    cache.stats.hits;    // 1
    cache.stats.misses;  // 1
    cache.stats.hitRate; // 0.5
  • add a strongly-typed onHook overload and exported hook payload types (92d2784, #1663)

    cache.onHook(CacheableMemoryHooks.BEFORE_SET, (item) => {
      // item typed as CacheableMemoryHookItem — value/ttl inferred
      item.value = transform(item.value);
    });

Contributors

Full List of Changes

  • feat(memory): add getOrSet cache-aside helper to CacheableMemory by @jaredwray in #1661
  • feat(memory): add statistics tracking via @cacheable/utils Stats by @jaredwray in #1662
  • feat(memory): strongly-typed onHook and hooks documentation by @jaredwray in #1663

Full diff: 2026-05-27...2026-06-27


@cacheable/net@2.1.0 — 2026-06-27

Add cached WHOIS and RDAP lookups; align fetch with native semantics.

Features

  • add WHOIS (TCP 43) and RDAP (HTTPS/JSON) lookups for domains, IPs, and ASNs (f61070e, #1658)

    import { whois, rdap } from '@cacheable/net';
    const result = await whois('example.com');
    result.fields;  // parsed WHOIS, e.g. { "Domain Name": "EXAMPLE.COM", ... }
    result.server;  // authoritative server that produced the data
    const rdapResult = await rdap('1.1.1.1'); // domains, IPs, and ASNs
    rdapResult.data; // parsed RDAP object

Bug Fixes

Documentation

  • expand README with full API, Features, and Table of Contents (268d910, #1666)

Contributors

Full List of Changes

  • fix(net): make fetch behave like native fetch by @jaredwray in #1652
  • feat(net): add WHOIS and RDAP lookups to @cacheable/net by @jaredwray in #1658
  • docs(net): expand @cacheable/net README with full API, Features, and Table of Contents by @jaredwray in #1666

Full diff: 2026-05-27...2026-06-27


@cacheable/utils@2.5.0 — 2026-06-27

Add a CacheTags service, event-driven Stats, and per-store TTL / sync getOrSet helpers.

Features

  • add CacheTags (CacheTagService) for tag-based invalidation on any Keyv store (7df1236, #1646; 639e42c, #1655)

    import { CacheTags } from '@cacheable/utils';
    const tags = new CacheTags({ store: keyv, enabled: true });
    await tags.setKeyTags('user:1', ['team:42']);
    await tags.invalidateTag('team:42'); // constant-time: bumps a per-tag version counter
    await tags.isKeyFresh('user:1');     // false
  • make Stats event-driven and fully featured — hit/miss rates, per-key tracking, events (0fca255, #1653)

    import { Stats } from '@cacheable/utils';
    const stats = new Stats({ enabled: true });
    stats.trackKeys = true;
    stats.on('hits', (s) => console.log(s.hits));
    stats.incrementHits();
    stats.hitRate; // 1
  • expose Stats per-key data as a public read-only trackedKeys map (51f6cea, #1660)

    for (const [key, counters] of stats.trackedKeys) {
      console.log(key, counters.hits, counters.misses);
    }
  • add a synchronous getOrSetSync cache-aside helper (mirrors async getOrSet; powers CacheableMemory.getOrSet) (13da777, #1661)

  • add a PerStoreTtl type and resolvePerStoreTtl helper for per-store TTLs (2debaff, #1656)

Contributors

Full List of Changes

  • feat: Add CacheTagService to @cacheable/utils by @cupofjoakim in #1646 (first-time contributor)
  • feat(utils): make Stats event-driven and fully featured by @jaredwray in #1653
  • feat(cacheable): tag-based invalidation via CacheTags by @jaredwray in #1655
  • cacheable - feat: support per-store TTL per operation by @jaredwray in #1656
  • refactor(utils): expose Stats per-key data as public trackedKeys map by @jaredwray in #1660
  • feat(memory): add getOrSet cache-aside helper to CacheableMemory by @jaredwray in #1661
  • feat(memory): add statistics tracking via @cacheable/utils Stats by @jaredwray in #1662

Full diff: 2026-05-27...2026-06-27


file-entry-cache@11.1.5 — 2026-06-27

Restore v8 reconcile and change-detection semantics.

Bug Fixes

  • restore v8 reconcile and change-detection semantics — reconcile() no longer revalidates untouched entries, repeated getFileDescriptor() keeps reporting changed: true until reconcile, and corrupt cache files no longer throw (7d58420, #1649)

Contributors

Full List of Changes

  • fix(file-entry-cache): restore v8 reconcile and change-detection semantics by @jaredwray in #1649

Full diff: 2026-05-27...2026-06-27


@cacheable/node-cache@3.1.1 — 2026-06-27

Fix metrics-accounting issues that caused inaccurate ksize/vsize reporting.

Bug Fixes

  • fix ksize/vsize inflation on overwrite, take() of falsy values, and value-size accounting for undefined on delete/expiry (ee73e5a, #1650)

Contributors

Full List of Changes

  • fix(node-cache): Fixing issues with metrics reporting by @jmjones88 in #1650 (first-time contributor)

Full diff: 2026-05-27...2026-06-27

2026-05-27

Choose a tag to compare

@jaredwray jaredwray released this 27 May 15:39
069f734

Releasing 8 packages: @cacheable/memory@2.1.0 (minor), @cacheable/node-cache@3.1.0 (minor), cacheable@2.4.0 (minor), cache-manager@7.2.9 (patch), file-entry-cache@11.1.4 (patch), flat-cache@6.1.23 (patch), @cacheable/net@2.0.9 (patch), @cacheable/utils@2.4.2 (patch).

@cacheable/memory@2.1.0 — 2026-05-27

Add lifecycle hooks and maxTtl cap to CacheableMemory.

Features

  • add hooks for all cache operations via CacheableMemoryHooks enum (1ff149d, #1644)

    import { CacheableMemory, CacheableMemoryHooks } from '@cacheable/memory';
    const cache = new CacheableMemory();
    cache.onHookSync(CacheableMemoryHooks.BEFORE_SET, (data) => {
      data.value = transform(data.value); // mutate before write
    });
    cache.set('key', 'value');
  • add maxTtl option to cap maximum time-to-live (948234a, #1645)

    const cache = new CacheableMemory({ ttl: '10m', maxTtl: '1h' });
    cache.set('key', 'value', '2h'); // capped to 1h
    cache.set('key2', 'value2');     // no TTL → capped to 1h

Internal

  • migrate build from tsup to tsdown, pnpm 11 (1508695, #1642)

Contributors

Full List of Changes

  • feat(cacheable, memory): add maxTtl option to cap maximum time-to-live by @jaredwray in #1645
  • feat(@cacheable/memory): add hooks like cacheable by @jaredwray in #1644
  • feat: Migrate to pnpm 11 with corepack and tsdown from tsup by @jaredwray in #1642

Full diff: 9346f94...release/2026-05-27-8-packages


@cacheable/node-cache@3.1.0 — 2026-05-27

Add keys/has/getTtl/flushAll, events, useClones, checkperiod, and fix multiple stat-tracking bugs.

Features

  • add keys() and has() methods for cache inspection (bf3ea48, #1643)

    const store = new NodeCacheStore();
    await store.set('a', 1);
    await store.keys();    // ['a']
    await store.has('a');  // true
  • add getTtl() to inspect key expiration timestamps (bf3ea48, #1643)

    await store.set('key', 'val', 5000);
    const ttl = await store.getTtl('key'); // ms timestamp when key expires
  • add flushAll() to clear data and reset all stats (bf3ea48, #1643)

    await store.flushAll(); // clears data + resets stats, emits "flush"
  • add event emitters for set, del, expired, and flush operations (bf3ea48, #1643)

    store.on('set', (key, value, ttl) => { /* ... */ });
    store.on('del', (key, value) => { /* ... */ });
    store.on('expired', (key, value) => { /* ... */ });
    store.on('flush', () => { /* ... */ });
  • add useClones option for deep-cloning via structuredClone (bf3ea48, #1643)

    const store = new NodeCacheStore({ useClones: true });
  • add checkperiod option for interval-based expired item detection (bf3ea48, #1643)

    const store = new NodeCacheStore({ checkperiod: 60 }); // check every 60s
    store.close(); // stop interval
  • add deleteOnExpire option and close()/getIntervalId() lifecycle methods (bf3ea48, #1643)

Bug Fixes

  • fix setTtl() treating falsy cached values (0, "", false, null) as non-existent (bf3ea48, #1643)
  • fix mdel() firing stats and events for non-existent keys (bf3ea48, #1643)
  • fix startInterval() leaking old timer when called twice (bf3ea48, #1643)
  • fix set() double-counting stats on key overwrites (bf3ea48, #1643)
  • fix checkData() swallowing unhandled promise rejections (bf3ea48, #1643)
  • fix handleExpired() stats underflow when Keyv auto-expires items (bf3ea48, #1643)
  • fix checkData() mutating Map during iteration (bf3ea48, #1643)

Internal

Contributors

Full List of Changes

  • feat(@cacheable/node-cache): enhance NodeCacheStore with missing features by @jaredwray in #1643
  • feat: Migrate to pnpm 11 with corepack and tsdown from tsup by @jaredwray in #1642
  • @cacheable/node-cache: move store tests to use @faker-js/faker by @jaredwray in #1641

Full diff: 9346f94...release/2026-05-27-8-packages


cacheable@2.4.0 — 2026-05-27

Add maxTtl option to enforce an upper bound on cache entry lifetimes.

Features

  • add maxTtl option to cap maximum time-to-live on set() and setMany() (948234a, #1645)

    import { Cacheable } from 'cacheable';
    const cache = new Cacheable({ ttl: '10m', maxTtl: '1h' });
    await cache.set('key', 'value', '2h'); // capped to 1h
    await cache.set('key2', 'value2');     // no TTL → capped to 1h

Internal

  • migrate build from tsup to tsdown, pnpm 11 (1508695, #1642)

Contributors

Full List of Changes

  • feat(cacheable, memory): add maxTtl option to cap maximum time-to-live by @jaredwray in #1645
  • feat: Migrate to pnpm 11 with corepack and tsdown from tsup by @jaredwray in #1642

Full diff: 9346f94...release/2026-05-27-8-packages


cache-manager@7.2.9 — 2026-05-27

Build tooling migration to tsdown and pnpm 11.

Internal

  • migrate build from tsup to tsdown, pnpm 11 (1508695, #1642)

Contributors

Full List of Changes

  • feat: Migrate to pnpm 11 with corepack and tsdown from tsup by @jaredwray in #1642

Full diff: 9346f94...release/2026-05-27-8-packages


file-entry-cache@11.1.4 — 2026-05-27

Build tooling migration to tsdown and pnpm 11.

Internal

  • migrate build from tsup to tsdown, pnpm 11 (1508695, #1642)

Contributors

Full List of Changes

  • feat: Migrate to pnpm 11 with corepack and tsdown from tsup by @jaredwray in #1642

Full diff: 9346f94...release/2026-05-27-8-packages


flat-cache@6.1.23 — 2026-05-27

Build tooling migration to tsdown and pnpm 11.

Internal

  • migrate build from tsup to tsdown, pnpm 11 (1508695, #1642)

Contributors

Full List of Changes

  • feat: Migrate to pnpm 11 with corepack and tsdown from tsup by @jaredwray in #1642

Full diff: 9346f94...release/2026-05-27-8-packages


@cacheable/net@2.0.9 — 2026-05-27

Build tooling migration to tsdown and pnpm 11.

Internal

  • migrate build from tsup to tsdown, pnpm 11 (1508695, #1642)

Contributors

Full List of Changes

  • feat: Migrate to pnpm 11 with corepack and tsdown from tsup by @jaredwray in #1642

Full diff: 9346f94...release/2026-05-27-8-packages


@cacheable/utils@2.4.2 — 2026-05-27

Build tooling migration to tsdown and pnpm 11.

Internal

  • migrate build from tsup to tsdown, pnpm 11 (1508695, #1642)

Contributors

Full List of Changes

  • feat: Migrate to pnpm 11 with corepack and tsdown from tsup by @jaredwray in #1642

Full diff: 9346f94...release/2026-05-27-8-packages

2026-05-16

Choose a tag to compare

@jaredwray jaredwray released this 16 May 23:04
9346f94

@cacheable/net@2.0.8

Fix FormData/Blob/URLSearchParams bodies by routing through the runtime's own fetch so the body classes share a realm with the fetch implementation.

Bug Fixes

  • send FormData/Blob correctly using the runtime's own fetch (7cbe243, #1636)

Contributors

@cacheable/memory@2.0.9

Clarify in the README that lruSize=0 disables LRU.

Documentation

  • clarify that lruSize=0 disables LRU (2abfb68, #1638)

Contributors

Full diff: 2026-05-07...2026-05-16

2026-05-07

Choose a tag to compare

@jaredwray jaredwray released this 07 May 19:44

What's Changed

Full Changelog: 2026-03-26...2026-05-07

2026-03-26

Choose a tag to compare

@jaredwray jaredwray released this 27 Mar 02:26
6292b97

What's Changed

Full Changelog: 2026-03-17...2026-03-26

2026-03-17

Choose a tag to compare

@jaredwray jaredwray released this 17 Mar 23:43
7f9d958

What's Changed

New Contributors

Full Changelog: 2026-02-27...2026-03-17

2026-02-27

Choose a tag to compare

@jaredwray jaredwray released this 27 Feb 16:33
b1a1f4e

What's Changed

Full Changelog: 2026-02-06...2026-02-27

2026-02-06

Choose a tag to compare

@jaredwray jaredwray released this 06 Feb 22:50
af10eb6

What's Changed

New Contributors

Full Changelog: 2025-01-17...2026-02-06

2025-01-17

Choose a tag to compare

@jaredwray jaredwray released this 17 Jan 17:24
8e8ee2b

What's Changed

Full Changelog: 2026-01-09...2025-01-17

2026-01-09

Choose a tag to compare

@jaredwray jaredwray released this 09 Jan 21:01
8087e05

What's Changed

Full Changelog: 2025-12-26...2026-01-09