{"_id":"@async-kit/cachex","name":"@async-kit/cachex","dist-tags":{"latest":"0.2.0"},"versions":{"0.2.0":{"name":"@async-kit/cachex","version":"0.2.0","description":"Smart async cache with request deduplication, TTL, stale-while-revalidate, and pluggable storage for JavaScript/TypeScript","keywords":["async","cache","ttl","memoize","deduplication","stale-while-revalidate","lru"],"license":"MIT","repository":{"type":"git","url":"git+https://github.com/NexaLeaf/async-kit.git","directory":"packages/cachex"},"homepage":"https://github.com/NexaLeaf/async-kit/tree/main/packages/cachex#readme","main":"./dist/index.cjs","module":"./dist/index.js","types":"./dist/index.d.ts","exports":{".":{"import":{"types":"./dist/index.d.ts","default":"./dist/index.js"},"require":{"types":"./dist/index.d.cts","default":"./dist/index.cjs"}}},"publishConfig":{"access":"public"},"sideEffects":false,"scripts":{"build":"tsup","typecheck":"tsc -p tsconfig.lib.json --noEmit"},"devDependencies":{},"gitHead":"f589ca61f0ee8b4e74e94cb2019745f6b63fc39e","_id":"@async-kit/cachex@0.2.0","bugs":{"url":"https://github.com/NexaLeaf/async-kit/issues"},"_nodeVersion":"24.14.0","_npmVersion":"11.9.0","dist":{"integrity":"sha512-Qkbd40KSW3tj50Q5nNI9jegaoUCUH4mxH4tQBoxhW30ru25plV5zxrUPm9pK8/4L21mjDhP10foqxO5xVt2xEw==","shasum":"9ddc920edc0939105826811d0eca95d04a8bbd58","tarball":"https://registry.npmjs.org/@async-kit/cachex/-/cachex-0.2.0.tgz","fileCount":9,"unpackedSize":54653,"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@async-kit%2fcachex@0.2.0","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEQCIHaUCrgvnb9fIIbJiLpNf2sXl3JvbyWH36qulZFek0IuAiBYgNrabEE74HkqeQ1+d7wXiANAtGg325SltE3W5PeI3w=="}]},"_npmUser":{"name":"palanisamym14","email":"palanisamym14@gmail.com"},"directories":{},"maintainers":[{"name":"palanisamym14","email":"palanisamym14@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/cachex_0.2.0_1773298977134_0.395886356676721"},"_hasShrinkwrap":false}},"time":{"created":"2026-03-12T07:02:57.086Z","0.2.0":"2026-03-12T07:02:57.273Z","modified":"2026-03-12T07:02:57.638Z"},"maintainers":[{"name":"palanisamym14","email":"palanisamym14@gmail.com"}],"description":"Smart async cache with request deduplication, TTL, stale-while-revalidate, and pluggable storage for JavaScript/TypeScript","homepage":"https://github.com/NexaLeaf/async-kit/tree/main/packages/cachex#readme","keywords":["async","cache","ttl","memoize","deduplication","stale-while-revalidate","lru"],"repository":{"type":"git","url":"git+https://github.com/NexaLeaf/async-kit.git","directory":"packages/cachex"},"bugs":{"url":"https://github.com/NexaLeaf/async-kit/issues"},"license":"MIT","readme":"# @async-kit/cachex\n\nSmart async function cache with **request deduplication**, **TTL**, **stale-while-revalidate**, and pluggable storage.\n\n## Install\n\n```bash\nnpm install @async-kit/cachex\n```\n\n## Quick start\n\n```ts\nimport { cache } from '@async-kit/cachex';\n\nconst getUser = cache((id: number) => db.users.find(id), { ttl: 60_000 });\n\nawait getUser(1); // → hits DB\nawait getUser(1); // → served from cache (within 60 s)\n```\n\n## Features\n\n| Feature | Description |\n|---|---|\n| **TTL** | Entries expire after `ttl` ms (default: never) |\n| **Request deduplication** | Concurrent calls for the same key share one in-flight Promise |\n| **Stale-while-revalidate** | Returns stale value immediately; refreshes in background |\n| **Tag invalidation** | Group-invalidate entries with `invalidateTag('users')` |\n| **LRU store** | Bounded memory with `LRUStore(maxSize)` |\n| **Pluggable store** | Implement `CacheStore<T>` to back with Redis, localStorage, etc. |\n| **Hooks** | `onSet`, `onHit`, `onMiss`, `onRevalidateError` |\n| **Stats** | `hits`, `misses`, `staleHits`, `stores`, `inflight` snapshot |\n\n## API\n\n### `cache(fn, options?)`\n\nFunctional wrapper — returns a cached function with `.cachex` attached.\n\n```ts\nconst getUser = cache(fetchUser, { ttl: 30_000, staleWhileRevalidate: true });\nawait getUser(42);\ngetUser.cachex.stats(); // { hits, misses, ... }\n```\n\n### `new Cachex(fn, options?)`\n\nClass API — same options, more control.\n\n```ts\nconst cx = new Cachex(fetchUser, { ttl: 60_000 });\nawait cx.call(42);\ncx.invalidate(42);       // remove one key\ncx.invalidateTag('usr'); // remove all tagged entries\ncx.clear();              // flush everything\ncx.stats();              // live counters\n```\n\n### Options\n\n```ts\ninterface CachexOptions<TArgs, TReturn> {\n  ttl?: number;                    // ms, default Infinity\n  staleWhileRevalidate?: boolean;  // default false\n  keyResolver?: (...args) => string;\n  store?: CacheStore<TReturn>;     // default MemoryStore\n  tags?: string[];\n  onSet?: (key, value) => void;\n  onHit?: (key, stale) => void;\n  onMiss?: (key) => void;\n  onRevalidateError?: (key, err) => void;\n}\n```\n\n### Stores\n\n```ts\nimport { MemoryStore, LRUStore } from '@async-kit/cachex';\n\n// Unbounded in-memory (default)\nconst store = new MemoryStore<User>();\n\n// LRU — evicts least-recently-used when full\nconst lru = new LRUStore<User>(500); // max 500 entries\n\n// Custom (Redis, etc.) — implement CacheStore<T>\nclass RedisStore<T> implements CacheStore<T> { ... }\n```\n\n## Examples\n\n### Stale-while-revalidate\n\n```ts\nconst getConfig = cache(fetchConfig, {\n  ttl: 5_000,\n  staleWhileRevalidate: true,\n  onRevalidateError: (key, err) => logger.error({ key, err }),\n});\n```\n\n### Tag-based invalidation\n\n```ts\nconst getUser = cache(fetchUser, { tags: ['users'] });\nawait getUser(1); await getUser(2);\ngetUser.cachex.invalidateTag('users'); // bust both\n```\n\n### Custom key resolver\n\n```ts\nconst search = cache(doSearch, {\n  keyResolver: (query, lang) => `${lang}:${query}`,\n  ttl: 10_000,\n});\n```\n\n## License\n\nMIT\n","readmeFilename":"README.md","_rev":"1-a3a8e13a4f390273ffa082d5ef77b3c1"}