npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2025 – Pkg Stats / Ryan Hefner

@karmaniverous/cached-axios

v0.2.0

Published

Tag‑aware caching for Axios: stable cache IDs, simple tag invalidation, and a drop‑in Orval mutator on top of axios‑cache‑interceptor.

Readme

Tag‑aware caching for Axios: stable cache IDs, simple tag invalidation, and a drop‑in Orval mutator on top of axios‑cache‑interceptor.

@karmaniverous/cached-axios

npm version Node Current docs changelog license

Tag-aware caching helpers for Axios on top of axios-cache-interceptor.

This library makes it easy to:

  • Assign stable cache ids to GET-like requests.
  • Group ids under tags and invalidate them after write-like requests.
  • Share a cache-aware Axios instance across a project.
  • Generate consistent id/tag keys from a declarative config shape.
  • Plug into code generators such as Orval via a ready-to-use mutator.

Installation

npm i @karmaniverous/cached-axios axios axios-cache-interceptor zod

Requires Node 20+.

Quick start

import {
  cachedAxios,
  withQuery,
  withMutation,
} from '@karmaniverous/cached-axios';

// GET with a stable id; associate id with tags for later invalidation.
await withQuery<User>(
  cachedAxios.request,
  'user:42', // your stable id
  ['user:list'], // tags to register
  { url: '/users/42', method: 'get', baseURL: 'https://api.example.com' },
);

// Write and invalidate any ids under these tags.
await withMutation(
  cachedAxios.request,
  ['user:list'], // tags to invalidate
  {
    url: '/users/42',
    method: 'patch',
    data: { name: 'Alice' },
    baseURL: 'https://api.example.com',
  },
);

The helpers forward any object-valued cache options from your base config and set only what they need (custom id for queries; update map for mutations). Pass cache: false on a call to disable caching for that request.

Building ids and tags with buildConfig

Declaratively define your keyspace, then use strongly-typed builders everywhere.

import { buildConfig } from '@karmaniverous/cached-axios';

const cfg = buildConfig({
  user: {
    byId: undefined,
    list: undefined,
  },
});

// Generate keys
const id = cfg.user.byId.id(42); // "user:byId:42"
const tag = cfg.user.list.tag(); // "user:list"

Segments can be string | number | (string|number)[] | undefined, and are joined with : to form keys.

Pre-bound helpers with makeCacheHelpers

import { makeCacheHelpers } from '@karmaniverous/cached-axios';

const { query, mutation } = makeCacheHelpers(() => ({
  baseURL: 'https://api.example.com',
  headers: { Authorization: 'Bearer <token>' },
}));

// Query
await query<User>(
  cachedAxios.request,
  cfg.user.byId.id(42),
  [cfg.user.list.tag()],
  {
    url: '/users/42',
    method: 'get',
  },
);

// Mutation + invalidation
await mutation(cachedAxios.request, [cfg.user.list.tag()], {
  url: '/users/42',
  method: 'patch',
  data: { name: 'Bob' },
});

Orval integration

Use the provided mutator to keep generated clients cache-aware.

// orval.config.ts (or .js)
import { orvalMutator } from '@karmaniverous/cached-axios/mutators/orval';

export default {
  petstore: {
    input: './openapi.yaml',
    output: {
      target: './src/generated/client.ts',
      client: 'axios',
      mutator: {
        path: '@karmaniverous/cached-axios/mutators/orval',
        name: 'orvalMutator',
      },
    },
  },
};

Recommended path: '@karmaniverous/cached-axios/mutators/orval' for generators. For manual imports, a convenience barrel is available at '@karmaniverous/cached-axios/mutators'. The root export remains available if you prefer: import { orvalMutator } from '@karmaniverous/cached-axios'.

The orvalMutator<T, R>(config, options?) shallow-merges options over config and always resolves to AxiosResponse<T>. It executes via the same shared cache-aware Axios instance exported as cachedAxios.

The shared Axios instance (cachedAxios)

import { cachedAxios } from '@karmaniverous/cached-axios';

Defaults:

  • interpretHeader: true — honor HTTP caching headers.
  • staleIfError: true — serve cached data when revalidation fails.
  • ttl: 5 minutes — fallback TTL if headers don’t specify caching.

No baseURL is set; pass baseURL/headers per request to keep parallel calls safe against multiple backends.

Caching and invalidation model

  • withQuery sets a custom cache id and registers it under provided tags in an in-memory index.
  • withMutation builds an ACI update map ({[id]: 'delete'}) for all ids currently associated with the given tags and clears those tag buckets.
  • The tag index is process-local and not persisted or shared between processes. For distributed invalidation, prefer server-driven cache headers or a shared cache layer (e.g., Redis) integrated with your backend.

API surface

  • cachedAxios: ACI-wrapped Axios instance.
  • withQuery(call, id, tags, base?): GET-like helper with stable id + tag registration.
  • withMutation(call, invalidate, base?): write-like helper with tag-based invalidation.
  • makeCacheHelpers(base?){ query, mutation } bound to a base config.
  • buildConfig(shape) → nested object with id(seg?) and tag(seg?) at every node.
  • orvalMutator<T, R>(config, options?) → AxiosResponse via cachedAxios.
  • Types:
    • Branded Id and Tag,
    • BuiltNode, ConfigInput,
    • Augmented Axios/ACI types re-exported from the package.

Disabling caching per request

await withQuery(cachedAxios.request, 'user:42', ['user:list'], {
  url: '/users/42',
  method: 'get',
  cache: false,
});

Types and augmentations

  • AxiosRequestConfig['cache'] is augmented to accept false | Partial<CacheProperties>.
  • AxiosResponse exposes cached?: boolean and previous?: AxiosResponse.
  • CacheProperties (from ACI) is extended with id?: string, etag?: string, and update?: Record<string, 'delete'>.

Docs and support

  • API docs are generated by TypeDoc (npm run docs).
  • Tests: npm test (Vitest with coverage).
  • Linting/formatting: npm run lint.

Built for you with ❤️ on Bali! Find more great tools & templates on my GitHub Profile.