@trieb.work/nextjs-turbo-redis-cache 1.13.0 → 1.14.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 (75) hide show
  1. package/.github/workflows/ci.yml +51 -4
  2. package/CHANGELOG.md +14 -0
  3. package/README.md +17 -4
  4. package/dist/index.js +15 -4
  5. package/dist/index.js.map +1 -1
  6. package/dist/index.mjs +15 -4
  7. package/dist/index.mjs.map +1 -1
  8. package/package.json +5 -3
  9. package/playwright.config.ts +1 -1
  10. package/src/RedisStringsHandler.ts +17 -4
  11. package/src/index.test.ts +86 -1
  12. package/test/cache-components/cache-components.integration.spec.ts +1 -1
  13. package/test/integration/next-app-15-0-3/pnpm-lock.yaml +32 -1
  14. package/test/integration/next-app-15-3-2/pnpm-lock.yaml +33 -1
  15. package/test/integration/next-app-15-4-7/pnpm-lock.yaml +36 -1
  16. package/test/integration/next-app-16-0-3/pnpm-lock.yaml +37 -1
  17. package/test/integration/{next-app-16-1-1 → next-app-16-2-3}/package.json +3 -3
  18. package/test/integration/{next-app-16-1-1 → next-app-16-2-3}/pnpm-lock.yaml +98 -55
  19. package/test/integration/{next-app-16-1-1-cache-components → next-app-16-2-3-cache-components}/package.json +3 -3
  20. package/test/integration/{next-app-16-1-1-cache-components → next-app-16-2-3-cache-components}/pnpm-lock.yaml +98 -55
  21. package/test/integration/nextjs-cache-handler.integration.test.ts +1 -0
  22. /package/test/integration/{next-app-16-1-1 → next-app-16-2-3}/README.md +0 -0
  23. /package/test/integration/{next-app-16-1-1 → next-app-16-2-3}/eslint.config.mjs +0 -0
  24. /package/test/integration/{next-app-16-1-1 → next-app-16-2-3}/next.config.ts +0 -0
  25. /package/test/integration/{next-app-16-1-1 → next-app-16-2-3}/postcss.config.mjs +0 -0
  26. /package/test/integration/{next-app-16-1-1 → next-app-16-2-3}/src/app/api/cached-static-fetch/route.ts +0 -0
  27. /package/test/integration/{next-app-16-1-1 → next-app-16-2-3}/src/app/api/nested-fetch-in-api-route/revalidated-fetch/route.ts +0 -0
  28. /package/test/integration/{next-app-16-1-1 → next-app-16-2-3}/src/app/api/revalidatePath/route.ts +0 -0
  29. /package/test/integration/{next-app-16-1-1 → next-app-16-2-3}/src/app/api/revalidateTag/route.ts +0 -0
  30. /package/test/integration/{next-app-16-1-1 → next-app-16-2-3}/src/app/api/revalidated-fetch/route.ts +0 -0
  31. /package/test/integration/{next-app-16-1-1 → next-app-16-2-3}/src/app/api/uncached-fetch/route.ts +0 -0
  32. /package/test/integration/{next-app-16-1-1 → next-app-16-2-3}/src/app/favicon.ico +0 -0
  33. /package/test/integration/{next-app-16-1-1 → next-app-16-2-3}/src/app/globals.css +0 -0
  34. /package/test/integration/{next-app-16-1-1 → next-app-16-2-3}/src/app/layout.tsx +0 -0
  35. /package/test/integration/{next-app-16-1-1 → next-app-16-2-3}/src/app/page.tsx +0 -0
  36. /package/test/integration/{next-app-16-1-1 → next-app-16-2-3}/src/app/pages/cached-static-fetch/default--force-dynamic-page/page.tsx +0 -0
  37. /package/test/integration/{next-app-16-1-1 → next-app-16-2-3}/src/app/pages/cached-static-fetch/revalidate15--default-page/page.tsx +0 -0
  38. /package/test/integration/{next-app-16-1-1 → next-app-16-2-3}/src/app/pages/cached-static-fetch/revalidate15--force-dynamic-page/page.tsx +0 -0
  39. /package/test/integration/{next-app-16-1-1 → next-app-16-2-3}/src/app/pages/no-fetch/default-page/page.tsx +0 -0
  40. /package/test/integration/{next-app-16-1-1 → next-app-16-2-3}/src/app/pages/revalidated-fetch/default--force-dynamic-page/page.tsx +0 -0
  41. /package/test/integration/{next-app-16-1-1 → next-app-16-2-3}/src/app/pages/revalidated-fetch/revalidate15--default-page/page.tsx +0 -0
  42. /package/test/integration/{next-app-16-1-1 → next-app-16-2-3}/src/app/pages/revalidated-fetch/revalidate15--force-dynamic-page/page.tsx +0 -0
  43. /package/test/integration/{next-app-16-1-1 → next-app-16-2-3}/src/app/pages/uncached-fetch/default--force-dynamic-page/page.tsx +0 -0
  44. /package/test/integration/{next-app-16-1-1 → next-app-16-2-3}/src/app/pages/uncached-fetch/revalidate15--default-page/page.tsx +0 -0
  45. /package/test/integration/{next-app-16-1-1 → next-app-16-2-3}/src/app/pages/uncached-fetch/revalidate15--force-dynamic-page/page.tsx +0 -0
  46. /package/test/integration/{next-app-16-1-1 → next-app-16-2-3}/src/app/revalidation-interface.tsx +0 -0
  47. /package/test/integration/{next-app-16-1-1 → next-app-16-2-3}/src/app/update-tag-test/page.tsx +0 -0
  48. /package/test/integration/{next-app-16-1-1 → next-app-16-2-3}/tsconfig.json +0 -0
  49. /package/test/integration/{next-app-16-1-1-cache-components → next-app-16-2-3-cache-components}/README.md +0 -0
  50. /package/test/integration/{next-app-16-1-1-cache-components → next-app-16-2-3-cache-components}/cache-handler.js +0 -0
  51. /package/test/integration/{next-app-16-1-1-cache-components → next-app-16-2-3-cache-components}/eslint.config.mjs +0 -0
  52. /package/test/integration/{next-app-16-1-1-cache-components → next-app-16-2-3-cache-components}/next.config.ts +0 -0
  53. /package/test/integration/{next-app-16-1-1-cache-components → next-app-16-2-3-cache-components}/postcss.config.mjs +0 -0
  54. /package/test/integration/{next-app-16-1-1-cache-components → next-app-16-2-3-cache-components}/public/file.svg +0 -0
  55. /package/test/integration/{next-app-16-1-1-cache-components → next-app-16-2-3-cache-components}/public/globe.svg +0 -0
  56. /package/test/integration/{next-app-16-1-1-cache-components → next-app-16-2-3-cache-components}/public/next.svg +0 -0
  57. /package/test/integration/{next-app-16-1-1-cache-components → next-app-16-2-3-cache-components}/public/vercel.svg +0 -0
  58. /package/test/integration/{next-app-16-1-1-cache-components → next-app-16-2-3-cache-components}/public/window.svg +0 -0
  59. /package/test/integration/{next-app-16-1-1-cache-components → next-app-16-2-3-cache-components}/src/app/api/cached-static-fetch/route.ts +0 -0
  60. /package/test/integration/{next-app-16-1-1-cache-components → next-app-16-2-3-cache-components}/src/app/api/cached-with-tag/route.ts +0 -0
  61. /package/test/integration/{next-app-16-1-1-cache-components → next-app-16-2-3-cache-components}/src/app/api/revalidate-tag/route.ts +0 -0
  62. /package/test/integration/{next-app-16-1-1-cache-components → next-app-16-2-3-cache-components}/src/app/api/revalidated-fetch/route.ts +0 -0
  63. /package/test/integration/{next-app-16-1-1-cache-components → next-app-16-2-3-cache-components}/src/app/cache-lab/cachelife-short/page.tsx +0 -0
  64. /package/test/integration/{next-app-16-1-1-cache-components → next-app-16-2-3-cache-components}/src/app/cache-lab/page.tsx +0 -0
  65. /package/test/integration/{next-app-16-1-1-cache-components → next-app-16-2-3-cache-components}/src/app/cache-lab/runtime-data-suspense/page.tsx +0 -0
  66. /package/test/integration/{next-app-16-1-1-cache-components → next-app-16-2-3-cache-components}/src/app/cache-lab/stale-while-revalidate/page.tsx +0 -0
  67. /package/test/integration/{next-app-16-1-1-cache-components → next-app-16-2-3-cache-components}/src/app/cache-lab/tag-invalidation/page.tsx +0 -0
  68. /package/test/integration/{next-app-16-1-1-cache-components → next-app-16-2-3-cache-components}/src/app/cache-lab/use-cache-nondeterministic/page.tsx +0 -0
  69. /package/test/integration/{next-app-16-1-1-cache-components → next-app-16-2-3-cache-components}/src/app/favicon.ico +0 -0
  70. /package/test/integration/{next-app-16-1-1-cache-components → next-app-16-2-3-cache-components}/src/app/globals.css +0 -0
  71. /package/test/integration/{next-app-16-1-1-cache-components → next-app-16-2-3-cache-components}/src/app/layout.tsx +0 -0
  72. /package/test/integration/{next-app-16-1-1-cache-components → next-app-16-2-3-cache-components}/src/app/page.tsx +0 -0
  73. /package/test/integration/{next-app-16-1-1-cache-components → next-app-16-2-3-cache-components}/src/app/revalidation-interface.tsx +0 -0
  74. /package/test/integration/{next-app-16-1-1-cache-components → next-app-16-2-3-cache-components}/src/app/update-tag-test/page.tsx +0 -0
  75. /package/test/integration/{next-app-16-1-1-cache-components → next-app-16-2-3-cache-components}/tsconfig.json +0 -0
@@ -30,7 +30,7 @@ jobs:
30
30
  run-cache-components: false
31
31
  - next-test-app: next-app-16-0-3
32
32
  run-cache-components: true
33
- - next-test-app: next-app-16-1-1
33
+ - next-test-app: next-app-16-2-3
34
34
  run-cache-components: true
35
35
 
36
36
  steps:
@@ -76,18 +76,18 @@ jobs:
76
76
  run: cd test/integration/${{ matrix.next-test-app }} && pnpm build
77
77
 
78
78
  - name: Run tests
79
- run: pnpm test
79
+ run: pnpm test:ci
80
80
  env:
81
81
  SKIP_BUILD: true
82
82
  NEXT_TEST_APP: ${{ matrix.next-test-app }}
83
83
 
84
84
  - name: Install Cache Components Integration Test Project
85
85
  if: matrix.run-cache-components
86
- run: cd test/integration/next-app-16-1-1-cache-components && pnpm install
86
+ run: cd test/integration/next-app-16-2-3-cache-components && pnpm install
87
87
 
88
88
  - name: Build Cache Components Integration Test Project
89
89
  if: matrix.run-cache-components
90
- run: cd test/integration/next-app-16-1-1-cache-components && pnpm build
90
+ run: cd test/integration/next-app-16-2-3-cache-components && pnpm build
91
91
 
92
92
  - name: Run Cache Components integration tests
93
93
  if: matrix.run-cache-components
@@ -121,3 +121,50 @@ jobs:
121
121
  NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }} # NPM token for publishing
122
122
  run: |
123
123
  npx semantic-release --dry-run
124
+
125
+ build-id-prefix:
126
+ runs-on: ubuntu-latest
127
+ permissions:
128
+ contents: read
129
+ steps:
130
+ - name: Checkout code
131
+ uses: actions/checkout@v6
132
+
133
+ - name: Install pnpm
134
+ run: corepack enable
135
+
136
+ - name: Setup Node.js
137
+ uses: actions/setup-node@v6
138
+ with:
139
+ node-version: '22'
140
+ cache: 'pnpm'
141
+
142
+ - name: Install dependencies
143
+ run: pnpm install --ignore-scripts
144
+
145
+ - name: Run lint
146
+ run: pnpm lint
147
+
148
+ - name: Build project
149
+ run: pnpm build
150
+
151
+ - name: Start Redis
152
+ uses: supercharge/redis-github-action@1.8.0
153
+ with:
154
+ redis-version: '7'
155
+ redis-port: 6379
156
+
157
+ - name: Install redis-cli
158
+ run: sudo apt-get update && sudo apt-get install -y redis-tools
159
+
160
+ - name: Configure Redis Keyspace Notifications
161
+ run: redis-cli config set notify-keyspace-events Exe
162
+
163
+ - name: Install Integration Test Project
164
+ run: cd test/integration/next-app-15-4-7 && pnpm install
165
+
166
+ - name: Build Integration Test Project
167
+ run: cd test/integration/next-app-15-4-7 && pnpm build
168
+
169
+ - name: Run BUILD_ID integration test
170
+ run: pnpm test:integration:build-id-prefix
package/CHANGELOG.md CHANGED
@@ -1,3 +1,17 @@
1
+ ## [1.14.1](https://github.com/trieb-work/nextjs-turbo-redis-cache/compare/v1.14.0...v1.14.1) (2026-05-15)
2
+
3
+
4
+ ### Bug Fixes
5
+
6
+ * treat Redis GET abort as cache miss ([#65](https://github.com/trieb-work/nextjs-turbo-redis-cache/issues/65)) ([52faf38](https://github.com/trieb-work/nextjs-turbo-redis-cache/commit/52faf38e267db3188a09a8495750d77c3b693ba8))
7
+
8
+ # [1.14.0](https://github.com/trieb-work/nextjs-turbo-redis-cache/compare/v1.13.0...v1.14.0) (2026-05-08)
9
+
10
+
11
+ ### Features
12
+
13
+ * upgrade Next.js test apps to 16.2.3 ([#77](https://github.com/trieb-work/nextjs-turbo-redis-cache/issues/77)) ([4f6c9a5](https://github.com/trieb-work/nextjs-turbo-redis-cache/commit/4f6c9a5660c11f945209691a7628c650145ebacd))
14
+
1
15
  # [1.13.0](https://github.com/trieb-work/nextjs-turbo-redis-cache/compare/v1.12.0...v1.13.0) (2026-05-04)
2
16
 
3
17
 
package/README.md CHANGED
@@ -27,8 +27,8 @@ Tested versions are:
27
27
  - Nextjs 15.3.2 + redis client 4.7.0
28
28
  - Nextjs 15.4.7 + redis client 4.7.0
29
29
  - Nextjs 16.0.3 + redis client 4.7.0 (cacheComponents: false)
30
- - Nextjs 16.1.1 + redis client 4.7.0 (cacheComponents: false)
31
- - Nextjs 16.1.1 + redis client 4.7.0 (cacheComponents: true)
30
+ - Nextjs 16.2.3 + redis client 4.7.0 (cacheComponents: false)
31
+ - Nextjs 16.2.3 + redis client 4.7.0 (cacheComponents: true)
32
32
 
33
33
  Currently PPR, 'use cache', cacheLife and cacheTag are not tested. Use these operations with caution and your own risk. [Cache Components](https://nextjs.org/docs/app/getting-started/cache-components) are supported experimentally (Next.js 16+).
34
34
 
@@ -226,6 +226,13 @@ To run all tests you can use the following command:
226
226
  pnpm build && pnpm test
227
227
  ```
228
228
 
229
+ For CI, we use dedicated scripts:
230
+
231
+ ```bash
232
+ pnpm test:ci
233
+ pnpm test:integration:build-id-prefix
234
+ ```
235
+
229
236
  Folder layout / runners:
230
237
 
231
238
  - **Vitest** (unit + integration) lives in `src/**/*.test.ts(x)` and `test/**`.
@@ -248,6 +255,12 @@ To run integration tests you can use the following command:
248
255
  pnpm build && pnpm test:integration
249
256
  ```
250
257
 
258
+ To run the BUILD_ID integration test independently:
259
+
260
+ ```bash
261
+ pnpm build && pnpm test:integration:build-id-prefix
262
+ ```
263
+
251
264
  ### E2E tests (Playwright)
252
265
 
253
266
  To run Playwright tests (`tests/**`) you can use:
@@ -327,8 +340,8 @@ This repo includes a dedicated Next.js Cache Components integration app with rea
327
340
  1. Install + start the Cache Components test app:
328
341
 
329
342
  ```bash
330
- pnpm -C test/integration/next-app-16-1-1-cache-components install
331
- pnpm -C test/integration/next-app-16-1-1-cache-components dev
343
+ pnpm -C test/integration/next-app-16-2-3-cache-components install
344
+ pnpm -C test/integration/next-app-16-2-3-cache-components dev
332
345
  ```
333
346
 
334
347
  Then open the Cache Lab pages:
package/dist/index.js CHANGED
@@ -501,6 +501,11 @@ function redisErrorHandler(debugInfo, redisCommandResult) {
501
501
  throw error;
502
502
  });
503
503
  }
504
+ function isAbortError(error) {
505
+ if (!error || typeof error !== "object") return false;
506
+ const err = error;
507
+ return err.name === "AbortError" || err.code === "ABORT_ERR";
508
+ }
504
509
  if (process.env.DEBUG_CACHE_HANDLER) {
505
510
  setInterval(() => {
506
511
  const start = performance.now();
@@ -692,12 +697,18 @@ var RedisStringsHandler = class {
692
697
  debug("green", "RedisStringsHandler.get() called with", key, ctx);
693
698
  await this.assertClientIsReady();
694
699
  const clientGet = this.redisGetDeduplication ? this.deduplicatedRedisGet(key) : this.redisGet;
700
+ const redisGetOperation = clientGet(
701
+ (0, import_redis.commandOptions)({ signal: AbortSignal.timeout(this.getTimeoutMs) }),
702
+ this.keyPrefix + key
703
+ ).catch((error) => {
704
+ if (isAbortError(error)) {
705
+ return null;
706
+ }
707
+ throw error;
708
+ });
695
709
  const serializedCacheEntry = await redisErrorHandler(
696
710
  "RedisStringsHandler.get(), operation: get" + (this.redisGetDeduplication ? "deduplicated" : "") + " " + this.getTimeoutMs + "ms " + this.keyPrefix + " " + key,
697
- clientGet(
698
- (0, import_redis.commandOptions)({ signal: AbortSignal.timeout(this.getTimeoutMs) }),
699
- this.keyPrefix + key
700
- )
711
+ redisGetOperation
701
712
  );
702
713
  debug(
703
714
  "green",