@mrjasonroy/cache-components-cache-handler 16.0.1 → 16.0.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (2) hide show
  1. package/README.md +136 -364
  2. package/package.json +1 -1
package/README.md CHANGED
@@ -1,442 +1,214 @@
1
1
  # @mrjasonroy/cache-components-cache-handler
2
2
 
3
- Modern cache handler for Next.js 16+ with support for the `"use cache"` directive and cache components.
3
+ Cache handler for Next.js 16+ with support for Cache Components and "use cache" directive.
4
4
 
5
- ## Features
5
+ > Why another cache handler? I was originally going to contribute to [fortedigital/nextjs-cache-handler](https://github.com/fortedigital/nextjs-cache-handler) but that project is focused on backwards compatibility and carries a lot of legacy baggage. This repo is a ground-up rewrite that:
6
+ > - Targets **Next.js 16+ only** (Cache Components, `"use cache"`, `cacheLife`, etc.)
7
+ > - Ships with **true E2E coverage** (Playwright + Next 16) for every backend
8
+ > - Keeps the surface area small: zero-config memory handler for dev, Redis/Valkey/ElastiCache factory for prod
9
+ > - Provides an AI-first workflow so contributors (human or agent) can ship confidently
6
10
 
7
- - ✅ **Next.js 16+ only** - Built specifically for the new caching system
8
- - ✅ **TypeScript** - Full type safety with strict mode
9
- - ✅ **In-memory LRU** - Fast, production-ready memory caching
10
- - ✅ **Composite handler** - Multi-tier caching strategies
11
- - ✅ **Tag-based revalidation** - Both explicit and implicit tags
12
- - ✅ **TTL support** - Time-based expiration
13
- - ✅ **Zero dependencies** - Lightweight and fast
14
- - ✅ **Comprehensive tests** - 31 tests, 100% coverage
11
+ [![npm version](https://badge.fury.io/js/@mrjasonroy%2Fcache-components-cache-handler.svg)](https://www.npmjs.com/package/@mrjasonroy/cache-components-cache-handler)
12
+ [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
13
+ [![TypeScript](https://img.shields.io/badge/TypeScript-5.7-blue)](https://www.typescriptlang.org/)
14
+ [![Next.js 16+](https://img.shields.io/badge/Next.js-16%2B-black)](https://nextjs.org/)
15
+ [![Tests](https://img.shields.io/badge/tests-passing-brightgreen)](https://github.com/mrjasonroy/cache-components-cache-handler/tree/main/apps/e2e-test-app)
15
16
 
16
- ## Installation
17
+ **📦 [View on npm](https://www.npmjs.com/package/@mrjasonroy/cache-components-cache-handler) | 🚀 [Releases](https://github.com/mrjasonroy/cache-components-cache-handler/releases)**
17
18
 
18
- ```bash
19
- npm install @mrjasonroy/cache-components-cache-handler
20
- # or
21
- pnpm add @mrjasonroy/cache-components-cache-handler
22
- # or
23
- yarn add @mrjasonroy/cache-components-cache-handler
24
- ```
19
+ ## What This Does
25
20
 
26
- ## Quick Start
21
+ Implements Next.js 16+ caching APIs:
22
+ - `"use cache"` directive
23
+ - `cacheLife()` - Configure cache lifetime
24
+ - `cacheTag()` - Tag cache entries
25
+ - `revalidateTag()` - Invalidate by tags
26
+ - `updateTag()` - Update tags
27
+ - `revalidatePath()` - Invalidate by path
28
+ - Cache Components and PPR
27
29
 
28
- ### Setup for Next.js 16
30
+ ## Supported Backends
29
31
 
30
- Next.js 16 has **two separate cache systems**:
31
- 1. **ISR Cache** (`cacheHandler`) - For Incremental Static Regeneration
32
- 2. **Data Cache** (`cacheHandlers`) - For `"use cache"` and `"use cache: remote"`
32
+ All backends are **integration tested** with Next.js 16+ in CI so you can trust a release tag.
33
33
 
34
- Use the helper function to configure both easily:
34
+ | Backend | Use Case | Key Features |
35
+ |---------|----------|--------------|
36
+ | **Memory** | Development, Single-instance | Zero config, fast, no external dependencies |
37
+ | **Redis** | Production, Distributed | Industry standard, high performance, clustering |
38
+ | **Valkey** | Production, Open Source | Redis-compatible, LGPL licensed, drop-in replacement |
39
+ | **AWS ElastiCache** | Production, Managed | Fully managed, IAM auth, auto-scaling, high availability |
35
40
 
36
- ```typescript
37
- // next.config.mjs
38
- import { createCacheConfig } from "@mrjasonroy/cache-components-cache-handler";
39
- import { resolve } from "path";
41
+ ## Install
40
42
 
41
- const cacheConfig = createCacheConfig({
42
- isrHandlerPath: resolve(process.cwd(), "./cache-handler.mjs"),
43
- dataCacheHandlerPath: resolve(process.cwd(), "./data-cache-handler.mjs"),
44
- });
43
+ ```bash
44
+ npm install @mrjasonroy/cache-components-cache-handler
45
45
 
46
- export default {
47
- cacheComponents: true, // Enable cache components
48
- ...cacheConfig,
49
- // Rest of your Next.js config
50
- };
46
+ # For Redis/Valkey/ElastiCache, also install ioredis
47
+ npm install ioredis
51
48
  ```
52
49
 
53
- Then create your cache handler files:
54
-
55
- ```javascript
56
- // cache-handler.mjs (ISR Cache)
57
- import { createMemoryCacheHandler } from "@mrjasonroy/cache-components-cache-handler";
50
+ ## Quick Start
58
51
 
59
- export default createMemoryCacheHandler({
60
- maxItemsNumber: 1000,
61
- maxItemSizeBytes: 100 * 1024 * 1024, // 100MB
62
- });
63
- ```
52
+ ### Zero-Config (Recommended)
64
53
 
65
54
  ```javascript
66
- // data-cache-handler.mjs (Data Cache for "use cache")
55
+ // data-cache-handler.mjs
67
56
  import { createCacheHandler } from "@mrjasonroy/cache-components-cache-handler";
68
57
 
69
- export default createCacheHandler({
70
- type: process.env.NODE_ENV === "production" ? "redis" : "memory",
71
- url: process.env.REDIS_URL,
72
- password: process.env.REDIS_PASSWORD,
73
- debug: process.env.NODE_ENV === "development",
74
- });
75
- ```
76
-
77
- ### Multi-Tier Caching
58
+ // Memory (dev)
59
+ export default createCacheHandler({ type: "memory" });
78
60
 
79
- ```typescript
80
- // next.config.js
81
- import {
82
- createCompositeHandler,
83
- createMemoryCacheHandler,
84
- RedisCacheHandler,
85
- } from "@mrjasonroy/cache-components-cache-handler";
86
-
87
- const memoryHandler = createMemoryCacheHandler({
88
- maxItemsNumber: 100, // Small L1 cache
89
- });
61
+ // Redis (production)
62
+ export default createCacheHandler({ type: "redis" });
90
63
 
91
- const redisHandler = new RedisCacheHandler({
92
- redis: process.env.REDIS_URL ?? "redis://localhost:6379",
93
- defaultTTL: 3600,
94
- });
64
+ // Valkey (production)
65
+ export default createCacheHandler({ type: "valkey" });
95
66
 
96
- export default {
97
- cacheHandler: createCompositeHandler({
98
- handlers: [memoryHandler, redisHandler],
99
- // Optional: route based on tags
100
- setStrategy: (data) => {
101
- if (data.tags.includes("memory-only")) {
102
- return 0; // Use memory handler
103
- }
104
- return 1; // Use Redis handler
105
- },
106
- }),
107
- };
67
+ // ElastiCache (AWS)
68
+ export default createCacheHandler({ type: "elasticache" });
108
69
  ```
109
70
 
110
- ## API Reference
111
-
112
- ### `createCacheConfig(options)`
113
-
114
- Helper function to generate Next.js 16 cache configuration for both ISR and Data Cache.
115
-
116
- **Options:**
117
-
118
- | Option | Type | Required | Description |
119
- |--------|------|----------|-------------|
120
- | `isrHandlerPath` | `string` | Yes | Path to ISR cache handler file |
121
- | `dataCacheHandlerPath` | `string` | Yes | Path to data cache handler file |
122
- | `disableDefaultMemoryCache` | `boolean` | No | Disable Next.js default memory cache (default: `true`) |
123
-
124
- **Returns:**
125
-
126
- ```typescript
127
- {
128
- cacheHandler: string; // ISR cache handler path
129
- cacheHandlers: {
130
- default: string; // "use cache" handler path
131
- remote: string; // "use cache: remote" handler path
132
- };
133
- cacheMaxMemorySize?: number; // 0 if disableDefaultMemoryCache is true
134
- }
135
- ```
136
-
137
- **Example:**
138
-
139
- ```typescript
140
- import { createCacheConfig } from "@mrjasonroy/cache-components-cache-handler";
141
- import { resolve } from "path";
142
-
143
- const cacheConfig = createCacheConfig({
144
- isrHandlerPath: resolve(process.cwd(), "./cache-handler.mjs"),
145
- dataCacheHandlerPath: resolve(process.cwd(), "./data-cache-handler.mjs"),
146
- });
147
-
71
+ ```javascript
72
+ // next.config.js
148
73
  export default {
149
74
  cacheComponents: true,
150
- ...cacheConfig,
75
+ cacheHandlers: {
76
+ default: "./data-cache-handler.mjs",
77
+ remote: "./data-cache-handler.mjs",
78
+ },
79
+ cacheMaxMemorySize: 0, // Disable Next's built-in in-memory handler
151
80
  };
152
81
  ```
153
82
 
154
- ### `createCacheConfigWithProfiles(options)`
155
-
156
- Advanced helper for using different cache handlers for `default` and `remote` profiles.
83
+ **Environment Variables:**
84
+ - `REDIS_URL` / `VALKEY_URL` - Primary connection string for Redis-compatible stores (Valkey works with the same URI format, e.g. `redis://localhost:6380` when using the provided docker-compose service)
85
+ - `REDIS_PASSWORD` - Password/token used when your URL lacks credentials (works for every backend)
86
+ - `ELASTICACHE_ENDPOINT` / `ELASTICACHE_PORT` - AWS ElastiCache hostname + port
87
+ - `ELASTICACHE_TLS` - `"true"`/`"false"` toggle (defaults to `true` for ElastiCache)
88
+ - `ELASTICACHE_AUTH_TOKEN` - Password/token for IAM-authenticated ElastiCache clusters
157
89
 
158
- **Options:**
90
+ ### Advanced: Custom Configuration
159
91
 
160
- | Option | Type | Required | Description |
161
- |--------|------|----------|-------------|
162
- | `isrHandlerPath` | `string` | Yes | Path to ISR cache handler file |
163
- | `defaultDataCacheHandlerPath` | `string` | Yes | Path for "use cache" (fast, local) |
164
- | `remoteDataCacheHandlerPath` | `string` | Yes | Path for "use cache: remote" (DB, API) |
165
- | `disableDefaultMemoryCache` | `boolean` | No | Disable Next.js default memory cache (default: `true`) |
92
+ Need more control? You can override any option:
166
93
 
167
- **Example:**
94
+ ```javascript
95
+ // data-cache-handler.mjs
96
+ import { createCacheHandler } from "@mrjasonroy/cache-components-cache-handler";
168
97
 
169
- ```typescript
170
- const cacheConfig = createCacheConfigWithProfiles({
171
- isrHandlerPath: resolve(process.cwd(), "./cache-handler.mjs"),
172
- defaultDataCacheHandlerPath: resolve(process.cwd(), "./data-cache-memory.mjs"),
173
- remoteDataCacheHandlerPath: resolve(process.cwd(), "./data-cache-redis.mjs"),
98
+ export default createCacheHandler({
99
+ type: "elasticache",
100
+ endpoint: "cache.prod-cluster.cache.amazonaws.com",
101
+ port: 6380,
102
+ tls: true,
103
+ password: process.env.CACHE_AUTH_TOKEN,
104
+ keyPrefix: "myapp:cache:",
105
+ tagPrefix: "myapp:tags:",
106
+ debug: process.env.NODE_ENV === "development",
174
107
  });
175
108
  ```
176
109
 
177
- ### `createMemoryCacheHandler(options?)`
178
-
179
- Creates an in-memory LRU cache handler.
180
-
181
- **Options:**
182
-
183
- | Option | Type | Default | Description |
184
- |--------|------|---------|-------------|
185
- | `maxItemsNumber` | `number` | `1000` | Maximum number of items to store |
186
- | `maxItemSizeBytes` | `number` | `104857600` (100MB) | Maximum size per item |
187
- | `defaultTTL` | `number` | `undefined` | Default TTL in seconds |
188
-
189
- **Features:**
190
-
191
- - LRU eviction when max size exceeded
192
- - Automatic expiration based on TTL
193
- - Tag-based revalidation (explicit and implicit)
194
- - Size-based rejection of oversized entries
195
-
196
- **Example:**
110
+ ## Usage
197
111
 
198
112
  ```typescript
199
- const handler = createMemoryCacheHandler({
200
- maxItemsNumber: 500,
201
- maxItemSizeBytes: 50 * 1024 * 1024, // 50MB
202
- defaultTTL: 1800, // 30 minutes
203
- });
204
- ```
205
-
206
- ### `createCompositeHandler(options)`
207
-
208
- Creates a composite handler that orchestrates multiple cache handlers.
209
-
210
- **Options:**
211
-
212
- | Option | Type | Required | Description |
213
- |--------|------|----------|-------------|
214
- | `handlers` | `CacheHandler[]` | Yes | Array of handlers (ordered by priority) |
215
- | `setStrategy` | `(data) => number` | No | Function to choose which handler to use for writes |
216
-
217
- **Features:**
218
-
219
- - First-match read strategy (tries handlers in order)
220
- - Configurable write strategy
221
- - Fault tolerance with `Promise.allSettled()`
222
- - Parallel revalidation across all handlers
223
-
224
- **Example:**
113
+ // Basic caching
114
+ async function ProductList() {
115
+ "use cache";
116
+ const products = await db.products.findMany();
117
+ return <ProductGrid products={products} />;
118
+ }
225
119
 
226
- ```typescript
227
- const composite = createCompositeHandler({
228
- handlers: [memoryHandler, redisHandler],
229
- setStrategy: (data) => {
230
- // Cache small items in memory, large items in Redis
231
- const size = JSON.stringify(data).length;
232
- return size < 10000 ? 0 : 1;
233
- },
234
- });
235
- ```
120
+ // With cache lifetime
121
+ import { cacheLife } from "next/cache";
236
122
 
237
- ## Advanced Usage
123
+ async function BlogPost({ id }: { id: string }) {
124
+ "use cache";
125
+ cacheLife("hours"); // 1 hour
126
+ const post = await db.posts.findUnique({ where: { id } });
127
+ return <Article post={post} />;
128
+ }
238
129
 
239
- ### Tag-Based Revalidation
130
+ // With tags for selective invalidation
131
+ import { cacheTag } from "next/cache";
240
132
 
241
- ```typescript
242
- // app/page.tsx
243
- export default async function Page() {
133
+ async function UserProfile({ userId }: { userId: string }) {
244
134
  "use cache";
245
- // This component will be cached with implicit tags
246
- return <div>Cached content</div>;
135
+ cacheTag("user-profile", `user:${userId}`);
136
+ const user = await db.user.findUnique({ where: { id: userId } });
137
+ return <Profile user={user} />;
247
138
  }
248
139
 
249
- // app/api/revalidate/route.ts
140
+ // Invalidate from API route
250
141
  import { revalidateTag } from "next/cache";
251
142
 
252
143
  export async function POST(request: Request) {
253
- const { tag } = await request.json();
254
- revalidateTag(tag);
144
+ const { userId } = await request.json();
145
+ revalidateTag(`user:${userId}`);
255
146
  return Response.json({ revalidated: true });
256
147
  }
257
148
  ```
258
149
 
259
- ### Time-Based Revalidation
150
+ ## Cache Handler API
260
151
 
261
- ```typescript
262
- // app/page.tsx
263
- export default async function Page() {
264
- "use cache";
265
- export const revalidate = 3600; // Revalidate after 1 hour
266
-
267
- return <div>Cached for 1 hour</div>;
268
- }
269
- ```
270
-
271
- ### Custom Cache Tags
152
+ This library implements the Next.js 16+ `DataCacheHandler` interface:
272
153
 
273
154
  ```typescript
274
- // app/actions.ts
275
- "use server";
155
+ interface DataCacheHandler {
156
+ // Retrieve cached entry for a cache key
157
+ get(cacheKey: string, softTags: string[]): Promise<DataCacheEntry | undefined>;
276
158
 
277
- import { unstable_cache } from "next/cache";
159
+ // Store a cache entry (handles streaming responses)
160
+ set(cacheKey: string, pendingEntry: Promise<DataCacheEntry>): Promise<void>;
278
161
 
279
- export const getData = unstable_cache(
280
- async () => {
281
- return fetch("https://api.example.com/data").then((res) => res.json());
282
- },
283
- ["api-data"],
284
- {
285
- tags: ["api-data", "user-data"],
286
- revalidate: 3600,
287
- },
288
- );
289
- ```
290
-
291
- ## How It Works
292
-
293
- ### Implicit vs Explicit Tags
294
-
295
- Next.js 16 uses two types of tags:
296
-
297
- 1. **Explicit tags** - User-defined tags (e.g., `["user-123", "posts"]`)
298
- 2. **Implicit tags** - System-generated tags with `_N_T_` prefix for ISR
299
-
300
- The handler tracks both types separately for efficient revalidation.
301
-
302
- ### LRU Eviction
303
-
304
- When the cache reaches `maxItemsNumber`:
305
-
306
- 1. The oldest (least recently used) entry is evicted
307
- 2. Entries are moved to the end on each access
308
- 3. New entries are always added at the end
309
-
310
- ### TTL Expiration
311
-
312
- Entries can expire based on:
313
-
314
- 1. `revalidate` value in cache context (seconds)
315
- 2. `defaultTTL` if no revalidate specified
316
- 3. Never expire if `revalidate: false`
317
-
318
- Expiration is checked on every `get()` call (lazy expiration).
319
-
320
- ## Type Definitions
321
-
322
- ```typescript
323
- interface CacheHandler {
324
- name: string;
325
- get(key: string, meta?: CacheHandlerGetMeta): Promise<CacheValue | null>;
326
- set(key: string, value: CacheValue, context?: CacheHandlerContext): Promise<void>;
327
- revalidateTag(tag: string): Promise<void>;
328
- delete?(key: string): Promise<void>;
329
- }
162
+ // Called periodically to refresh local tag manifest
163
+ refreshTags(): Promise<void>;
330
164
 
331
- interface CacheHandlerContext {
332
- tags?: string[];
333
- revalidate?: number | false;
334
- softTags?: string[];
335
- }
165
+ // Get maximum revalidation timestamp for tags
166
+ getExpiration(tags: string[]): Promise<Timestamp>;
336
167
 
337
- interface CacheHandlerGetMeta {
338
- implicitTags: string[];
168
+ // Called when revalidateTag() invalidates tags
169
+ updateTags(tags: string[], durations?: { expire?: number }): Promise<void>;
339
170
  }
340
171
  ```
341
172
 
342
- ## Testing
343
-
344
- ```bash
345
- # Run tests
346
- pnpm test
347
-
348
- # Run tests in watch mode
349
- pnpm test:watch
350
-
351
- # Run with coverage
352
- pnpm test --coverage
353
- ```
354
-
355
- ## Performance
173
+ When you call `revalidateTag('my-tag')` in your application, Next.js internally calls our `updateTags(['my-tag'])` implementation, which marks all cache entries with that tag as stale.
356
174
 
357
- The memory handler is optimized for production use:
175
+ ## Documentation
358
176
 
359
- - Native `Map` for O(1) lookups
360
- - Minimal overhead per cache entry
361
- - Zero dependencies
362
- - Fast expiration checks
363
- - Efficient LRU implementation
177
+ - [GitHub Repository](https://github.com/mrjasonroy/cache-components-cache-handler)
178
+ - [Redis Configuration](https://github.com/mrjasonroy/cache-components-cache-handler/blob/main/docs/redis.md)
179
+ - [Valkey & ElastiCache Setup](https://github.com/mrjasonroy/cache-components-cache-handler/blob/main/docs/redis.md#valkey)
180
+ - [Contributing](https://github.com/mrjasonroy/cache-components-cache-handler/blob/main/CONTRIBUTING.md)
364
181
 
365
- Benchmark (1000 items, 1KB each):
182
+ ## CI & Test Matrix
366
183
 
367
- - Set: ~0.01ms per item
368
- - Get: ~0.005ms per item
369
- - Memory usage: ~1MB + cache data
370
-
371
- ## Migration from Other Handlers
372
-
373
- ### From Next.js Built-in Cache
374
-
375
- ```diff
376
- // next.config.js
377
- + import { createMemoryCacheHandler } from "@mrjasonroy/cache-components-cache-handler";
378
-
379
- export default {
380
- + cacheHandler: createMemoryCacheHandler(),
381
- };
382
- ```
184
+ | Workflow | What it Verifies |
185
+ |----------|------------------|
186
+ | **CI** | Biome lint + format check, typecheck, Vitest, and Playwright e2e suites against Memory, Redis, Valkey, and ElastiCache-mode backends |
187
+ | **Next.js Canary Test** | Daily compatibility runs against Next.js canary/rc/latest to catch upstream breakage |
188
+ | **Next.js Version Check** | Nightly scan for new Next.js releases, opens PRs to bump peer deps |
189
+ | **Publish** | Trusted publishing with provenance – release tags must pass the full matrix before npm sees them |
383
190
 
384
- ### From Custom Redis Handler
191
+ ## Development
385
192
 
386
- ```diff
387
- // next.config.js
388
- import {
389
- createMemoryCacheHandler,
390
- + createCompositeHandler,
391
- } from "@mrjasonroy/cache-components-cache-handler";
392
- import { createRedisHandler } from "./redis-handler";
393
-
394
- export default {
395
- - cacheHandler: createRedisHandler(),
396
- + cacheHandler: createCompositeHandler({
397
- + handlers: [
398
- + createMemoryCacheHandler({ maxItemsNumber: 100 }), // L1 cache
399
- + createRedisHandler(), // L2 cache
400
- + ],
401
- + }),
402
- };
193
+ ```bash
194
+ git clone https://github.com/mrjasonroy/cache-components-cache-handler
195
+ cd cache-components-cache-handler
196
+ pnpm install
197
+ pnpm build
198
+ pnpm test
403
199
  ```
404
200
 
405
- ## Troubleshooting
406
-
407
- ### Cache not working
408
-
409
- 1. Check Next.js version (requires 16.0.0+)
410
- 2. Verify `"use cache"` directive is at top of component/function
411
- 3. Check browser/server console for errors
412
-
413
- ### Memory usage too high
414
-
415
- 1. Reduce `maxItemsNumber`
416
- 2. Reduce `maxItemSizeBytes`
417
- 3. Add TTL with `defaultTTL`
418
- 4. Use composite handler with Redis for large caches
419
-
420
- ### Revalidation not working
421
-
422
- 1. Verify tags are correctly defined
423
- 2. Check `revalidateTag()` is called on server
424
- 3. Ensure implicit tags are passed to `get()`
425
-
426
201
  ## Contributing
427
202
 
428
- This project is part of a monorepo. See the main [README](../../README.md) for contribution guidelines.
429
-
430
- ## License
203
+ This project is AI-friendly and contributor-friendly.
431
204
 
432
- MIT © Jason Roy
205
+ - **For AI Agents:** See [CLAUDE.md](https://github.com/mrjasonroy/cache-components-cache-handler/blob/main/CLAUDE.md) for instructions
206
+ - **For Humans:** See [CONTRIBUTING.md](https://github.com/mrjasonroy/cache-components-cache-handler/blob/main/CONTRIBUTING.md)
433
207
 
434
- ## Support
208
+ ## License
435
209
 
436
- - [GitHub Issues](https://github.com/mrjasonroy/cache-components-cache-handler/issues)
437
- - [Documentation](https://github.com/mrjasonroy/cache-components-cache-handler)
210
+ MIT © [Jason Roy](https://github.com/mrjasonroy)
438
211
 
439
- ## Related
212
+ ## Acknowledgments
440
213
 
441
- - [Next.js 16 Cache Documentation](https://nextjs.org/docs/app/getting-started/cache-components)
442
- - [@mrjasonroy/cache-components-cache-handler-redis](../cache-handler-redis) - Redis implementation
214
+ Forked from/Inspired by [@fortedigital/nextjs-cache-handler](https://github.com/fortedigital/nextjs-cache-handler), but focusing only on supporting Next.js 16+ and the new caching system.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mrjasonroy/cache-components-cache-handler",
3
- "version": "16.0.1",
3
+ "version": "16.0.3",
4
4
  "description": "Cache handler for Next.js 16+ with support for 'use cache' directive and Cache Components",
5
5
  "author": "Jason Roy",
6
6
  "license": "MIT",