@trieb.work/nextjs-turbo-redis-cache 1.10.0-beta.14 → 1.11.0-beta.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.
Files changed (55) hide show
  1. package/.github/workflows/ci.yml +28 -12
  2. package/CHANGELOG.md +6 -94
  3. package/README.md +94 -0
  4. package/dist/index.d.mts +22 -1
  5. package/dist/index.d.ts +22 -1
  6. package/dist/index.js +333 -15
  7. package/dist/index.js.map +1 -1
  8. package/dist/index.mjs +330 -14
  9. package/dist/index.mjs.map +1 -1
  10. package/package.json +3 -2
  11. package/playwright.config.ts +8 -1
  12. package/src/CacheComponentsHandler.ts +471 -0
  13. package/src/RedisStringsHandler.ts +11 -11
  14. package/src/index.test.ts +1 -1
  15. package/src/index.ts +5 -0
  16. package/test/cache-components/cache-components.integration.spec.ts +188 -0
  17. package/test/integration/next-app-15-4-7/next.config.js +3 -0
  18. package/test/integration/next-app-15-4-7/pnpm-lock.yaml +1 -1
  19. package/test/integration/next-app-16-0-3/next.config.ts +3 -0
  20. package/test/integration/next-app-16-1-1-cache-components/README.md +36 -0
  21. package/test/integration/next-app-16-1-1-cache-components/cache-handler.js +3 -0
  22. package/test/integration/next-app-16-1-1-cache-components/eslint.config.mjs +18 -0
  23. package/test/integration/next-app-16-1-1-cache-components/next.config.ts +13 -0
  24. package/test/integration/next-app-16-1-1-cache-components/package.json +28 -0
  25. package/test/integration/next-app-16-1-1-cache-components/pnpm-lock.yaml +4128 -0
  26. package/test/integration/next-app-16-1-1-cache-components/postcss.config.mjs +7 -0
  27. package/test/integration/next-app-16-1-1-cache-components/public/file.svg +1 -0
  28. package/test/integration/next-app-16-1-1-cache-components/public/globe.svg +1 -0
  29. package/test/integration/next-app-16-1-1-cache-components/public/next.svg +1 -0
  30. package/test/integration/next-app-16-1-1-cache-components/public/public/file.svg +1 -0
  31. package/test/integration/next-app-16-1-1-cache-components/public/public/globe.svg +1 -0
  32. package/test/integration/next-app-16-1-1-cache-components/public/public/next.svg +1 -0
  33. package/test/integration/next-app-16-1-1-cache-components/public/public/vercel.svg +1 -0
  34. package/test/integration/next-app-16-1-1-cache-components/public/public/window.svg +1 -0
  35. package/test/integration/next-app-16-1-1-cache-components/public/vercel.svg +1 -0
  36. package/test/integration/next-app-16-1-1-cache-components/public/window.svg +1 -0
  37. package/test/integration/next-app-16-1-1-cache-components/src/app/api/cached-static-fetch/route.ts +19 -0
  38. package/test/integration/next-app-16-1-1-cache-components/src/app/api/cached-with-tag/route.ts +21 -0
  39. package/test/integration/next-app-16-1-1-cache-components/src/app/api/revalidate-tag/route.ts +19 -0
  40. package/test/integration/next-app-16-1-1-cache-components/src/app/api/revalidated-fetch/route.ts +19 -0
  41. package/test/integration/next-app-16-1-1-cache-components/src/app/cache-lab/cachelife-short/page.tsx +110 -0
  42. package/test/integration/next-app-16-1-1-cache-components/src/app/cache-lab/page.tsx +90 -0
  43. package/test/integration/next-app-16-1-1-cache-components/src/app/cache-lab/runtime-data-suspense/page.tsx +127 -0
  44. package/test/integration/next-app-16-1-1-cache-components/src/app/cache-lab/stale-while-revalidate/page.tsx +130 -0
  45. package/test/integration/next-app-16-1-1-cache-components/src/app/cache-lab/tag-invalidation/page.tsx +127 -0
  46. package/test/integration/next-app-16-1-1-cache-components/src/app/cache-lab/use-cache-nondeterministic/page.tsx +110 -0
  47. package/test/integration/next-app-16-1-1-cache-components/src/app/favicon.ico +0 -0
  48. package/test/integration/next-app-16-1-1-cache-components/src/app/globals.css +26 -0
  49. package/test/integration/next-app-16-1-1-cache-components/src/app/layout.tsx +57 -0
  50. package/test/integration/next-app-16-1-1-cache-components/src/app/page.tsx +755 -0
  51. package/test/integration/next-app-16-1-1-cache-components/src/app/revalidation-interface.tsx +267 -0
  52. package/test/integration/next-app-16-1-1-cache-components/src/app/update-tag-test/page.tsx +22 -0
  53. package/test/integration/next-app-16-1-1-cache-components/tsconfig.json +34 -0
  54. package/tests/cache-lab.spec.ts +157 -0
  55. package/vitest.cache-components.config.ts +16 -0
@@ -25,11 +25,15 @@ jobs:
25
25
  pull-requests: write # Grant write access to pull request comments
26
26
  strategy:
27
27
  matrix:
28
- next-test-app:
29
- - next-app-15-0-3
30
- - next-app-15-3-2
31
- - next-app-15-4-7
32
- - next-app-16-0-3
28
+ include:
29
+ - next-test-app: next-app-15-0-3
30
+ run-cache-components: false
31
+ - next-test-app: next-app-15-3-2
32
+ run-cache-components: false
33
+ - next-test-app: next-app-15-4-7
34
+ run-cache-components: false
35
+ - next-test-app: next-app-16-0-3
36
+ run-cache-components: true
33
37
 
34
38
 
35
39
  steps:
@@ -42,7 +46,7 @@ jobs:
42
46
  - name: Setup Node.js
43
47
  uses: actions/setup-node@v6
44
48
  with:
45
- node-version: '20'
49
+ node-version: '22'
46
50
  cache: 'pnpm'
47
51
 
48
52
  - name: Install dependencies
@@ -78,18 +82,30 @@ jobs:
78
82
  SKIP_BUILD: true
79
83
  NEXT_TEST_APP: ${{ matrix.next-test-app }}
80
84
 
81
- - name: Install Playwright browsers (Next 16 only)
82
- if: matrix.next-test-app == 'next-app-16-0-3'
85
+ - name: Install Cache Components Integration Test Project
86
+ if: matrix.run-cache-components
87
+ run: cd test/integration/next-app-16-1-1-cache-components && pnpm install
88
+
89
+ - name: Build Cache Components Integration Test Project
90
+ if: matrix.run-cache-components
91
+ run: cd test/integration/next-app-16-1-1-cache-components && pnpm build
92
+
93
+ - name: Run Cache Components integration tests
94
+ if: matrix.run-cache-components
95
+ run: pnpm test:cache-components
96
+
97
+ - name: Install Playwright browsers
98
+ if: matrix.run-cache-components
83
99
  run: pnpm exec playwright install --with-deps
84
100
 
85
- - name: Run Playwright E2E tests (Next 16 only)
86
- if: matrix.next-test-app == 'next-app-16-0-3'
101
+ - name: Run Playwright E2E tests
102
+ if: matrix.run-cache-components
87
103
  run: pnpm test:e2e
88
104
  env:
89
- PLAYWRIGHT_BASE_URL: http://localhost:3055
105
+ PLAYWRIGHT_BASE_URL: http://localhost:3101
90
106
 
91
107
  - name: Code Coverage Comments
92
- if: github.event_name == 'pull_request'
108
+ if: github.event_name == 'pull_request' && github.event.pull_request.head.repo.full_name == github.repository
93
109
  uses: kcjpop/coverage-comments@v2.2
94
110
  with:
95
111
  github-token: ${{ secrets.GITHUB_TOKEN }}
package/CHANGELOG.md CHANGED
@@ -1,107 +1,19 @@
1
- # [1.10.0-beta.14](https://github.com/trieb-work/nextjs-turbo-redis-cache/compare/v1.10.0-beta.13...v1.10.0-beta.14) (2025-12-27)
1
+ # [1.11.0-beta.1](https://github.com/trieb-work/nextjs-turbo-redis-cache/compare/v1.10.0...v1.11.0-beta.1) (2025-12-30)
2
2
 
3
3
 
4
- ### Bug Fixes
5
-
6
- * remove extensive debugging and simplify npm publish step in release workflow ([d3b7aa9](https://github.com/trieb-work/nextjs-turbo-redis-cache/commit/d3b7aa9fa13d9ff65e2b34e1e49433507cfb9cb2))
7
-
8
- # [1.10.0-beta.13](https://github.com/trieb-work/nextjs-turbo-redis-cache/compare/v1.10.0-beta.12...v1.10.0-beta.13) (2025-12-27)
9
-
10
-
11
- ### Bug Fixes
12
-
13
- * add comprehensive debugging and .npmrc configuration for npm trusted publishing ([8d4fabb](https://github.com/trieb-work/nextjs-turbo-redis-cache/commit/8d4fabb02062a7a771693277909555671e810835))
14
-
15
- # [1.10.0-beta.12](https://github.com/trieb-work/nextjs-turbo-redis-cache/compare/v1.10.0-beta.11...v1.10.0-beta.12) (2025-12-27)
16
-
17
-
18
- ### Bug Fixes
19
-
20
- * implement OIDC token exchange for npm trusted publishing in release workflow ([3b3cea1](https://github.com/trieb-work/nextjs-turbo-redis-cache/commit/3b3cea152dfb183e918dac1b34c6a8277c300474))
21
-
22
- # [1.10.0-beta.11](https://github.com/trieb-work/nextjs-turbo-redis-cache/compare/v1.10.0-beta.10...v1.10.0-beta.11) (2025-12-27)
23
-
24
-
25
- ### Bug Fixes
26
-
27
- * add diagnostics step to debug OIDC and npm configuration in release workflow ([6a7f3cf](https://github.com/trieb-work/nextjs-turbo-redis-cache/commit/6a7f3cf7cda23d57acb34d3bb4c4dd6ab7103ca7))
28
-
29
- # [1.10.0-beta.10](https://github.com/trieb-work/nextjs-turbo-redis-cache/compare/v1.10.0-beta.9...v1.10.0-beta.10) (2025-12-27)
30
-
31
-
32
- ### Bug Fixes
33
-
34
- * add provenance, public access, and verbose logging to npm publish command ([2fccf3d](https://github.com/trieb-work/nextjs-turbo-redis-cache/commit/2fccf3d12c899e5aee38ea5d7c0cdce22dd83ce4))
35
-
36
- # [1.10.0-beta.9](https://github.com/trieb-work/nextjs-turbo-redis-cache/compare/v1.10.0-beta.8...v1.10.0-beta.9) (2025-12-27)
37
-
38
-
39
- ### Bug Fixes
40
-
41
- * add git+ prefix to repository URL in package.json ([70f94df](https://github.com/trieb-work/nextjs-turbo-redis-cache/commit/70f94dff5059808eb4a2376950f3bb9fecb4511e))
42
-
43
- # [1.10.0-beta.8](https://github.com/trieb-work/nextjs-turbo-redis-cache/compare/v1.10.0-beta.7...v1.10.0-beta.8) (2025-12-27)
44
-
45
-
46
- ### Bug Fixes
47
-
48
- * disable semantic-release npm publishing and add manual npm publish step with trusted publishing ([4cbf99d](https://github.com/trieb-work/nextjs-turbo-redis-cache/commit/4cbf99de560a6a466b5d10f945bd9640356ef444))
49
-
50
- # [1.10.0-beta.7](https://github.com/trieb-work/nextjs-turbo-redis-cache/compare/v1.10.0-beta.6...v1.10.0-beta.7) (2025-12-26)
51
-
52
-
53
- ### Bug Fixes
54
-
55
- * remove empty auth token environment variables from release workflow ([8d4e87b](https://github.com/trieb-work/nextjs-turbo-redis-cache/commit/8d4e87b301842842cd3d0c0a8cb8401dbf100fa9))
56
-
57
- # [1.10.0-beta.6](https://github.com/trieb-work/nextjs-turbo-redis-cache/compare/v1.10.0-beta.5...v1.10.0-beta.6) (2025-12-26)
58
-
59
-
60
- ### Bug Fixes
61
-
62
- * upgrade semantic-release and related dependencies to v25 ([63fd812](https://github.com/trieb-work/nextjs-turbo-redis-cache/commit/63fd812bc0815aa5155619faf9b36b9287daac21))
63
- * use pnpm exec instead of pnpx for semantic-release command ([ca310c0](https://github.com/trieb-work/nextjs-turbo-redis-cache/commit/ca310c0e1b4150052787eba1709152d606d2d76d))
64
-
65
- # [1.10.0-beta.5](https://github.com/trieb-work/nextjs-turbo-redis-cache/compare/v1.10.0-beta.4...v1.10.0-beta.5) (2025-12-26)
66
-
67
-
68
- ### Bug Fixes
69
-
70
- * remove registry-url and clear auth tokens in release workflow ([b0d9edb](https://github.com/trieb-work/nextjs-turbo-redis-cache/commit/b0d9edb4e8efa37500a4dfe4054a24f55582e60e))
71
-
72
- # [1.10.0-beta.4](https://github.com/trieb-work/nextjs-turbo-redis-cache/compare/v1.10.0-beta.3...v1.10.0-beta.4) (2025-12-26)
73
-
74
-
75
- ### Bug Fixes
76
-
77
- * trigger beta release ([724ecbb](https://github.com/trieb-work/nextjs-turbo-redis-cache/commit/724ecbb6d76697818a2c6a863c98e144eed049d2))
78
-
79
- # [1.10.0-beta.3](https://github.com/trieb-work/nextjs-turbo-redis-cache/compare/v1.10.0-beta.2...v1.10.0-beta.3) (2025-12-26)
80
-
81
-
82
- ### Bug Fixes
83
-
84
- * configure npm provenance in package.json publishConfig ([83a3017](https://github.com/trieb-work/nextjs-turbo-redis-cache/commit/83a301797396e98b739db199bfb3e97ee1c8565e))
85
-
86
- # [1.10.0-beta.2](https://github.com/trieb-work/nextjs-turbo-redis-cache/compare/v1.10.0-beta.1...v1.10.0-beta.2) (2025-12-26)
87
-
88
-
89
- ### Bug Fixes
4
+ ### Features
90
5
 
91
- * trigger beta release ([432b58f](https://github.com/trieb-work/nextjs-turbo-redis-cache/commit/432b58f661db20e5a8302d54679b16cc33a6dfb6))
6
+ * add Next.js 16.0.3 integration test environment and build artifacts for cache components ([f2b3088](https://github.com/trieb-work/nextjs-turbo-redis-cache/commit/f2b3088c5845865cb69e5ee691cd09ede5735119))
7
+ * add Next.js 16.0.3 integration test environment and build artifacts for cache components ([01fb22a](https://github.com/trieb-work/nextjs-turbo-redis-cache/commit/01fb22a9ae0fbbb6fba44bb225ab46fdcc009a85))
8
+ * cache components lab + Next.js 16.1.x support ([be2e9b3](https://github.com/trieb-work/nextjs-turbo-redis-cache/commit/be2e9b3b7af441df112fc83483994877a4415443))
92
9
 
93
- # [1.10.0-beta.1](https://github.com/trieb-work/nextjs-turbo-redis-cache/compare/v1.9.1...v1.10.0-beta.1) (2025-12-26)
10
+ # [1.10.0](https://github.com/trieb-work/nextjs-turbo-redis-cache/compare/v1.9.1...v1.10.0) (2025-12-27)
94
11
 
95
12
 
96
13
  ### Bug Fixes
97
14
 
98
- * avoid overlapping redis reconnects ([4da291f](https://github.com/trieb-work/nextjs-turbo-redis-cache/commit/4da291f1a62ef8ffd9a8528640ee57b1367d0e25))
99
15
  * cleanup ([c948fdf](https://github.com/trieb-work/nextjs-turbo-redis-cache/commit/c948fdfe0e6b5f70edc985b3cdda9cf2f002633a))
100
16
  * folder structure ([93356fd](https://github.com/trieb-work/nextjs-turbo-redis-cache/commit/93356fd567c0f05fad92d3443da77216fd2cc28d))
101
- * just testing around ([09bd26d](https://github.com/trieb-work/nextjs-turbo-redis-cache/commit/09bd26dc7b328945f11818a11446b3e5dd86c943))
102
- * remove not needed attributes ([6c11e0d](https://github.com/trieb-work/nextjs-turbo-redis-cache/commit/6c11e0d574e6ae8d98c60f71ea70070415de9de7))
103
- * testing with npm ([fa7ecb0](https://github.com/trieb-work/nextjs-turbo-redis-cache/commit/fa7ecb0283c2611918a3f780bc0c87cf2b28d5db))
104
- * trigger beta release ([62ea418](https://github.com/trieb-work/nextjs-turbo-redis-cache/commit/62ea4182b65fac53f23a93418b9f4650ab717b60))
105
17
 
106
18
 
107
19
  ### Features
package/README.md CHANGED
@@ -214,6 +214,12 @@ To run all tests you can use the following command:
214
214
  pnpm build && pnpm test
215
215
  ```
216
216
 
217
+ Folder layout / runners:
218
+
219
+ - **Vitest** (unit + integration) lives in `src/**/*.test.ts(x)` and `test/**`.
220
+ - **Playwright** (E2E) lives in `tests/**` (see `playwright.config.ts`).
221
+ - `test/browser/**` contains Vitest tests that hit a running Next.js app over HTTP. Despite the folder name, this is not Playwright and does not use Vitest browser mode.
222
+
217
223
  ### Unit tests
218
224
 
219
225
  To run unit tests you can use the following command:
@@ -230,6 +236,14 @@ To run integration tests you can use the following command:
230
236
  pnpm build && pnpm test:integration
231
237
  ```
232
238
 
239
+ ### E2E tests (Playwright)
240
+
241
+ To run Playwright tests (`tests/**`) you can use:
242
+
243
+ ```bash
244
+ pnpm test:e2e
245
+ ```
246
+
233
247
  The integration tests will start a Next.js server and test the caching handler. You can modify testing behavior by setting the following environment variables:
234
248
 
235
249
  - SKIP_BUILD: If set to true, the integration tests will not build the Next.js app. Therefore the nextjs app needs to be built before running the tests. Or you execute the test once without skip build and the re-execute `pnpm test:integration` with skip build set to true.
@@ -238,6 +252,86 @@ The integration tests will start a Next.js server and test the caching handler.
238
252
 
239
253
  Integration tests may have dependencies between test cases, so individual test failures should be evaluated in the context of the full test suite rather than in isolation.
240
254
 
255
+ ## Cache Components handler (Next.js 16+)
256
+
257
+ This package can be used as a Cache Components handler (Node.js runtime) for Next.js apps that enable Cache Components.
258
+
259
+ ### Enable Cache Components + cache handler
260
+
261
+ Install the package in your Next.js app:
262
+
263
+ ```bash
264
+ pnpm add @trieb.work/nextjs-turbo-redis-cache redis
265
+ ```
266
+
267
+ In your Next.js app, enable Cache Components and point `cacheHandlers.default` to a module that exports the handler instance:
268
+
269
+ ```ts
270
+ // next.config.ts
271
+ import type { NextConfig } from 'next';
272
+
273
+ const nextConfig: NextConfig = {
274
+ cacheComponents: true,
275
+ cacheHandlers: {
276
+ default: require.resolve('./cache-handler.js'),
277
+ },
278
+ };
279
+
280
+ export default nextConfig;
281
+ ```
282
+
283
+ ```js
284
+ // cache-handler.js
285
+ const { redisCacheHandler } = require('@trieb.work/nextjs-turbo-redis-cache');
286
+
287
+ module.exports = redisCacheHandler;
288
+ ```
289
+
290
+ If you prefer ESM:
291
+
292
+ ```js
293
+ // cache-handler.js
294
+ import { redisCacheHandler } from '@trieb.work/nextjs-turbo-redis-cache';
295
+
296
+ export default redisCacheHandler;
297
+ ```
298
+
299
+ ### Required environment variables
300
+
301
+ - `REDIS_URL` (recommended): e.g. `redis://localhost:6379`
302
+
303
+ Optional:
304
+
305
+ - `VERCEL_URL`: used as a key prefix for multi-tenant isolation (also useful in tests). If unset, a default prefix is used.
306
+ - `REDIS_COMMAND_TIMEOUT_MS`: timeout (ms) for Redis commands used by the handler.
307
+
308
+ ### Local manual testing (Cache Lab)
309
+
310
+ This repo includes a dedicated Next.js Cache Components integration app with real pages for manual testing.
311
+
312
+ 1. Start Redis locally.
313
+ 1. Install + start the Cache Components test app:
314
+
315
+ ```bash
316
+ pnpm -C test/integration/next-app-16-1-1-cache-components install
317
+ pnpm -C test/integration/next-app-16-1-1-cache-components dev
318
+ ```
319
+
320
+ Then open the Cache Lab pages:
321
+
322
+ - `/cache-lab`
323
+ - `/cache-lab/use-cache-nondeterministic`
324
+ - `/cache-lab/cachelife-short`
325
+ - `/cache-lab/tag-invalidation`
326
+ - `/cache-lab/stale-while-revalidate`
327
+ - `/cache-lab/runtime-data-suspense`
328
+
329
+ To run the Playwright E2E tests against a running dev server:
330
+
331
+ ```bash
332
+ PLAYWRIGHT_BASE_URL=http://localhost:3101 pnpm test:e2e
333
+ ```
334
+
241
335
  ## Some words on nextjs caching internals
242
336
 
243
337
  Nextjs will use different caching objects for different pages and api routes. Currently supported are kind: APP_ROUTE and APP_PAGE.
package/dist/index.d.mts CHANGED
@@ -149,4 +149,25 @@ declare class CachedHandler {
149
149
  resetRequestCache(...args: Parameters<RedisStringsHandler['resetRequestCache']>): ReturnType<RedisStringsHandler['resetRequestCache']>;
150
150
  }
151
151
 
152
- export { RedisStringsHandler, CachedHandler as default };
152
+ interface CacheComponentsEntry {
153
+ value: ReadableStream<Uint8Array>;
154
+ tags: string[];
155
+ stale: number;
156
+ timestamp: number;
157
+ expire: number;
158
+ revalidate: number;
159
+ }
160
+ interface CacheComponentsHandler {
161
+ get(cacheKey: string, softTags: string[]): Promise<CacheComponentsEntry | undefined>;
162
+ set(cacheKey: string, pendingEntry: Promise<CacheComponentsEntry>): Promise<void>;
163
+ refreshTags(): Promise<void>;
164
+ getExpiration(tags: string[]): Promise<number>;
165
+ updateTags(tags: string[], durations?: {
166
+ expire?: number;
167
+ }): Promise<void>;
168
+ }
169
+ type CreateCacheComponentsHandlerOptions = CreateRedisStringsHandlerOptions;
170
+ declare function getRedisCacheComponentsHandler(options?: CreateCacheComponentsHandlerOptions): CacheComponentsHandler;
171
+ declare const redisCacheHandler: CacheComponentsHandler;
172
+
173
+ export { RedisStringsHandler, CachedHandler as default, getRedisCacheComponentsHandler, redisCacheHandler };
package/dist/index.d.ts CHANGED
@@ -149,4 +149,25 @@ declare class CachedHandler {
149
149
  resetRequestCache(...args: Parameters<RedisStringsHandler['resetRequestCache']>): ReturnType<RedisStringsHandler['resetRequestCache']>;
150
150
  }
151
151
 
152
- export { RedisStringsHandler, CachedHandler as default };
152
+ interface CacheComponentsEntry {
153
+ value: ReadableStream<Uint8Array>;
154
+ tags: string[];
155
+ stale: number;
156
+ timestamp: number;
157
+ expire: number;
158
+ revalidate: number;
159
+ }
160
+ interface CacheComponentsHandler {
161
+ get(cacheKey: string, softTags: string[]): Promise<CacheComponentsEntry | undefined>;
162
+ set(cacheKey: string, pendingEntry: Promise<CacheComponentsEntry>): Promise<void>;
163
+ refreshTags(): Promise<void>;
164
+ getExpiration(tags: string[]): Promise<number>;
165
+ updateTags(tags: string[], durations?: {
166
+ expire?: number;
167
+ }): Promise<void>;
168
+ }
169
+ type CreateCacheComponentsHandlerOptions = CreateRedisStringsHandlerOptions;
170
+ declare function getRedisCacheComponentsHandler(options?: CreateCacheComponentsHandlerOptions): CacheComponentsHandler;
171
+ declare const redisCacheHandler: CacheComponentsHandler;
172
+
173
+ export { RedisStringsHandler, CachedHandler as default, getRedisCacheComponentsHandler, redisCacheHandler };