https://github.com/hansottowirtz/cloudflare-workers-cache
`unstable_cache` from Next.js for Cloudflare Workers
https://github.com/hansottowirtz/cloudflare-workers-cache
cache cloudflare-cache cloudflare-workers kv-store nextjs
Last synced: 3 months ago
JSON representation
`unstable_cache` from Next.js for Cloudflare Workers
- Host: GitHub
- URL: https://github.com/hansottowirtz/cloudflare-workers-cache
- Owner: hansottowirtz
- Created: 2024-04-13T19:01:03.000Z (over 1 year ago)
- Default Branch: main
- Last Pushed: 2024-04-20T18:12:50.000Z (over 1 year ago)
- Last Synced: 2024-04-28T03:29:48.756Z (over 1 year ago)
- Topics: cache, cloudflare-cache, cloudflare-workers, kv-store, nextjs
- Language: TypeScript
- Homepage: https://cloudflare-workers-cache-example-app.hansottowirtz.be/sum?a=1&b=1
- Size: 1.02 MB
- Stars: 3
- Watchers: 1
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
Awesome Lists containing this project
README
# `unstable_cache` from Next.js for Cloudflare Workers
Cache any JSON-serializable result from an async function. It uses the same API as [`unstable_cache` from Next.js](https://nextjs.org/docs/app/api-reference/functions/unstable_cache).
- Simple wrapper function over the [Cloudflare Workers Cache API](https://developers.cloudflare.com/workers/runtime-apis/cache/#accessing-cache).
- Supports time-based and tag-based cache revalidation.
- Stores tag revalidation data in a KV store.
- No need for a Cloudflare Enterprise account for tag revalidation.```ts
const getUser = (id: number) => sql`SELECT * FROM users WHERE id = ${id}`;const cachedGetUser = cache(getUser, ["get-user"], {
tags: ["users"],
revalidate: 60,
});// on edit
revalidateTag("users");
```## Installation
```bash
npm install cloudflare-workers-cache
```## Setup
First, create a kv namespace:
```bash
wrangler kv:namespace create CACHE_TAG_STORE
```Then, adjust your `wrangler.toml`:
```toml
compatibility_flags = ["nodejs_compat"] # needed because this library uses AsyncLocalStoragekv_namespaces = [{ binding = "CACHE_TAG_STORE", id = "..." }] # copy this from the output of the previous command
```## Usage
See [example-app/src/index.ts](example-app/src/index.ts) for a fully working example.
```ts
import {
cache,
revalidateTag,
provideCacheToFetch,
createCfCacheObjectCache,
createCfKvCacheTagStore,
} from "cloudflare-workers-cache";// cache an async function
const cachedSum = cache(sum, ["sum"], {
tags: ["sum"],
});// configure which object cache and cache tag store to use
const cacheConfig = {
objectCache: createCfCacheObjectCache(caches.open("cache")),
cacheTagStore: (env) => createCfKvCacheTagStore(env.CACHE_TAG_STORE),
};export default {
fetch: provideCacheToFetch(cacheConfig, async (req) => {
const url = new URL(req.url);
if (url.pathname === "/sum") {
const a = +url.searchParams.get("a")!;
const b = +url.searchParams.get("b")!;
const result = await cachedSum(a, b);
return new Response(result.toString());
} else if (url.pathname === "/revalidate") {
revalidateTag("sum");
return new Response("Revalidated");
}
return new Response("Not found", { status: 404 });
}),
}
```## API
### `cache(fn, keyParts, options)`
Cache the result of an async function. Same API as [`unstable_cache` from Next.js](https://nextjs.org/docs/app/api-reference/functions/unstable_cache).
- `fn`: The async function to cache.
- `keyParts`: The combination of the function arguments and `keyParts` create the cache key.
- `options`:
- `tags`: Tags which can be used in `revalidateTag`.
- `revalidate`: Time in seconds after which the cache should be revalidated.### `revalidateTag(tag)`
Revalidate all cache entries with the given tag. Revalidation occurs on the next function call.
### `provideCacheToFetch(cacheConfig, handler)`
Wrap a fetch handler with the cache configuration.
Alternatively, you can use `provideWaitUntil`, `provideObjectCache`, `provideCacheTagStore` to set async contexts separately. See [src/wrap-fetch.ts](src/wrap-fetch.ts).
### `createCfCacheObjectCache(cache)`
Create an object cache using the Cloudflare Cache.
### `createCfKvCacheTagStore(kvNamespace)`
Create a cache tag store using a Cloudflare KV store.
## Write custom cache stores
By default, the object cache uses Cloudflare Cache, and the tag store uses Cloudflare KV, see [src/cloudflare-adapters.ts](src/cloudflare-adapters.ts). You can write your own implementations by implementing the `ObjectCache` and `CacheTagStore` interfaces.
```ts
const customObjectCache: ObjectCache = {
async get(key) {
// ...
},
async set(key, value, duration) {
// ...
},
}const customCacheTagStore: CacheTagStore = {
async getTagsCacheKey(tags) {
// ...
},
async revalidateTag(tag) {
// ...
}
}const cacheConfig: CacheConfig = {
objectCache: customObjectCache,
cacheTagStore: customCacheTagStore,
};
```## TODO
- Allow usage of `Cache-Tag` revalidation for Cloudflare Enterprise customers.