{"_id":"ocache","_rev":"9-bc5ebdecddcd69f311a217d85b28b768","name":"ocache","dist-tags":{"latest":"0.3.0"},"versions":{"0.0.0":{"name":"ocache","version":"0.0.0","license":"MIT","_id":"ocache@0.0.0","maintainers":[{"name":"pi0","email":"pyapar@gmail.com"}],"dist":{"shasum":"72e82e0f8de57237f7f41d325a7fd35e4be3777a","tarball":"https://registry.npmjs.org/ocache/-/ocache-0.0.0.tgz","fileCount":1,"integrity":"sha512-V8IYmp3+t/lCudzPvl9Kg+dMgQeBOo2m4V1dxU5x5bbXg/rBitwIrX8Z+coHJ2pBd6qlH4bc6X6tFihhWI3zNQ==","signatures":[{"sig":"MEUCIQCQ2qzewBIOxuVPwE+HlfJLuWc02HY+x1nwaoqwafFL+AIgEm1PDbChIxDLduJ4pMvqwRj9EwikY0Xya9YJgy+5YBA=","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":61,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJiMo2QACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2VmqmxQ/+KrkIdmAjmn6fRhjnzsbarr+zGku3em7+q3r59V07BF7C+D3J\r\ngcXr1j6x+yRrIvNc4yCx6KhicOwcFyY9J5qfGTbqio1+6GROEVfwPXepHHTw\r\n4h0OgtmsIS9syI0pdgBsgwHfXjcSSP5+gzq3ukbxJEs1NtBqXtOTqSm2ET9O\r\nf5qNy1gCLHfBEoZ4+tXG/gldbINFQnT0o3qN4Q93x7NQpLsUmlqoe6qbBGeA\r\nLLjmTD3T0bh1PcEqABLnCMUyIL4Y6Ia/wHGZG/s6HuxHMF7IyBK24Y4u7nK3\r\nRbjs1KLqrPmxjm6FBRecVlbRx0W+NFwgMZquf9YZODGT3hl16q6VvmVqeQuC\r\ngMmrukv7EOQgACWFiu9QOjDfy3ZPEzMTs7z807do1uA4lv7eKitflO64GsaB\r\nY09/6iwaryy+9af375yTdh1CA326PW8+iAZXsb06fG4nU1/Kyx/gKCMr6QDT\r\nXlw1Oz27YSrqtf1plusByz9fIkFtQXI9//6nI/q3i97SNm0XoTci9O+AszRs\r\n5R4ZE+7W3Es2IwFM4GNnko/S4PCVXs6tTzjhrEIKFK5udgbZR0ttfTHQMj1S\r\ndZBTvc7ES6BAeznJMRwTITMjEsnJVrJsyAhELKKxcXLFQ/s+8X7g1+SuJax8\r\n3QAPqlZLtThXi7Q88iKvywMd46tskP56EWU=\r\n=TyBY\r\n-----END PGP SIGNATURE-----\r\n"},"_npmUser":{"name":"pi0","email":"pyapar@gmail.com"},"_npmVersion":"8.3.1","directories":{},"_nodeVersion":"16.14.0","_hasShrinkwrap":false,"_npmOperationalInternal":{"tmp":"tmp/ocache_0.0.0_1647480208243_0.35687666960137876","host":"s3://npm-registry-packages"}},"0.1.1":{"name":"ocache","version":"0.1.1","license":"MIT","_id":"ocache@0.1.1","maintainers":[{"name":"pi0","email":"pyapar@gmail.com"}],"homepage":"https://github.com/unjs/ocache#readme","bugs":{"url":"https://github.com/unjs/ocache/issues"},"dist":{"shasum":"d50d30fa4ba3332edf8cbae07d44d16cc5ae9e3c","tarball":"https://registry.npmjs.org/ocache/-/ocache-0.1.1.tgz","fileCount":5,"integrity":"sha512-sZ8GJeuIWqwE1EW8iuwWDjHA0T5S/hgR69kSVqJkNDHi8rniDW3ITw5xTh1TMYY+Bdc7L+X2HwsVbAkpSBkz0Q==","signatures":[{"sig":"MEUCIGrghwdPwQiLgDfPT7HKMVxeyOi66JH1Bo9GwZQ1X5RrAiEAmNlfk185l6wzgXnItDKux14pqfP+scOB5MJfGjm8TMY=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":23981},"type":"module","types":"./dist/index.d.mts","exports":{".":"./dist/index.mjs"},"gitHead":"182fad269779df8e8232680c107e0d1b307d0f5c","scripts":{"dev":"vitest dev","fmt":"automd && oxlint . --fix && oxfmt .","lint":"oxlint . && oxfmt --check .","test":"pnpm lint && pnpm typecheck && vitest run --coverage","build":"obuild","prepack":"pnpm build","release":"pnpm test && pnpm build && changelogen --release && npm publish && git push --follow-tags","typecheck":"tsgo --noEmit --skipLibCheck"},"_npmUser":{"name":"pi0","email":"pyapar@gmail.com"},"repository":{"url":"git+https://github.com/unjs/ocache.git","type":"git"},"_npmVersion":"11.6.2","description":"Standalone caching utilities with TTL, SWR, and HTTP response caching","directories":{},"sideEffects":false,"_nodeVersion":"24.13.0","dependencies":{"ohash":"^2.0.11"},"_hasShrinkwrap":false,"packageManager":"pnpm@10.29.3","devDependencies":{"oxfmt":"latest","automd":"latest","obuild":"latest","oxlint":"latest","vitest":"latest","docs4ts":"^0.0.3","typescript":"latest","@types/node":"latest","changelogen":"latest","@vitest/coverage-v8":"latest","@typescript/native-preview":"latest"},"_npmOperationalInternal":{"tmp":"tmp/ocache_0.1.1_1773097549821_0.5253789683352974","host":"s3://npm-registry-packages-npm-production"}},"0.1.2":{"name":"ocache","version":"0.1.2","license":"MIT","_id":"ocache@0.1.2","maintainers":[{"name":"pi0","email":"pyapar@gmail.com"}],"homepage":"https://github.com/unjs/ocache#readme","bugs":{"url":"https://github.com/unjs/ocache/issues"},"dist":{"shasum":"4b69ac1450206543a8abb8f0055b5e628a1d3c87","tarball":"https://registry.npmjs.org/ocache/-/ocache-0.1.2.tgz","fileCount":5,"integrity":"sha512-lI34wjM7cahEdrq2I5obbF7MEdE97vULf6vNj6ZCzwEadzyXO1w7QOl2qzzG4IL8cyO7wDtXPj9CqW/aG3mn7g==","signatures":[{"sig":"MEUCICTMZVbgd1UR8FGqT3gYx464kUp1rbGIIGM0Xl5DDCCmAiEAnxsq1vORWHbDSn5/u2o6gpxuN8eW6y49IG7zvbdUa58=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":25493},"type":"module","types":"./dist/index.d.mts","exports":{".":"./dist/index.mjs"},"gitHead":"0b12afc1be414ccc8836adb247ade62441826916","scripts":{"dev":"vitest dev","fmt":"automd && oxlint . --fix && oxfmt .","lint":"oxlint . && oxfmt --check .","test":"pnpm lint && pnpm typecheck && vitest run --coverage","build":"obuild","prepack":"pnpm build","release":"pnpm test && pnpm build && changelogen --release && npm publish && git push --follow-tags","typecheck":"tsgo --noEmit --skipLibCheck"},"_npmUser":{"name":"pi0","email":"pyapar@gmail.com"},"repository":{"url":"git+https://github.com/unjs/ocache.git","type":"git"},"_npmVersion":"11.6.2","description":"Standalone caching utilities with TTL, SWR, and HTTP response caching","directories":{},"sideEffects":false,"_nodeVersion":"24.13.0","dependencies":{"ohash":"^2.0.11"},"_hasShrinkwrap":false,"packageManager":"pnpm@10.29.3","devDependencies":{"oxfmt":"latest","automd":"latest","obuild":"latest","oxlint":"latest","vitest":"latest","docs4ts":"^0.0.3","typescript":"latest","@types/node":"latest","changelogen":"latest","@vitest/coverage-v8":"latest","@typescript/native-preview":"latest"},"_npmOperationalInternal":{"tmp":"tmp/ocache_0.1.2_1773099063282_0.7372930800173729","host":"s3://npm-registry-packages-npm-production"}},"0.1.3":{"name":"ocache","version":"0.1.3","license":"MIT","_id":"ocache@0.1.3","maintainers":[{"name":"pi0","email":"pyapar@gmail.com"}],"homepage":"https://github.com/unjs/ocache#readme","bugs":{"url":"https://github.com/unjs/ocache/issues"},"dist":{"shasum":"ceb4bd3d6a0c54792ebb99d0897ac4069e15ff6d","tarball":"https://registry.npmjs.org/ocache/-/ocache-0.1.3.tgz","fileCount":5,"integrity":"sha512-1YlRgsdPL+yTC/i0ztczEJXjJNvp0p8AuJN7/m02eX/zXVDICHPfI+5J4mfLN3d9hYnA1wWgOP5SFhnz+I+8rg==","signatures":[{"sig":"MEUCIDqTiIuoPmRNOW5trVnJizVtn5a5LyTHiWeoKxd/V7RiAiEA5TIQpoeanPrg1M/ZUBrc/aR4t1o3Obxgyx10eYvdxwA=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":34351},"type":"module","types":"./dist/index.d.mts","exports":{".":"./dist/index.mjs"},"gitHead":"d555f10b7e70d7fa59c14dbb8b1a5471a3544a98","scripts":{"dev":"vitest dev","fmt":"automd && oxlint . --fix && oxfmt .","lint":"oxlint . && oxfmt --check .","test":"pnpm lint && pnpm typecheck && vitest run --coverage","build":"obuild","prepack":"pnpm build","release":"pnpm test && pnpm build && changelogen --release && npm publish && git push --follow-tags","typecheck":"tsgo --noEmit --skipLibCheck"},"_npmUser":{"name":"pi0","email":"pyapar@gmail.com"},"repository":{"url":"git+https://github.com/unjs/ocache.git","type":"git"},"_npmVersion":"11.6.2","description":"Standalone caching utilities with TTL, SWR, and HTTP response caching","directories":{},"sideEffects":false,"_nodeVersion":"24.13.0","dependencies":{"ohash":"^2.0.11"},"_hasShrinkwrap":false,"packageManager":"pnpm@10.32.1","devDependencies":{"oxfmt":"^0.41.0","automd":"^0.4.3","mitata":"^1.0.34","obuild":"^0.4.32","oxlint":"^1.56.0","vitest":"^4.1.0","docs4ts":"^0.0.4","typescript":"^5.9.3","@types/node":"^25.5.0","changelogen":"^0.6.2","@vitest/coverage-v8":"^4.1.0","@typescript/native-preview":"^7.0.0-dev.20260319.1"},"_npmOperationalInternal":{"tmp":"tmp/ocache_0.1.3_1773928633744_0.16406968496619045","host":"s3://npm-registry-packages-npm-production"}},"0.1.4":{"name":"ocache","version":"0.1.4","license":"MIT","_id":"ocache@0.1.4","maintainers":[{"name":"pi0","email":"pyapar@gmail.com"}],"homepage":"https://github.com/unjs/ocache#readme","bugs":{"url":"https://github.com/unjs/ocache/issues"},"dist":{"shasum":"d4a71be84ceaeb5685cc0128c197d44713dda9a7","tarball":"https://registry.npmjs.org/ocache/-/ocache-0.1.4.tgz","fileCount":5,"integrity":"sha512-e7geNdWjxSnvsSgvLuPvgKgu7ubM10ZmTPOgpr7mz2BXYtvjMKTiLhjFi/gWU8chkuP6hNkZBsa9LzOusyaqkQ==","signatures":[{"sig":"MEQCIFW8MF4T29XU4Fod9cSSjtgNK8A8IhOqKV7rE9kpW4AwAiBev9TETTnvOuSIfDjrzmx23hLcjjndnKIwlx/qYzOqqQ==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":34490},"type":"module","types":"./dist/index.d.mts","exports":{".":"./dist/index.mjs"},"gitHead":"a2a761d26121e0ca491e21760a60fd821bce1e48","scripts":{"dev":"vitest dev","fmt":"automd && oxlint . --fix && oxfmt .","lint":"oxlint . && oxfmt --check .","test":"pnpm lint && pnpm typecheck && vitest run --coverage","build":"obuild","prepack":"pnpm build","release":"pnpm test && pnpm build && changelogen --release && npm publish && git push --follow-tags","typecheck":"tsgo --noEmit --skipLibCheck"},"_npmUser":{"name":"pi0","email":"pyapar@gmail.com"},"repository":{"url":"git+https://github.com/unjs/ocache.git","type":"git"},"_npmVersion":"11.6.2","description":"Standalone caching utilities with TTL, SWR, and HTTP response caching","directories":{},"sideEffects":false,"_nodeVersion":"24.13.0","dependencies":{"ohash":"^2.0.11"},"_hasShrinkwrap":false,"packageManager":"pnpm@10.32.1","devDependencies":{"oxfmt":"^0.41.0","automd":"^0.4.3","mitata":"^1.0.34","obuild":"^0.4.32","oxlint":"^1.56.0","vitest":"^4.1.0","docs4ts":"^0.0.4","typescript":"^5.9.3","@types/node":"^25.5.0","changelogen":"^0.6.2","@vitest/coverage-v8":"^4.1.0","@typescript/native-preview":"^7.0.0-dev.20260319.1"},"_npmOperationalInternal":{"tmp":"tmp/ocache_0.1.4_1773930204477_0.8281541275807214","host":"s3://npm-registry-packages-npm-production"}},"0.1.5":{"name":"ocache","version":"0.1.5","license":"MIT","_id":"ocache@0.1.5","maintainers":[{"name":"pi0","email":"pyapar@gmail.com"}],"homepage":"https://github.com/unjs/ocache#readme","bugs":{"url":"https://github.com/unjs/ocache/issues"},"dist":{"shasum":"333f374b654fd8aadf79df760f57e7de11e8cea3","tarball":"https://registry.npmjs.org/ocache/-/ocache-0.1.5.tgz","fileCount":5,"integrity":"sha512-kNNnkkVQup/QDvmTz8Q84wc2ntiyoVHDxa6eHWKt5qdGAmFRBIxy83rxgCYEjW0x06UJ9E3P6VgM2yY4rOBH4w==","signatures":[{"sig":"MEUCIQD5smOFn8+glu0Bn6kubHcUm+kswVpkLeOmf7FqewnIaQIgQonX+/iU6GK0suOLhca2q+kimvbU55ru3VfT1GkzeRA=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":36242},"type":"module","types":"./dist/index.d.mts","exports":{".":"./dist/index.mjs"},"scripts":{"dev":"vitest dev","fmt":"automd && oxlint . --fix && oxfmt .","lint":"oxlint . && oxfmt --check .","test":"pnpm lint && pnpm typecheck && vitest run --coverage","build":"obuild","prepack":"pnpm build","release":"pnpm test && pnpm build && changelogen --release && npm publish && git push --follow-tags","typecheck":"tsgo --noEmit --skipLibCheck"},"_npmUser":{"name":"pi0","email":"pyapar@gmail.com"},"repository":{"url":"git+https://github.com/unjs/ocache.git","type":"git"},"_npmVersion":"11.13.0","description":"Standalone caching utilities with TTL, SWR, and HTTP response caching","directories":{},"sideEffects":false,"_nodeVersion":"24.16.0","dependencies":{"ohash":"^2.0.11"},"_hasShrinkwrap":false,"packageManager":"pnpm@11.5.2","devDependencies":{"oxfmt":"^0.54.0","automd":"^0.4.3","mitata":"^1.0.34","obuild":"^0.4.36","oxlint":"^1.69.0","vitest":"^4.1.8","docs4ts":"^0.0.4","typescript":"^6.0.3","@types/node":"^25.9.2","changelogen":"^0.6.2","@vitest/coverage-v8":"^4.1.8","@typescript/native-preview":"7.0.0-dev.20260609.1"},"_npmOperationalInternal":{"tmp":"tmp/ocache_0.1.5_1781112911779_0.09099399114579776","host":"s3://npm-registry-packages-npm-production"}},"0.2.0":{"name":"ocache","version":"0.2.0","license":"MIT","_id":"ocache@0.2.0","maintainers":[{"name":"pi0","email":"pyapar@gmail.com"}],"homepage":"https://github.com/unjs/ocache#readme","bugs":{"url":"https://github.com/unjs/ocache/issues"},"dist":{"shasum":"804d414d9292434b7dc49d4d412e7915623fa828","tarball":"https://registry.npmjs.org/ocache/-/ocache-0.2.0.tgz","fileCount":5,"integrity":"sha512-QE+SxXf/A8yR01rEOg2X5KwUe+mARHo1xQXl+iwLMzLIH06S5lBOZhhHQWp7T5etfFa8nOnRhvjGuo9YBCWwig==","signatures":[{"sig":"MEYCIQD+ATcMQx1fmD2u/83cHHtjDtdr3ZbMdSv401kkzMes9wIhAO/bMYiGXDXhRwapEid/GYbqoLVSjvbv9eqr7rRUJ25M","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":56772},"type":"module","types":"./dist/index.d.mts","exports":{".":"./dist/index.mjs"},"scripts":{"dev":"vitest dev","fmt":"automd && oxlint . --fix && oxfmt .","lint":"oxlint . && oxfmt --check .","test":"pnpm lint && pnpm typecheck && vitest run --coverage","build":"obuild","prepack":"pnpm build","release":"pnpm test && pnpm build && changelogen --release && npm publish && git push --follow-tags","typecheck":"tsgo --noEmit --skipLibCheck"},"_npmUser":{"name":"pi0","email":"pyapar@gmail.com"},"repository":{"url":"git+https://github.com/unjs/ocache.git","type":"git"},"_npmVersion":"11.16.0","description":"Composable caching primitives with TTL, SWR, and HTTP response caching","directories":{},"sideEffects":false,"_nodeVersion":"24.18.0","dependencies":{"ohash":"^2.0.11"},"_hasShrinkwrap":false,"packageManager":"pnpm@11.10.0","devDependencies":{"oxfmt":"^0.58.0","automd":"^0.4.3","mitata":"^1.0.34","obuild":"^0.4.37","oxlint":"^1.73.0","vitest":"^4.1.10","docs4ts":"^0.0.4","typescript":"^6.0.3","@types/node":"^26.0.1","changelogen":"^0.6.2","@vitest/coverage-v8":"^4.1.10","@typescript/native-preview":"latest"},"_npmOperationalInternal":{"tmp":"tmp/ocache_0.2.0_1783600365715_0.03194969028747208","host":"s3://npm-registry-packages-npm-production"}},"0.3.0":{"_id":"ocache@0.3.0","bugs":{"url":"https://github.com/unjs/ocache/issues"},"dist":{"shasum":"325985cbf510e3a073a7e5c16b0d68d6755ce21e","tarball":"https://registry.npmjs.org/ocache/-/ocache-0.3.0.tgz","fileCount":7,"integrity":"sha512-RS/9P0zeBb0gDJmadGERLH8lZNXK7xbufTDhclkXGvFGTsj0G4M5/cLk+mizcERH29mLXNnocfB5wjcK70wGJg==","signatures":[{"sig":"MEYCIQDk8ZnvmSMZ7O3lxop50YesRwkbh8EddJkQtMDBFaedhAIhANnRGXKBL+2MPVT5luCrln1trGkRHXGDlnPgzEaB56f0","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"},{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEUCIDymLBSvLXLSyfK+CHAY8gxbkKIIOeGvLdq8+Wcwz/GxAiEA9ALX7FC5j9UoeonnwFKanDnp0zzEfvqE9zFMF9vu2TM="}],"unpackedSize":101395},"name":"ocache","type":"module","types":"./dist/index.d.mts","exports":{".":"./dist/index.mjs"},"imports":{"#crypto":{"node":"./lib/digest.node.mjs","default":"./lib/digest.mjs"}},"license":"MIT","scripts":{"dev":"vitest dev","fmt":"automd && oxlint . --fix && oxfmt .","lint":"oxlint . && oxfmt --check .","test":"pnpm lint && pnpm typecheck && vitest run --coverage","bench":"node --expose-gc bench/index.ts","build":"obuild","bundle":"node test/bundle.ts","prepack":"pnpm build","release":"pnpm test && pnpm build && changelogen --release && npm publish && git push --follow-tags","typecheck":"tsc --noEmit --skipLibCheck","bench:docs":"node bench/docs.ts","bench:chart":"node bench/chart.ts","bench:micro":"node --expose-gc bench/micro.ts"},"version":"0.3.0","_npmUser":{"name":"pi0","email":"pyapar@gmail.com"},"homepage":"https://github.com/unjs/ocache#readme","repository":{"url":"git+https://github.com/unjs/ocache.git","type":"git"},"_npmVersion":"11.17.0","description":"Composable caching primitives with TTL, SWR, and HTTP response caching","directories":{},"maintainers":[{"name":"pi0","email":"pyapar@gmail.com"}],"sideEffects":false,"_nodeVersion":"24.19.0","_hasShrinkwrap":false,"packageManager":"pnpm@11.21.0","devDependencies":{"oxfmt":"^0.63.0","automd":"^0.4.3","mitata":"^1.0.34","obuild":"^0.4.38","oxlint":"^1.78.0","vitest":"^4.1.10","docs4ts":"^0.0.4","rolldown":"^1.2.4","typescript":"^7.0.2","@types/node":"^26.2.0","changelogen":"^0.6.2","@vitest/coverage-v8":"^4.1.10"},"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/ocache_0.3.0_1787065380447_0.9721730401902846"}}},"time":{"created":"2022-03-17T01:23:28.243Z","modified":"2026-08-18T15:03:00.810Z","0.0.0":"2022-03-17T01:23:28.422Z","0.1.1":"2026-03-09T23:05:49.969Z","0.1.2":"2026-03-09T23:31:03.428Z","0.1.3":"2026-03-19T13:57:13.879Z","0.1.4":"2026-03-19T14:23:24.620Z","0.1.5":"2026-06-10T17:35:11.913Z","0.2.0":"2026-07-09T12:32:45.844Z","0.3.0":"2026-08-18T15:03:00.536Z"},"bugs":{"url":"https://github.com/unjs/ocache/issues"},"license":"MIT","homepage":"https://github.com/unjs/ocache#readme","repository":{"url":"git+https://github.com/unjs/ocache.git","type":"git"},"description":"Composable caching primitives with TTL, SWR, and HTTP response caching","maintainers":[{"name":"pi0","email":"pyapar@gmail.com"}],"readme":"# ocache\n\n<!-- automd:badges color=yellow -->\n\n[![npm version](https://img.shields.io/npm/v/ocache?color=yellow)](https://npmjs.com/package/ocache)\n[![npm downloads](https://img.shields.io/npm/dm/ocache?color=yellow)](https://npm.chart.dev/ocache)\n\n<!-- /automd -->\n\nComposable caching primitives with TTL, stale-while-revalidate, and HTTP response caching. Zero framework dependencies — works with any runtime that has standard `Request`/`Response`.\n\n> [!TIP]\n> 📖 Head to the [documentation](https://ocache.unjs.io/guide) to learn more.\n\n## Features\n\n- 🗃️ **[Function caching](https://ocache.unjs.io/functions)** — wrap any function with TTL, stale-while-revalidate, and request deduplication.\n- 🌐 **[HTTP response caching](https://ocache.unjs.io/handler)** — automatic `etag` and `304 Not Modified` support.\n- 🔑 **[Smart cache keys](https://ocache.unjs.io/query-params)** — derived from arguments or request URL, with per-header and per-query variance.\n- 🔌 **[Pluggable storage](https://ocache.unjs.io/storage)** — bring your own backend via a minimal `get`/`set` interface.\n- ♻️ **[Invalidation & expiration](https://ocache.unjs.io/invalidation)** — remove or mark entries stale on demand, with SWR background refresh.\n\n## Usage\n\n### Caching Functions\n\nWrap any function with `defineCachedFunction` to add caching with TTL, stale-while-revalidate, and request deduplication:\n\n```ts\nimport { defineCachedFunction } from \"ocache\";\n\nconst cachedFetch = defineCachedFunction(\n  async (url: string) => {\n    const res = await fetch(url);\n    return res.json();\n  },\n  {\n    maxAge: 60, // Cache for 60 seconds\n    name: \"api-fetch\",\n  },\n);\n\n// First call hits the function, subsequent calls return cached result\nconst data = await cachedFetch(\"https://api.example.com/data\");\n```\n\n> [!NOTE]\n> Learn more in the [Caching Functions](https://ocache.unjs.io/functions) guide, and see [Invalidation & Expiration](https://ocache.unjs.io/invalidation) and [Storage](https://ocache.unjs.io/storage).\n\n### Caching HTTP Handlers\n\nWrap HTTP handlers with `defineCachedHandler` for automatic response caching with `etag` and `304 Not Modified` support:\n\n```ts\nimport { defineCachedHandler } from \"ocache\";\n\nconst handler = defineCachedHandler(\n  async (event) => {\n    // event.req is a standard Request object\n    const url = event.url ?? new URL(event.req.url);\n    const data = await getExpensiveData(url.pathname);\n    return new Response(JSON.stringify(data), {\n      headers: { \"content-type\": \"application/json\" },\n    });\n  },\n  {\n    maxAge: 300, // Cache for 5 minutes\n    swr: true,\n    staleMaxAge: 600,\n    varies: [\"accept-language\"], // Vary cache key by these headers (also emitted as `Vary`)\n    allowQuery: [\"color\"], // Opt in: only these query params vary the cache (default: none)\n  },\n);\n```\n\n> [!NOTE]\n> Learn more in the [Caching HTTP Handlers](https://ocache.unjs.io/handler) guide, and see [Query Parameters](https://ocache.unjs.io/query-params), [Cookies](https://ocache.unjs.io/cookies), [Cache-Control & Eligibility](https://ocache.unjs.io/cache-control), and [Incremental Static Regeneration](https://ocache.unjs.io/isr).\n\n## API\n\n<!-- automd:docs4ts -->\n\n### `BlobValue`\n\n```ts\ntype BlobValue = ArrayBufferView | ArrayBufferLike;\n```\n\nWhat a byte backend may return: a view, or the buffer behind one.\n\n---\n\n### `CachedEventHandler`\n\n```ts\ntype CachedEventHandler<E extends HTTPEvent = HTTPEvent> = EventHandler<E> &\n```\n\nCached handler with resource-level cache management methods.\n\nEach method covers GET and HEAD variants in every base prefix.\n\n---\n\n### `cachedFunction`\n\n```ts\nconst cachedFunction = defineCachedFunction;\n```\n\nAlias for [`defineCachedFunction`](#definecachedfunction).\n\n---\n\n### `CacheStatus`\n\n```ts\ntype CacheStatus = \"hit\" | \"stale\" | \"revalidated\" | \"miss\";\n```\n\nResult of one cache call.\n\n- `\"hit\"`: returned a fresh stored value.\n- `\"stale\"`: returned stale data and started background revalidation.\n- `\"revalidated\"`: replaced an old value before returning.\n- `\"miss\"`: resolved a value when none existed.\n\n---\n\n### `composeStorage`\n\n```ts\nfunction composeStorage(\n  layers: ReadonlyArray<StorageInterface | StorageLayer>,\n  opts: ComposeStorageOptions =\n```\n\nCombines several backends into one tiered [`StorageInterface`](#storageinterface).\n\nReads try each layer in order and stop at the first hit, promoting it into every earlier\nlayer. Writes and deletes reach every layer. A layer that throws is skipped rather than\nfailing the operation, so a shared remote layer can be down while a local one still serves.\n\nThis is a backend, not a cache option: the cache above it sees one store with one\ndeclaration, so nothing in the key, the entry, or the purge path changes.\n\n**Example:**\n\n```ts\nconst storage = composeStorage([\n  { storage: createMemoryStorage({ maxBytes: 64 * 1024 * 1024 }), ttl: 60 },\n  createBlobStorage(redis),\n]);\n```\n\n---\n\n### `createBlobStorage`\n\n```ts\nfunction createBlobStorage(backend: BlobBackend): StorageInterface;\n```\n\nAdapts a byte-only backend into a [`StorageInterface`](#storageinterface), storing each entry as one frame.\n\nThe entry's metadata travels as JSON and its payload travels as itself, appended after it.\nThat keeps a response body — text or binary — out of the JSON document: text pays no\nescaping in either direction, and bytes pay no base64 and no 4/3 expansion in the backend.\n\nThe payload is the one named by {@link CacheEntry.payload}, which the producer of the entry\ndeclares — `http/entry.ts` for a response body, `cache.ts` for a byte value. Nothing here\ninfers a payload from a value's shape.\n\nThis declares `binary`, because the frame carries the declared payload as bytes. Every\nother member of the entry is JSON, exactly as it would be on a serializing backend: a byte\nview hidden somewhere ocache did not put one does not survive, on this backend or on any\nother JSON-shaped one.\n\nA frame written by a different version is read as a miss, so a format change costs one\nrevalidation rather than a mangled entry.\n\n**Example:**\n\n```ts\nconst storage = createBlobStorage({\n  get: (key) => unstorage.getItemRaw(key),\n  set: (key, value, opts) =>\n    value === null ? unstorage.removeItem(key) : unstorage.setItemRaw(key, value, opts),\n});\n```\n\n---\n\n### `createMemoryStorage`\n\n```ts\nfunction createMemoryStorage(opts: MemoryStorageOptions =\n```\n\nCreates Map-based memory storage with TTLs in seconds and LRU eviction.\n\n---\n\n### `defineCachedFunction`\n\n```ts\nfunction defineCachedFunction<T, ArgsT extends unknown[] = any[]>(\n  fn: (...args: ArgsT) => T | Promise<T>,\n  opts: CacheOptions<T, ArgsT> =\n```\n\nWraps a function with caching, SWR, integrity checks, and request deduplication.\n\n**Parameters:**\n\n- **`fn`** — Function to cache.\n- **`opts`** — Cache options.\n\n**Returns:** — The cached function and its cache management methods.\n\n---\n\n### `defineCachedHandler`\n\n```ts\nfunction defineCachedHandler<E extends HTTPEvent = HTTPEvent>(\n  handler: EventHandler<E>,\n  opts: CachedEventHandlerOptions<E> =\n```\n\nWraps an HTTP handler with response caching and conditional response support.\n\nOnly GET and HEAD requests without Range are cacheable.\nOnly 200, 203, 301, and 308 responses are stored.\nResponse Cache-Control and Vary headers can prevent storage.\n\n**Parameters:**\n\n- **`handler`** — Handler to cache.\n- **`opts`** — Cache and HTTP options.\n\n**Returns:** — A cached handler with resource-level cache management methods.\n\n---\n\n### `EventHandler`\n\n```ts\ntype EventHandler<E extends HTTPEvent = HTTPEvent> = (\n```\n\nHandler that receives an HTTP event.\n\n---\n\n### `expireCache`\n\n```ts\nasync function expireCache<ArgsT extends unknown[] = any[]>(\n  input:\n```\n\nMarks matching entries as stale without removing them.\n\nSWR may serve the stale value within its original stale window.\nWithout SWR, the next call revalidates before returning.\nPass the original lifetime options to preserve the remaining storage TTL.\nThis function throws when `options.storage` is unset.\n\n**Parameters:**\n\n- **`input`** — Cache options and function arguments.\n\n**Example:**\n\n```ts\nawait expireCache({\n  options: { name: \"fetchUser\", getKey: (id: string) => id, maxAge: 60, swr: true, storage },\n  args: [\"user-123\"],\n});\n```\n\n---\n\n### `invalidateCache`\n\n```ts\nasync function invalidateCache<ArgsT extends unknown[] = any[]>(\n  input:\n```\n\nRemoves matching entries from all base prefixes.\n\nPass the original options object or the same explicit storage backend.\nThis function throws when `options.storage` is unset because no global store exists.\nPrefer the cached function's `.invalidate()` method when available.\n\n**Parameters:**\n\n- **`input`** — Cache options and function arguments.\n\n**Example:**\n\n```ts\nawait invalidateCache({\n  options: { name: \"fetchUser\", getKey: (id: string) => id, storage },\n  args: [\"user-123\"],\n});\n```\n\n---\n\n### `resolveCacheKeys`\n\n```ts\nasync function resolveCacheKeys<ArgsT extends unknown[] = any[]>(\n  input:\n```\n\nReturns one storage key per base prefix.\n\nPass the same `getKey`, `name`, `group`, and `base` options as the cached function.\nThis helper computes keys without accessing storage.\n\n**Parameters:**\n\n- **`input`** — Cache options and function arguments.\n\n**Returns:** — Storage keys in base-prefix order.\n\n**Example:**\n\n```ts\nconst keys = await resolveCacheKeys({\n  options: { name: \"fetchUser\", getKey: (id: string) => id },\n  args: [\"user-123\"],\n});\n```\n\n---\n\n### `resolveSignal`\n\n```ts\nfunction resolveSignal(event: HTTPEvent): AbortSignal | undefined;\n```\n\nThe deadline signal of the resolution this event leads, if it leads one.\n\n---\n\n### `resolveStatus`\n\n```ts\nfunction resolveStatus(event: HTTPEvent): CacheStatus | undefined;\n```\n\nThe status of the foreground resolution this event leads, if it leads one.\n\n---\n\n### `StorageOption`\n\n```ts\ntype StorageOption = StorageInterface | (() => StorageInterface);\n```\n\nA storage instance or a late-bound storage factory.\n\nThe cache calls a factory once, on the first cache operation.\n\n<!-- /automd-->\n\n## Development\n\n<details>\n\n<summary>local development</summary>\n\n- Clone this repository\n- Install latest LTS version of [Node.js](https://nodejs.org/en/)\n- Enable [Corepack](https://github.com/nodejs/corepack) using `corepack enable`\n- Install dependencies using `pnpm install`\n- Run interactive tests using `pnpm dev`\n\n</details>\n\n## License\n\nPublished under the [MIT](https://github.com/unjs/ocache/blob/main/LICENSE) license 💛.\n","readmeFilename":"README.md"}