@leejpsd/nextjs-cache-handler 0.2.0 → 0.3.1
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.
- package/CHANGELOG.md +67 -2
- package/README.md +47 -25
- package/dist/cache-components/index.cjs +235 -46
- package/dist/cache-components/index.cjs.map +1 -1
- package/dist/cache-components/index.d.cts +1 -1
- package/dist/cache-components/index.d.ts +1 -1
- package/dist/cache-components/index.js +227 -46
- package/dist/cache-components/index.js.map +1 -1
- package/dist/incremental/index.cjs +231 -41
- package/dist/incremental/index.cjs.map +1 -1
- package/dist/incremental/index.d.cts +42 -3
- package/dist/incremental/index.d.ts +42 -3
- package/dist/incremental/index.js +223 -41
- package/dist/incremental/index.js.map +1 -1
- package/dist/index.cjs +313 -70
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +305 -70
- package/dist/index.js.map +1 -1
- package/dist/ops/index.d.cts +1 -1
- package/dist/ops/index.d.ts +1 -1
- package/dist/otel/index.cjs +72 -0
- package/dist/otel/index.cjs.map +1 -0
- package/dist/otel/index.d.cts +72 -0
- package/dist/otel/index.d.ts +72 -0
- package/dist/otel/index.js +64 -0
- package/dist/otel/index.js.map +1 -0
- package/dist/shared/client/adapter-ioredis.cjs +49 -10
- package/dist/shared/client/adapter-ioredis.cjs.map +1 -1
- package/dist/shared/client/adapter-ioredis.d.cts +5 -2
- package/dist/shared/client/adapter-ioredis.d.ts +5 -2
- package/dist/shared/client/adapter-ioredis.js +43 -11
- package/dist/shared/client/adapter-ioredis.js.map +1 -1
- package/dist/shared/client/adapter-redis.cjs +22 -7
- package/dist/shared/client/adapter-redis.cjs.map +1 -1
- package/dist/shared/client/adapter-redis.d.cts +1 -1
- package/dist/shared/client/adapter-redis.d.ts +1 -1
- package/dist/shared/client/adapter-redis.js +16 -7
- package/dist/shared/client/adapter-redis.js.map +1 -1
- package/dist/{types-Dq1q6qXd.d.cts → types-Bl-rkLKX.d.cts} +37 -1
- package/dist/{types-Dq1q6qXd.d.ts → types-Bl-rkLKX.d.ts} +37 -1
- package/package.json +27 -5
package/CHANGELOG.md
CHANGED
|
@@ -1,11 +1,78 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 0.3.1
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- [`f07e91b`](https://github.com/leejpsd/nextjs-cache-handler/commit/f07e91b432be6d52885f2f0a83bfb6c63d519bbe) Thanks [@leejpsd](https://github.com/leejpsd)! - Refresh the npm package description and keywords for the 0.3 feature set:
|
|
8
|
+
Next.js 15/16, built-in compression, Redis Sentinel, OpenTelemetry, and the
|
|
9
|
+
multi-instance AWS validation results.
|
|
10
|
+
|
|
11
|
+
## 0.3.0
|
|
12
|
+
|
|
13
|
+
### Minor Changes
|
|
14
|
+
|
|
15
|
+
- [`dc1ac0a`](https://github.com/leejpsd/nextjs-cache-handler/commit/dc1ac0a0b29e73485f4af587f8ec0f4b68d1d54f) Thanks [@leejpsd](https://github.com/leejpsd)! - Reliability fixes (reconnect backoff instead of a permanent connect-failure
|
|
16
|
+
latch, bounded memory fallback, namespace-scoped tag propagation without
|
|
17
|
+
truncation, strict `fallback: "never"` honored by the ISR handler, working
|
|
18
|
+
ESM peer loading) plus new features: Next.js 15 ISR support, request-scoped
|
|
19
|
+
GET deduplication, transparent gzip/brotli value compression, Redis Sentinel
|
|
20
|
+
support, a built-in OpenTelemetry adapter at `/otel`, and `memoryMaxEntries`.
|
|
21
|
+
|
|
3
22
|
All notable changes to this project are documented here. The format is
|
|
4
23
|
based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and
|
|
5
24
|
this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
6
25
|
|
|
7
26
|
## [Unreleased]
|
|
8
27
|
|
|
28
|
+
### Added
|
|
29
|
+
|
|
30
|
+
- **Next.js 15 support** for the singular `cacheHandler` (ISR): both ctx
|
|
31
|
+
generations accepted (`ctx.revalidate`/`kindHint` and
|
|
32
|
+
`ctx.cacheControl`/`kind`); `peerDependencies.next` widened to
|
|
33
|
+
`>=15.0.0 <17`. Verified end to end against Next 15.5 (build, ISR
|
|
34
|
+
HIT/MISS, tag/path revalidation, fetch-cache TTL, cross-process reads).
|
|
35
|
+
- **Request-scoped GET deduplication** (singular handler):
|
|
36
|
+
`resetRequestCache()` is now a real implementation — duplicate reads of a
|
|
37
|
+
cache key within one request share a single Redis GET. New metric event
|
|
38
|
+
`cache.get.deduped`.
|
|
39
|
+
- **Transparent value compression** (`compression: "gzip" | "brotli"`,
|
|
40
|
+
default off) via node:zlib — marker-prefixed storage with auto-detecting
|
|
41
|
+
reads, safe to enable on a live cache with a mixed fleet. Payloads < 1 KiB
|
|
42
|
+
stay plain.
|
|
43
|
+
- **Redis Sentinel support** (`{ type: "sentinel", sentinels, name }`) via
|
|
44
|
+
ioredis master discovery — verified locally including a live failover.
|
|
45
|
+
- **Built-in OpenTelemetry adapter** at
|
|
46
|
+
`@leejpsd/nextjs-cache-handler/otel` (`createOtelMetricEmitter`);
|
|
47
|
+
`@opentelemetry/api` is an optional peer resolved at runtime.
|
|
48
|
+
- **`memoryMaxEntries` option** (default 1000) bounding the in-memory
|
|
49
|
+
fallback stores with LRU eviction.
|
|
50
|
+
|
|
51
|
+
### Fixed
|
|
52
|
+
|
|
53
|
+
- **Connect failures no longer latch the process into memory-only mode.**
|
|
54
|
+
Reconnects retry with exponential backoff (1s→30s cap) and dropped
|
|
55
|
+
connections are replaced (dead clients disposed).
|
|
56
|
+
- **`refreshTags` scans only the current build namespace** and processes
|
|
57
|
+
markers chunk-by-chunk — the previous 500-key cap silently left tags
|
|
58
|
+
unpropagated; the local mirror is now rebuilt per complete scan (bounded
|
|
59
|
+
by live markers) and `memTagExp` is capped.
|
|
60
|
+
- **`fallback: "never"` is honored by the singular handler** (it previously
|
|
61
|
+
read/wrote the memory fallback unconditionally, silently degrading strict
|
|
62
|
+
mode to per-process caching).
|
|
63
|
+
- **ESM build can load optional peers**: bare `require()` calls became
|
|
64
|
+
esbuild's throwing `__require` fallback in ESM; now routed through
|
|
65
|
+
`createRequire` with a CWD fallback for symlinked installs (npm file
|
|
66
|
+
installs, pnpm).
|
|
67
|
+
|
|
68
|
+
### Changed
|
|
69
|
+
|
|
70
|
+
- Multi-tag `updateTags` fans out concurrently (one round trip via
|
|
71
|
+
auto-pipelining) instead of one await per tag; ioredis clients enable
|
|
72
|
+
`enableAutoPipelining`.
|
|
73
|
+
- Removed the declared-but-never-emitted `cache.stale.refresh.skipped`
|
|
74
|
+
metric event type.
|
|
75
|
+
|
|
9
76
|
## [0.2.0] - 2026-05-10
|
|
10
77
|
|
|
11
78
|
First minor bump. Three differentiators land in this release.
|
|
@@ -117,8 +184,6 @@ runtime cache key shapes.
|
|
|
117
184
|
- Provenance attestation is disabled for the local-publish flow; v0.2
|
|
118
185
|
will switch to GitHub Actions OIDC publish
|
|
119
186
|
|
|
120
|
-
|
|
121
|
-
|
|
122
187
|
### Added — `cacheHandlers` (plural) for `'use cache'`
|
|
123
188
|
|
|
124
189
|
- `createCacheComponentsHandler(opts)` factory implementing the full
|
package/README.md
CHANGED
|
@@ -3,17 +3,20 @@
|
|
|
3
3
|
[](https://www.npmjs.com/package/@leejpsd/nextjs-cache-handler)
|
|
4
4
|
[](./LICENSE)
|
|
5
5
|
|
|
6
|
-
> **`v0.
|
|
6
|
+
> **`v0.3.0`** — install with
|
|
7
7
|
> `npm install @leejpsd/nextjs-cache-handler`. Production-validated against
|
|
8
|
-
> AWS ECS Fargate with multi-instance Redis (24h live-traffic soak
|
|
9
|
-
>
|
|
8
|
+
> AWS ECS Fargate with multi-instance Redis (v0.1: 24h live-traffic soak;
|
|
9
|
+
> v0.3: fresh multi-instance verification incl. a live Redis-reboot drill
|
|
10
|
+
> with zero 5xx — see
|
|
11
|
+
> [`docs/staging-verification-2026-08-01.md`](./docs/staging-verification-2026-08-01.md)).
|
|
10
12
|
>
|
|
11
|
-
> v0.
|
|
12
|
-
>
|
|
13
|
-
>
|
|
14
|
-
>
|
|
13
|
+
> v0.3 adds: **Next.js 15 support** (ISR handler), **reconnect with
|
|
14
|
+
> exponential backoff** (no more permanent memory-only latch), **request-scoped
|
|
15
|
+
> GET deduplication**, transparent **gzip/brotli compression**, **Redis
|
|
16
|
+
> Sentinel** support, a built-in **OpenTelemetry emitter** at `/otel`, and an
|
|
17
|
+
> LRU-bounded memory fallback.
|
|
15
18
|
|
|
16
|
-
The Redis cache handler for **Next.js 16** that ships **both** `cacheHandler`
|
|
19
|
+
The Redis cache handler for **Next.js 15/16** that ships **both** `cacheHandler`
|
|
17
20
|
(ISR / Pages Router) **and** `cacheHandlers` (`'use cache'` directive,
|
|
18
21
|
`cacheComponents: true`) — the area where
|
|
19
22
|
[`@fortedigital/nextjs-cache-handler`](https://github.com/fortedigital/nextjs-cache-handler)
|
|
@@ -54,18 +57,19 @@ As of 2026-05, the leading OSS Redis handler `@fortedigital/nextjs-cache-handler
|
|
|
54
57
|
declares `peerDependencies.next: ">=16.1.5"` but the README marks the new
|
|
55
58
|
plural interface as ❌ **"Not yet supported - Help needed"**:
|
|
56
59
|
|
|
57
|
-
> 📅 **Compatibility matrix verified 2026-
|
|
60
|
+
> 📅 **Compatibility matrix re-verified 2026-07-31** (from each project's
|
|
61
|
+
> published README/registry metadata). The OSS Next.js cache
|
|
58
62
|
> handler ecosystem moves quickly — please verify
|
|
59
63
|
> [`@fortedigital`](https://github.com/fortedigital/nextjs-cache-handler#compatibility)
|
|
60
64
|
> and
|
|
61
65
|
> [`nextjs-turbo-redis-cache`](https://github.com/trieb-work/nextjs-turbo-redis-cache#features)
|
|
62
66
|
> directly before relying on this comparison.
|
|
63
67
|
|
|
64
|
-
|
|
|
68
|
+
| Feature | this (0.3.0) | @fortedigital 3.2.1 | nextjs-turbo-redis-cache 1.15 |
|
|
65
69
|
|---|---|---|---|
|
|
66
70
|
| `cacheHandlers` config (plural) | ✅ | ❌ Help needed | ✅ since 1.11 |
|
|
67
71
|
| `'use cache'` directive | ✅ | ❌ Help needed | ✅ since 1.11 |
|
|
68
|
-
| `'use cache: remote'` | ✅ | ❌ Help needed | partial |
|
|
72
|
+
| `'use cache: remote'` | ✅ default handler (dedicated multi-tier: roadmap) | ❌ Help needed | partial |
|
|
69
73
|
| `'use cache: private'` | n/a (uncustomizable) | n/a | n/a |
|
|
70
74
|
| `cacheComponents: true` | ✅ | ❌ Help needed | ✅ |
|
|
71
75
|
| Build-phase skip (`PHASE_PRODUCTION_BUILD`) | ✅ | ✅ (singular only) | ✅ |
|
|
@@ -75,13 +79,17 @@ plural interface as ❌ **"Not yet supported - Help needed"**:
|
|
|
75
79
|
| Redis Cluster | ✅ (cluster adapter, see Production checklist) | ✅ | ✅ |
|
|
76
80
|
| ioredis support | ✅ | ✅ | ✅ |
|
|
77
81
|
| In-memory fallback (TTL-aware) | ✅ | partial | ✅ L1 + Redis L2 |
|
|
78
|
-
|
|
|
82
|
+
| Next 15 support (ISR handler) | ✅ `>=15.0.0` | ✅ (legacy 2.x line) | ✅ `>=15.0.3` |
|
|
83
|
+
| Request-scoped GET dedup | ✅ | ❌ | ✅ |
|
|
84
|
+
| Built-in value compression | ✅ gzip/brotli option | example only | example only |
|
|
85
|
+
| Redis Sentinel | ✅ (local failover drill) | ❌ | ❌ |
|
|
86
|
+
| OpenTelemetry | ✅ built-in `/otel` emitter + `onMetric` hook | ❌ | ❌ |
|
|
87
|
+
| Reconnect strategy | ✅ exponential backoff | client-level | error-threshold restart |
|
|
79
88
|
| Live-traffic dogfood (24h+) | ✅ AWS ECS Fargate | not published | not published |
|
|
80
89
|
|
|
81
90
|
PR [#207](https://github.com/fortedigital/nextjs-cache-handler/pull/207) on
|
|
82
|
-
`@fortedigital`
|
|
83
|
-
|
|
84
|
-
package has from the start.
|
|
91
|
+
`@fortedigital` (their `cacheHandlers` attempt) was held up in review over
|
|
92
|
+
`PHASE_PRODUCTION_BUILD` handling — which this package has from the start.
|
|
85
93
|
|
|
86
94
|
---
|
|
87
95
|
|
|
@@ -185,6 +193,8 @@ interface CacheHandlerOptions {
|
|
|
185
193
|
singleFlightLockTtlSec?: number; // default: 10
|
|
186
194
|
isBuildPhase?: () => boolean; // override PHASE_PRODUCTION_BUILD detection
|
|
187
195
|
hashTag?: boolean; // default: false (set true on Redis Cluster)
|
|
196
|
+
memoryMaxEntries?: number; // default: 1000 — LRU cap for the in-memory fallback
|
|
197
|
+
compression?: "gzip" | "brotli"; // default: off — transparent value compression (node:zlib)
|
|
188
198
|
onMetric?: (event: MetricEvent) => void;
|
|
189
199
|
logger?: Logger;
|
|
190
200
|
}
|
|
@@ -192,10 +202,12 @@ interface CacheHandlerOptions {
|
|
|
192
202
|
type RedisClientConfig =
|
|
193
203
|
| { type: "redis"; url: string; password?: string; tls?: boolean; connectTimeout?: number }
|
|
194
204
|
| { type: "ioredis"; url: string; password?: string; tls?: boolean; connectTimeout?: number }
|
|
195
|
-
| { type: "cluster"; nodes: { host: string; port: number }[]; password?: string; tls?: boolean }
|
|
205
|
+
| { type: "cluster"; nodes: { host: string; port: number }[]; password?: string; tls?: boolean }
|
|
206
|
+
| { type: "sentinel"; sentinels: { host: string; port: number }[]; name: string;
|
|
207
|
+
password?: string; sentinelPassword?: string; tls?: boolean; connectTimeout?: number };
|
|
196
208
|
```
|
|
197
209
|
|
|
198
|
-
Full reference: [`docs/api.md`](./docs/api.md)
|
|
210
|
+
Full reference: [`docs/api.md`](./docs/api.md).
|
|
199
211
|
|
|
200
212
|
---
|
|
201
213
|
|
|
@@ -234,8 +246,9 @@ Full reference: [`docs/api.md`](./docs/api.md) (auto-generated).
|
|
|
234
246
|
| **Self-hosted Redis 7+** | `{ type: "redis", url }` or `{ type: "ioredis", url }` | ✅ AWS ElastiCache 24h soak |
|
|
235
247
|
| **Redis Cluster** | `{ type: "cluster", nodes }` + `hashTag: true` | unit-tested, not yet load-tested at scale |
|
|
236
248
|
| **Upstash Redis** | `{ type: "redis", url: "rediss://..." }` (TLS auto-detected) | not yet validated, expected to work via the standard Redis protocol |
|
|
237
|
-
| **AWS ElastiCache (replication group)** | `{ type: "redis", url: "rediss://..." }` | ✅ reference deployment |
|
|
238
|
-
| **
|
|
249
|
+
| **AWS ElastiCache (replication group)** | `{ type: "redis", url: "rediss://..." }` | ✅ reference deployment (re-verified 2026-08-01, Seoul) |
|
|
250
|
+
| **Redis Sentinel** | `{ type: "sentinel", sentinels, name }` | ✅ local master/replica failover drill |
|
|
251
|
+
| **Vercel KV** | not yet supported — dedicated adapter on the roadmap | — |
|
|
239
252
|
| **DragonflyDB / KeyDB** | Redis-protocol compatible — `{ type: "redis", url }` should work | not validated |
|
|
240
253
|
|
|
241
254
|
---
|
|
@@ -337,10 +350,16 @@ eventual implementation should converge on the same behavior.
|
|
|
337
350
|
|
|
338
351
|
## Compatibility
|
|
339
352
|
|
|
340
|
-
- **Next.js**: `>=
|
|
353
|
+
- **Next.js**: `>=15.0.0 <17`
|
|
354
|
+
- `cacheHandler` (singular, ISR): Next **15 and 16** — the handler accepts
|
|
355
|
+
both ctx shapes (Next 15's `ctx.revalidate` / `kindHint`, Next 16's
|
|
356
|
+
`ctx.cacheControl` / `kind`)
|
|
357
|
+
- `cacheHandlers` (plural, `'use cache'`): Next **>=16.1.5** only — the
|
|
358
|
+
interface does not exist before 16
|
|
341
359
|
- **Node.js**: `>=20`
|
|
342
360
|
- **redis**: `>=5.0.0` (peer, optional)
|
|
343
|
-
- **ioredis**: `>=5.0.0` (peer, optional)
|
|
361
|
+
- **ioredis**: `>=5.0.0` (peer, optional) — also powers `type: "cluster"` and
|
|
362
|
+
`type: "sentinel"` (Sentinel master discovery with automatic failover)
|
|
344
363
|
|
|
345
364
|
ESM and CJS dual-published, full TypeScript types, validated via
|
|
346
365
|
[`arethetypeswrong`](https://arethetypeswrong.github.io) and
|
|
@@ -357,10 +376,13 @@ ESM and CJS dual-published, full TypeScript types, validated via
|
|
|
357
376
|
metrics, OpenTelemetry reference adapter, integration tests against
|
|
358
377
|
real Redis 7 (21 scenarios over `redis@5` + `ioredis`), GitHub Actions
|
|
359
378
|
OIDC publish path with provenance attestation ✅
|
|
360
|
-
- **v0.3.0** —
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
379
|
+
- **v0.3.0** *(2026-08)* — Next.js 15 ISR support, reconnect backoff (no
|
|
380
|
+
permanent connect-failure latch), request-scoped GET deduplication,
|
|
381
|
+
gzip/brotli compression, Redis Sentinel, built-in OpenTelemetry emitter
|
|
382
|
+
(`/otel`), LRU-bounded memory fallback, ESM peer-loading fixes ✅
|
|
383
|
+
- **v0.4.0** — Build-phase cache seeding (prepopulate prebuilt pages),
|
|
384
|
+
pub/sub-based tag propagation, Redis Cluster e2e validation, Vercel KV /
|
|
385
|
+
Upstash adapter, `'use cache: remote'` multi-tier setup
|
|
364
386
|
|
|
365
387
|
---
|
|
366
388
|
|