@trieb.work/nextjs-turbo-redis-cache 1.17.0 → 1.18.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/README.md +87 -24
- package/dist/index.d.mts +40 -1
- package/dist/index.d.ts +40 -1
- package/dist/index.js +291 -116
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +288 -115
- package/dist/index.mjs.map +1 -1
- package/package.json +9 -6
- package/.cursor/skills/testing/SKILL.md +0 -121
- package/.github/workflows/ci.yml +0 -309
- package/.github/workflows/pages.yml +0 -38
- package/.github/workflows/release.yml +0 -207
- package/.prettierrc.json +0 -6
- package/.vscode/settings.json +0 -10
- package/ARCHITECTURE.md +0 -431
- package/CHANGELOG.md +0 -411
- package/commitlint.config.cjs +0 -4
- package/docker/redis.conf +0 -1
- package/docs/index.html +0 -140
- package/docs/robots.txt +0 -4
- package/docs/sitemap.xml +0 -8
- package/docs/styles.css +0 -141
- package/eslint.config.mjs +0 -26
- package/hooks/commit-msg +0 -10
- package/hooks/pre-commit +0 -11
- package/playwright.config.ts +0 -18
- package/release.config.cjs +0 -31
- package/scripts/prepare.sh +0 -7
- package/scripts/setup-git.sh +0 -8
- package/scripts/setup-repo-name.sh +0 -17
- package/scripts/vitest-run-staged.cjs +0 -44
- package/src/CacheComponentsHandler.ts +0 -567
- package/src/CachedHandler.ts +0 -53
- package/src/DeduplicatedRequestHandler.ts +0 -110
- package/src/RedisStringsHandler.ts +0 -937
- package/src/SyncedMap.ts +0 -482
- package/src/ZodHandler.ts +0 -45
- package/src/index.ts +0 -16
- package/src/serializer.ts +0 -59
- package/src/utils/debug.ts +0 -30
- package/src/utils/json.ts +0 -49
- package/src/utils/prefix.ts +0 -44
- package/test/README.md +0 -194
- package/test/nextjs-test-projects/next-app-15-4-11/README.md +0 -36
- package/test/nextjs-test-projects/next-app-15-4-11/eslint.config.mjs +0 -16
- package/test/nextjs-test-projects/next-app-15-4-11/next.config.js +0 -9
- package/test/nextjs-test-projects/next-app-15-4-11/package-lock.json +0 -5969
- package/test/nextjs-test-projects/next-app-15-4-11/package.json +0 -29
- package/test/nextjs-test-projects/next-app-15-4-11/pnpm-lock.yaml +0 -3726
- package/test/nextjs-test-projects/next-app-15-4-11/postcss.config.mjs +0 -5
- package/test/nextjs-test-projects/next-app-15-4-11/public/file.svg +0 -1
- package/test/nextjs-test-projects/next-app-15-4-11/public/globe.svg +0 -1
- package/test/nextjs-test-projects/next-app-15-4-11/public/next.svg +0 -1
- package/test/nextjs-test-projects/next-app-15-4-11/public/vercel.svg +0 -1
- package/test/nextjs-test-projects/next-app-15-4-11/public/window.svg +0 -1
- package/test/nextjs-test-projects/next-app-15-4-11/src/app/api/cached-static-fetch/route.ts +0 -18
- package/test/nextjs-test-projects/next-app-15-4-11/src/app/api/nested-fetch-in-api-route/revalidated-fetch/route.ts +0 -27
- package/test/nextjs-test-projects/next-app-15-4-11/src/app/api/revalidatePath/route.ts +0 -15
- package/test/nextjs-test-projects/next-app-15-4-11/src/app/api/revalidateTag/route.ts +0 -15
- package/test/nextjs-test-projects/next-app-15-4-11/src/app/api/revalidated-fetch/route.ts +0 -17
- package/test/nextjs-test-projects/next-app-15-4-11/src/app/api/uncached-fetch/route.ts +0 -15
- package/test/nextjs-test-projects/next-app-15-4-11/src/app/globals.css +0 -26
- package/test/nextjs-test-projects/next-app-15-4-11/src/app/layout.tsx +0 -59
- package/test/nextjs-test-projects/next-app-15-4-11/src/app/page.tsx +0 -755
- package/test/nextjs-test-projects/next-app-15-4-11/src/app/pages/cached-static-fetch/default--force-dynamic-page/page.tsx +0 -19
- package/test/nextjs-test-projects/next-app-15-4-11/src/app/pages/cached-static-fetch/revalidate15--default-page/page.tsx +0 -34
- package/test/nextjs-test-projects/next-app-15-4-11/src/app/pages/cached-static-fetch/revalidate15--force-dynamic-page/page.tsx +0 -25
- package/test/nextjs-test-projects/next-app-15-4-11/src/app/pages/no-fetch/default-page/page.tsx +0 -55
- package/test/nextjs-test-projects/next-app-15-4-11/src/app/pages/revalidated-fetch/default--force-dynamic-page/page.tsx +0 -19
- package/test/nextjs-test-projects/next-app-15-4-11/src/app/pages/revalidated-fetch/revalidate15--default-page/page.tsx +0 -35
- package/test/nextjs-test-projects/next-app-15-4-11/src/app/pages/revalidated-fetch/revalidate15--force-dynamic-page/page.tsx +0 -25
- package/test/nextjs-test-projects/next-app-15-4-11/src/app/pages/uncached-fetch/default--force-dynamic-page/page.tsx +0 -19
- package/test/nextjs-test-projects/next-app-15-4-11/src/app/pages/uncached-fetch/revalidate15--default-page/page.tsx +0 -32
- package/test/nextjs-test-projects/next-app-15-4-11/src/app/pages/uncached-fetch/revalidate15--force-dynamic-page/page.tsx +0 -25
- package/test/nextjs-test-projects/next-app-15-4-11/src/app/revalidation-interface.tsx +0 -267
- package/test/nextjs-test-projects/next-app-15-4-11/tsconfig.json +0 -27
- package/test/nextjs-test-projects/next-app-16-0-11/README.md +0 -36
- package/test/nextjs-test-projects/next-app-16-0-11/eslint.config.mjs +0 -18
- package/test/nextjs-test-projects/next-app-16-0-11/next.config.ts +0 -10
- package/test/nextjs-test-projects/next-app-16-0-11/package.json +0 -28
- package/test/nextjs-test-projects/next-app-16-0-11/pnpm-lock.yaml +0 -4163
- package/test/nextjs-test-projects/next-app-16-0-11/postcss.config.mjs +0 -7
- package/test/nextjs-test-projects/next-app-16-0-11/src/app/api/cached-static-fetch/route.ts +0 -18
- package/test/nextjs-test-projects/next-app-16-0-11/src/app/api/nested-fetch-in-api-route/revalidated-fetch/route.ts +0 -27
- package/test/nextjs-test-projects/next-app-16-0-11/src/app/api/revalidatePath/route.ts +0 -15
- package/test/nextjs-test-projects/next-app-16-0-11/src/app/api/revalidateTag/route.ts +0 -20
- package/test/nextjs-test-projects/next-app-16-0-11/src/app/api/revalidated-fetch/route.ts +0 -17
- package/test/nextjs-test-projects/next-app-16-0-11/src/app/api/uncached-fetch/route.ts +0 -15
- package/test/nextjs-test-projects/next-app-16-0-11/src/app/favicon.ico +0 -0
- package/test/nextjs-test-projects/next-app-16-0-11/src/app/globals.css +0 -26
- package/test/nextjs-test-projects/next-app-16-0-11/src/app/layout.tsx +0 -59
- package/test/nextjs-test-projects/next-app-16-0-11/src/app/page.tsx +0 -755
- package/test/nextjs-test-projects/next-app-16-0-11/src/app/pages/cached-static-fetch/default--force-dynamic-page/page.tsx +0 -19
- package/test/nextjs-test-projects/next-app-16-0-11/src/app/pages/cached-static-fetch/revalidate15--default-page/page.tsx +0 -34
- package/test/nextjs-test-projects/next-app-16-0-11/src/app/pages/cached-static-fetch/revalidate15--force-dynamic-page/page.tsx +0 -25
- package/test/nextjs-test-projects/next-app-16-0-11/src/app/pages/no-fetch/default-page/page.tsx +0 -55
- package/test/nextjs-test-projects/next-app-16-0-11/src/app/pages/revalidated-fetch/default--force-dynamic-page/page.tsx +0 -19
- package/test/nextjs-test-projects/next-app-16-0-11/src/app/pages/revalidated-fetch/revalidate15--default-page/page.tsx +0 -35
- package/test/nextjs-test-projects/next-app-16-0-11/src/app/pages/revalidated-fetch/revalidate15--force-dynamic-page/page.tsx +0 -25
- package/test/nextjs-test-projects/next-app-16-0-11/src/app/pages/uncached-fetch/default--force-dynamic-page/page.tsx +0 -19
- package/test/nextjs-test-projects/next-app-16-0-11/src/app/pages/uncached-fetch/revalidate15--default-page/page.tsx +0 -32
- package/test/nextjs-test-projects/next-app-16-0-11/src/app/pages/uncached-fetch/revalidate15--force-dynamic-page/page.tsx +0 -25
- package/test/nextjs-test-projects/next-app-16-0-11/src/app/revalidation-interface.tsx +0 -267
- package/test/nextjs-test-projects/next-app-16-0-11/src/app/update-tag-test/page.tsx +0 -25
- package/test/nextjs-test-projects/next-app-16-0-11/tsconfig.json +0 -34
- package/test/nextjs-test-projects/next-app-16-0-11-cache-components/README.md +0 -36
- package/test/nextjs-test-projects/next-app-16-0-11-cache-components/cache-handler.js +0 -3
- package/test/nextjs-test-projects/next-app-16-0-11-cache-components/eslint.config.mjs +0 -18
- package/test/nextjs-test-projects/next-app-16-0-11-cache-components/next.config.ts +0 -13
- package/test/nextjs-test-projects/next-app-16-0-11-cache-components/package.json +0 -28
- package/test/nextjs-test-projects/next-app-16-0-11-cache-components/pnpm-lock.yaml +0 -4206
- package/test/nextjs-test-projects/next-app-16-0-11-cache-components/postcss.config.mjs +0 -7
- package/test/nextjs-test-projects/next-app-16-0-11-cache-components/public/file.svg +0 -1
- package/test/nextjs-test-projects/next-app-16-0-11-cache-components/public/globe.svg +0 -1
- package/test/nextjs-test-projects/next-app-16-0-11-cache-components/public/next.svg +0 -1
- package/test/nextjs-test-projects/next-app-16-0-11-cache-components/public/vercel.svg +0 -1
- package/test/nextjs-test-projects/next-app-16-0-11-cache-components/public/window.svg +0 -1
- package/test/nextjs-test-projects/next-app-16-0-11-cache-components/src/app/api/cached-static-fetch/route.ts +0 -19
- package/test/nextjs-test-projects/next-app-16-0-11-cache-components/src/app/api/cached-with-cachelife/route.ts +0 -24
- package/test/nextjs-test-projects/next-app-16-0-11-cache-components/src/app/api/cached-with-tag/route.ts +0 -21
- package/test/nextjs-test-projects/next-app-16-0-11-cache-components/src/app/api/revalidate-tag/route.ts +0 -19
- package/test/nextjs-test-projects/next-app-16-0-11-cache-components/src/app/api/revalidated-fetch/route.ts +0 -19
- package/test/nextjs-test-projects/next-app-16-0-11-cache-components/src/app/cache-lab/cachelife-short/page.tsx +0 -110
- package/test/nextjs-test-projects/next-app-16-0-11-cache-components/src/app/cache-lab/page.tsx +0 -90
- package/test/nextjs-test-projects/next-app-16-0-11-cache-components/src/app/cache-lab/runtime-data-suspense/page.tsx +0 -127
- package/test/nextjs-test-projects/next-app-16-0-11-cache-components/src/app/cache-lab/stale-while-revalidate/page.tsx +0 -130
- package/test/nextjs-test-projects/next-app-16-0-11-cache-components/src/app/cache-lab/tag-invalidation/page.tsx +0 -127
- package/test/nextjs-test-projects/next-app-16-0-11-cache-components/src/app/cache-lab/use-cache-nondeterministic/page.tsx +0 -110
- package/test/nextjs-test-projects/next-app-16-0-11-cache-components/src/app/favicon.ico +0 -0
- package/test/nextjs-test-projects/next-app-16-0-11-cache-components/src/app/globals.css +0 -26
- package/test/nextjs-test-projects/next-app-16-0-11-cache-components/src/app/layout.tsx +0 -57
- package/test/nextjs-test-projects/next-app-16-0-11-cache-components/src/app/page.tsx +0 -755
- package/test/nextjs-test-projects/next-app-16-0-11-cache-components/src/app/revalidation-interface.tsx +0 -267
- package/test/nextjs-test-projects/next-app-16-0-11-cache-components/src/app/update-tag-test/page.tsx +0 -22
- package/test/nextjs-test-projects/next-app-16-0-11-cache-components/tsconfig.json +0 -34
- package/test/nextjs-test-projects/next-app-16-2-6/README.md +0 -36
- package/test/nextjs-test-projects/next-app-16-2-6/eslint.config.mjs +0 -18
- package/test/nextjs-test-projects/next-app-16-2-6/next.config.ts +0 -7
- package/test/nextjs-test-projects/next-app-16-2-6/package.json +0 -28
- package/test/nextjs-test-projects/next-app-16-2-6/pnpm-lock.yaml +0 -4165
- package/test/nextjs-test-projects/next-app-16-2-6/postcss.config.mjs +0 -7
- package/test/nextjs-test-projects/next-app-16-2-6/src/app/api/cached-static-fetch/route.ts +0 -18
- package/test/nextjs-test-projects/next-app-16-2-6/src/app/api/nested-fetch-in-api-route/revalidated-fetch/route.ts +0 -27
- package/test/nextjs-test-projects/next-app-16-2-6/src/app/api/revalidatePath/route.ts +0 -15
- package/test/nextjs-test-projects/next-app-16-2-6/src/app/api/revalidateTag/route.ts +0 -20
- package/test/nextjs-test-projects/next-app-16-2-6/src/app/api/revalidated-fetch/route.ts +0 -17
- package/test/nextjs-test-projects/next-app-16-2-6/src/app/api/uncached-fetch/route.ts +0 -15
- package/test/nextjs-test-projects/next-app-16-2-6/src/app/favicon.ico +0 -0
- package/test/nextjs-test-projects/next-app-16-2-6/src/app/globals.css +0 -26
- package/test/nextjs-test-projects/next-app-16-2-6/src/app/layout.tsx +0 -59
- package/test/nextjs-test-projects/next-app-16-2-6/src/app/page.tsx +0 -755
- package/test/nextjs-test-projects/next-app-16-2-6/src/app/pages/cached-static-fetch/default--force-dynamic-page/page.tsx +0 -19
- package/test/nextjs-test-projects/next-app-16-2-6/src/app/pages/cached-static-fetch/revalidate15--default-page/page.tsx +0 -34
- package/test/nextjs-test-projects/next-app-16-2-6/src/app/pages/cached-static-fetch/revalidate15--force-dynamic-page/page.tsx +0 -25
- package/test/nextjs-test-projects/next-app-16-2-6/src/app/pages/no-fetch/default-page/page.tsx +0 -55
- package/test/nextjs-test-projects/next-app-16-2-6/src/app/pages/revalidated-fetch/default--force-dynamic-page/page.tsx +0 -19
- package/test/nextjs-test-projects/next-app-16-2-6/src/app/pages/revalidated-fetch/revalidate15--default-page/page.tsx +0 -35
- package/test/nextjs-test-projects/next-app-16-2-6/src/app/pages/revalidated-fetch/revalidate15--force-dynamic-page/page.tsx +0 -25
- package/test/nextjs-test-projects/next-app-16-2-6/src/app/pages/uncached-fetch/default--force-dynamic-page/page.tsx +0 -19
- package/test/nextjs-test-projects/next-app-16-2-6/src/app/pages/uncached-fetch/revalidate15--default-page/page.tsx +0 -32
- package/test/nextjs-test-projects/next-app-16-2-6/src/app/pages/uncached-fetch/revalidate15--force-dynamic-page/page.tsx +0 -25
- package/test/nextjs-test-projects/next-app-16-2-6/src/app/revalidation-interface.tsx +0 -267
- package/test/nextjs-test-projects/next-app-16-2-6/src/app/update-tag-test/page.tsx +0 -25
- package/test/nextjs-test-projects/next-app-16-2-6/tsconfig.json +0 -34
- package/test/nextjs-test-projects/next-app-16-2-6-cache-components/README.md +0 -36
- package/test/nextjs-test-projects/next-app-16-2-6-cache-components/cache-handler.js +0 -3
- package/test/nextjs-test-projects/next-app-16-2-6-cache-components/eslint.config.mjs +0 -18
- package/test/nextjs-test-projects/next-app-16-2-6-cache-components/next.config.ts +0 -13
- package/test/nextjs-test-projects/next-app-16-2-6-cache-components/package.json +0 -28
- package/test/nextjs-test-projects/next-app-16-2-6-cache-components/pnpm-lock.yaml +0 -4165
- package/test/nextjs-test-projects/next-app-16-2-6-cache-components/postcss.config.mjs +0 -7
- package/test/nextjs-test-projects/next-app-16-2-6-cache-components/public/file.svg +0 -1
- package/test/nextjs-test-projects/next-app-16-2-6-cache-components/public/globe.svg +0 -1
- package/test/nextjs-test-projects/next-app-16-2-6-cache-components/public/next.svg +0 -1
- package/test/nextjs-test-projects/next-app-16-2-6-cache-components/public/vercel.svg +0 -1
- package/test/nextjs-test-projects/next-app-16-2-6-cache-components/public/window.svg +0 -1
- package/test/nextjs-test-projects/next-app-16-2-6-cache-components/src/app/api/cached-static-fetch/route.ts +0 -19
- package/test/nextjs-test-projects/next-app-16-2-6-cache-components/src/app/api/cached-with-cachelife/route.ts +0 -24
- package/test/nextjs-test-projects/next-app-16-2-6-cache-components/src/app/api/cached-with-tag/route.ts +0 -21
- package/test/nextjs-test-projects/next-app-16-2-6-cache-components/src/app/api/revalidate-tag/route.ts +0 -19
- package/test/nextjs-test-projects/next-app-16-2-6-cache-components/src/app/api/revalidated-fetch/route.ts +0 -19
- package/test/nextjs-test-projects/next-app-16-2-6-cache-components/src/app/cache-lab/cachelife-short/page.tsx +0 -110
- package/test/nextjs-test-projects/next-app-16-2-6-cache-components/src/app/cache-lab/page.tsx +0 -90
- package/test/nextjs-test-projects/next-app-16-2-6-cache-components/src/app/cache-lab/runtime-data-suspense/page.tsx +0 -127
- package/test/nextjs-test-projects/next-app-16-2-6-cache-components/src/app/cache-lab/stale-while-revalidate/page.tsx +0 -130
- package/test/nextjs-test-projects/next-app-16-2-6-cache-components/src/app/cache-lab/tag-invalidation/page.tsx +0 -127
- package/test/nextjs-test-projects/next-app-16-2-6-cache-components/src/app/cache-lab/use-cache-nondeterministic/page.tsx +0 -110
- package/test/nextjs-test-projects/next-app-16-2-6-cache-components/src/app/favicon.ico +0 -0
- package/test/nextjs-test-projects/next-app-16-2-6-cache-components/src/app/globals.css +0 -26
- package/test/nextjs-test-projects/next-app-16-2-6-cache-components/src/app/layout.tsx +0 -57
- package/test/nextjs-test-projects/next-app-16-2-6-cache-components/src/app/page.tsx +0 -755
- package/test/nextjs-test-projects/next-app-16-2-6-cache-components/src/app/revalidation-interface.tsx +0 -267
- package/test/nextjs-test-projects/next-app-16-2-6-cache-components/src/app/update-tag-test/page.tsx +0 -22
- package/test/nextjs-test-projects/next-app-16-2-6-cache-components/tsconfig.json +0 -34
- package/test/nextjs-test-projects/next-app-16-3-0/README.md +0 -36
- package/test/nextjs-test-projects/next-app-16-3-0/eslint.config.mjs +0 -18
- package/test/nextjs-test-projects/next-app-16-3-0/next.config.ts +0 -7
- package/test/nextjs-test-projects/next-app-16-3-0/package.json +0 -28
- package/test/nextjs-test-projects/next-app-16-3-0/pnpm-lock.yaml +0 -4284
- package/test/nextjs-test-projects/next-app-16-3-0/postcss.config.mjs +0 -7
- package/test/nextjs-test-projects/next-app-16-3-0/src/app/api/cached-static-fetch/route.ts +0 -18
- package/test/nextjs-test-projects/next-app-16-3-0/src/app/api/nested-fetch-in-api-route/revalidated-fetch/route.ts +0 -27
- package/test/nextjs-test-projects/next-app-16-3-0/src/app/api/revalidatePath/route.ts +0 -15
- package/test/nextjs-test-projects/next-app-16-3-0/src/app/api/revalidateTag/route.ts +0 -20
- package/test/nextjs-test-projects/next-app-16-3-0/src/app/api/revalidated-fetch/route.ts +0 -17
- package/test/nextjs-test-projects/next-app-16-3-0/src/app/api/uncached-fetch/route.ts +0 -15
- package/test/nextjs-test-projects/next-app-16-3-0/src/app/favicon.ico +0 -0
- package/test/nextjs-test-projects/next-app-16-3-0/src/app/globals.css +0 -26
- package/test/nextjs-test-projects/next-app-16-3-0/src/app/layout.tsx +0 -59
- package/test/nextjs-test-projects/next-app-16-3-0/src/app/page.tsx +0 -755
- package/test/nextjs-test-projects/next-app-16-3-0/src/app/pages/cached-static-fetch/default--force-dynamic-page/page.tsx +0 -19
- package/test/nextjs-test-projects/next-app-16-3-0/src/app/pages/cached-static-fetch/revalidate15--default-page/page.tsx +0 -34
- package/test/nextjs-test-projects/next-app-16-3-0/src/app/pages/cached-static-fetch/revalidate15--force-dynamic-page/page.tsx +0 -25
- package/test/nextjs-test-projects/next-app-16-3-0/src/app/pages/no-fetch/default-page/page.tsx +0 -55
- package/test/nextjs-test-projects/next-app-16-3-0/src/app/pages/revalidated-fetch/default--force-dynamic-page/page.tsx +0 -19
- package/test/nextjs-test-projects/next-app-16-3-0/src/app/pages/revalidated-fetch/revalidate15--default-page/page.tsx +0 -35
- package/test/nextjs-test-projects/next-app-16-3-0/src/app/pages/revalidated-fetch/revalidate15--force-dynamic-page/page.tsx +0 -25
- package/test/nextjs-test-projects/next-app-16-3-0/src/app/pages/uncached-fetch/default--force-dynamic-page/page.tsx +0 -19
- package/test/nextjs-test-projects/next-app-16-3-0/src/app/pages/uncached-fetch/revalidate15--default-page/page.tsx +0 -32
- package/test/nextjs-test-projects/next-app-16-3-0/src/app/pages/uncached-fetch/revalidate15--force-dynamic-page/page.tsx +0 -25
- package/test/nextjs-test-projects/next-app-16-3-0/src/app/revalidation-interface.tsx +0 -267
- package/test/nextjs-test-projects/next-app-16-3-0/src/app/update-tag-test/page.tsx +0 -25
- package/test/nextjs-test-projects/next-app-16-3-0/tsconfig.json +0 -34
- package/test/nextjs-test-projects/next-app-16-3-0-cache-components/README.md +0 -36
- package/test/nextjs-test-projects/next-app-16-3-0-cache-components/cache-handler.js +0 -3
- package/test/nextjs-test-projects/next-app-16-3-0-cache-components/eslint.config.mjs +0 -18
- package/test/nextjs-test-projects/next-app-16-3-0-cache-components/next.config.ts +0 -13
- package/test/nextjs-test-projects/next-app-16-3-0-cache-components/package.json +0 -28
- package/test/nextjs-test-projects/next-app-16-3-0-cache-components/pnpm-lock.yaml +0 -4284
- package/test/nextjs-test-projects/next-app-16-3-0-cache-components/postcss.config.mjs +0 -7
- package/test/nextjs-test-projects/next-app-16-3-0-cache-components/public/file.svg +0 -1
- package/test/nextjs-test-projects/next-app-16-3-0-cache-components/public/globe.svg +0 -1
- package/test/nextjs-test-projects/next-app-16-3-0-cache-components/public/next.svg +0 -1
- package/test/nextjs-test-projects/next-app-16-3-0-cache-components/public/vercel.svg +0 -1
- package/test/nextjs-test-projects/next-app-16-3-0-cache-components/public/window.svg +0 -1
- package/test/nextjs-test-projects/next-app-16-3-0-cache-components/src/app/api/cached-static-fetch/route.ts +0 -19
- package/test/nextjs-test-projects/next-app-16-3-0-cache-components/src/app/api/cached-with-cachelife/route.ts +0 -24
- package/test/nextjs-test-projects/next-app-16-3-0-cache-components/src/app/api/cached-with-tag/route.ts +0 -21
- package/test/nextjs-test-projects/next-app-16-3-0-cache-components/src/app/api/revalidate-tag/route.ts +0 -19
- package/test/nextjs-test-projects/next-app-16-3-0-cache-components/src/app/api/revalidated-fetch/route.ts +0 -19
- package/test/nextjs-test-projects/next-app-16-3-0-cache-components/src/app/cache-lab/cachelife-short/page.tsx +0 -110
- package/test/nextjs-test-projects/next-app-16-3-0-cache-components/src/app/cache-lab/page.tsx +0 -90
- package/test/nextjs-test-projects/next-app-16-3-0-cache-components/src/app/cache-lab/runtime-data-suspense/page.tsx +0 -127
- package/test/nextjs-test-projects/next-app-16-3-0-cache-components/src/app/cache-lab/stale-while-revalidate/page.tsx +0 -130
- package/test/nextjs-test-projects/next-app-16-3-0-cache-components/src/app/cache-lab/tag-invalidation/page.tsx +0 -127
- package/test/nextjs-test-projects/next-app-16-3-0-cache-components/src/app/cache-lab/use-cache-nondeterministic/page.tsx +0 -110
- package/test/nextjs-test-projects/next-app-16-3-0-cache-components/src/app/favicon.ico +0 -0
- package/test/nextjs-test-projects/next-app-16-3-0-cache-components/src/app/globals.css +0 -26
- package/test/nextjs-test-projects/next-app-16-3-0-cache-components/src/app/layout.tsx +0 -57
- package/test/nextjs-test-projects/next-app-16-3-0-cache-components/src/app/page.tsx +0 -755
- package/test/nextjs-test-projects/next-app-16-3-0-cache-components/src/app/revalidation-interface.tsx +0 -267
- package/test/nextjs-test-projects/next-app-16-3-0-cache-components/src/app/update-tag-test/page.tsx +0 -22
- package/test/nextjs-test-projects/next-app-16-3-0-cache-components/tsconfig.json +0 -34
- package/test/nextjs-test-projects/next-app-customized/README.md +0 -36
- package/test/nextjs-test-projects/next-app-customized/customized-cache-handler.js +0 -34
- package/test/nextjs-test-projects/next-app-customized/eslint.config.mjs +0 -16
- package/test/nextjs-test-projects/next-app-customized/next.config.js +0 -6
- package/test/nextjs-test-projects/next-pages-16-2-6/README.md +0 -16
- package/test/nextjs-test-projects/next-pages-16-2-6/eslint.config.mjs +0 -18
- package/test/nextjs-test-projects/next-pages-16-2-6/next.config.ts +0 -7
- package/test/nextjs-test-projects/next-pages-16-2-6/package.json +0 -26
- package/test/nextjs-test-projects/next-pages-16-2-6/pnpm-lock.yaml +0 -3896
- package/test/nextjs-test-projects/next-pages-16-2-6/src/pages/api/revalidate.ts +0 -24
- package/test/nextjs-test-projects/next-pages-16-2-6/src/pages/index.tsx +0 -11
- package/test/nextjs-test-projects/next-pages-16-2-6/src/pages/isr/[slug].tsx +0 -49
- package/test/nextjs-test-projects/next-pages-16-2-6/src/pages/static-forever.tsx +0 -20
- package/test/nextjs-test-projects/next-pages-16-2-6/tsconfig.json +0 -34
- package/test/nextjs-test-projects/next-pages-16-3-0/README.md +0 -16
- package/test/nextjs-test-projects/next-pages-16-3-0/eslint.config.mjs +0 -18
- package/test/nextjs-test-projects/next-pages-16-3-0/next.config.ts +0 -7
- package/test/nextjs-test-projects/next-pages-16-3-0/package.json +0 -26
- package/test/nextjs-test-projects/next-pages-16-3-0/pnpm-lock.yaml +0 -3939
- package/test/nextjs-test-projects/next-pages-16-3-0/src/pages/api/revalidate.ts +0 -24
- package/test/nextjs-test-projects/next-pages-16-3-0/src/pages/index.tsx +0 -11
- package/test/nextjs-test-projects/next-pages-16-3-0/src/pages/isr/[slug].tsx +0 -49
- package/test/nextjs-test-projects/next-pages-16-3-0/src/pages/static-forever.tsx +0 -20
- package/test/nextjs-test-projects/next-pages-16-3-0/tsconfig.json +0 -34
- package/test/playwright/cache-lab.spec.ts +0 -157
- package/test/playwright/update-tag.spec.ts +0 -33
- package/test/vitest/integration/build-id-prefix.integration.test.ts +0 -102
- package/test/vitest/integration/cache-components/cache-components.integration.test.ts +0 -231
- package/test/vitest/integration/cache-components/redis-kill-reconnect.test.ts +0 -65
- package/test/vitest/integration/cache-components/redis-quit-vs-disconnect.test.ts +0 -59
- package/test/vitest/integration/cache-components/redis-subscriber-outage.test.ts +0 -100
- package/test/vitest/integration/cache-components/scripts/redis-kill-reconnect.ts +0 -243
- package/test/vitest/integration/cache-components/scripts/redis-quit-vs-disconnect.ts +0 -113
- package/test/vitest/integration/cache-components/scripts/redis-subscriber-outage.ts +0 -379
- package/test/vitest/integration/cache-components/scripts/redis-test-helpers.ts +0 -155
- package/test/vitest/integration/nextjs-cache-handler.integration.test.ts +0 -945
- package/test/vitest/integration/pages-router.integration.test.ts +0 -420
- package/test/vitest/unit/SyncedMap-reconnect-repro.test.ts +0 -154
- package/test/vitest/unit/index.test.ts +0 -173
- package/test/vitest/unit/pages-router-kinds.test.ts +0 -292
- package/test/vitest/unit/reconnect-socket-already-opened.test.ts +0 -117
- package/test/vitest/unit/serializer.test.ts +0 -182
- package/test/vitest/unit/utils/prefix.test.ts +0 -115
- package/tsconfig.json +0 -18
- package/tsup.config.ts +0 -14
- package/vite.config.ts +0 -34
- package/vitest.cache-components.config.ts +0 -16
package/README.md
CHANGED
|
@@ -90,6 +90,8 @@ const nextConfig = {
|
|
|
90
90
|
|
|
91
91
|
Make sure to set either REDIS_URL or REDISHOST and REDISPORT environment variables.
|
|
92
92
|
|
|
93
|
+
Redis connections are skipped during `next build` (`NEXT_PHASE=phase-production-build`), so a production build can succeed without Redis. The handler connects when Next.js first calls it at runtime (`next start`).
|
|
94
|
+
|
|
93
95
|
### Option B: create a wrapper file to change options
|
|
94
96
|
|
|
95
97
|
create new file `customized-cache-handler.js` in your project root and add the following code:
|
|
@@ -131,6 +133,8 @@ module.exports = class CustomizedCacheHandler {
|
|
|
131
133
|
}
|
|
132
134
|
```
|
|
133
135
|
|
|
136
|
+
`defaultStaleAge` and `estimateExpireAge` are fallbacks for when Next.js does not pass `cacheControl.expire`. On Next.js 16.3+ ISR, Redis TTL is `expire` and these options do not change it.
|
|
137
|
+
|
|
134
138
|
extend `next.config.js` with:
|
|
135
139
|
|
|
136
140
|
```
|
|
@@ -145,23 +149,23 @@ A working example of above can be found in the `test/nextjs-test-projects/next-a
|
|
|
145
149
|
|
|
146
150
|
## Available Options
|
|
147
151
|
|
|
148
|
-
| Option | Description
|
|
149
|
-
| ----------------------------- |
|
|
150
|
-
| redisUrl | Redis connection url
|
|
151
|
-
| database | Redis database number to use. Uses DB 0 for production, DB 1 otherwise
|
|
152
|
-
| keyPrefix | Prefix added to all Redis keys
|
|
153
|
-
| sharedTagsKey | Key used to store shared tags hash map in Redis
|
|
154
|
-
| getTimeoutMs | Timeout in milliseconds for time critical Redis operations. If Redis get is not fulfilled within this time, returns null to avoid blocking site rendering.
|
|
155
|
-
| revalidateTagQuerySize | Number of entries to query in one batch during full sync of shared tags hash map
|
|
156
|
-
| avgResyncIntervalMs | Average interval in milliseconds between tag map full re-syncs
|
|
157
|
-
| redisGetDeduplication | Enable deduplication of Redis get requests via internal in-memory cache.
|
|
158
|
-
| inMemoryCachingTime | Time in milliseconds to cache Redis get results in memory. Set this to 0 to disable in-memory caching completely.
|
|
159
|
-
| defaultStaleAge |
|
|
160
|
-
| estimateExpireAge |
|
|
161
|
-
| socketOptions | Redis client socket options for TLS/SSL configuration (e.g., `{ tls: true, rejectUnauthorized: false }`)
|
|
162
|
-
| clientOptions | Additional Redis client options (e.g., username, password)
|
|
163
|
-
| killContainerOnErrorThreshold | Number of consecutive errors before the container is killed. Set to 0 to disable.
|
|
164
|
-
| valueSerializer | Pluggable wire-format codec for Redis string values (compression, encryption, custom encoding). See [Custom value serializer](#custom-value-serializer-compression-encryption).
|
|
152
|
+
| Option | Description | Default Value |
|
|
153
|
+
| ----------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
154
|
+
| redisUrl | Redis connection url | `process.env.REDIS_URL? process.env.REDIS_URL : process.env.REDISHOST ? redis://${process.env.REDISHOST}:${process.env.REDISPORT} : 'redis://localhost:6379'` |
|
|
155
|
+
| database | Redis database number to use. Uses DB 0 for production, DB 1 otherwise | `process.env.VERCEL_ENV === 'production' ? 0 : 1` |
|
|
156
|
+
| keyPrefix | Prefix added to all Redis keys | `RedisStringsHandler` default: `process.env.KEY_PREFIX \|\| process.env.VERCEL_URL \|\| 'UNDEFINED_URL_'`<br> Next handlers resolve: `options.keyPrefix \|\| KEY_PREFIX \|\| VERCEL_URL \|\| BUILD_ID \|\| 'UNDEFINED_URL_'` |
|
|
157
|
+
| sharedTagsKey | Key used to store shared tags hash map in Redis | `'__sharedTags__'` |
|
|
158
|
+
| getTimeoutMs | Timeout in milliseconds for time critical Redis operations. If Redis get is not fulfilled within this time, returns null to avoid blocking site rendering. | `process.env.REDIS_COMMAND_TIMEOUT_MS ? (Number.parseInt(process.env.REDIS_COMMAND_TIMEOUT_MS) ?? 500) : 500` |
|
|
159
|
+
| revalidateTagQuerySize | Number of entries to query in one batch during full sync of shared tags hash map | `250` |
|
|
160
|
+
| avgResyncIntervalMs | Average interval in milliseconds between tag map full re-syncs | `3600000` (1 hour) |
|
|
161
|
+
| redisGetDeduplication | Enable deduplication of Redis get requests via internal in-memory cache. | `true` |
|
|
162
|
+
| inMemoryCachingTime | Time in milliseconds to cache Redis get results in memory. Set this to 0 to disable in-memory caching completely. | `10000` |
|
|
163
|
+
| defaultStaleAge | Fallback stale age in seconds used only when Next.js does not pass a finite `cacheControl.expire` (e.g. `revalidate: false`, or older callers that only send `revalidate`). Next 16.3+ ISR typically sends `expire` (~1 year); that value is the Redis TTL and this option is ignored. | `1209600` (14 days) |
|
|
164
|
+
| estimateExpireAge | Fallback to compute Redis TTL from a stale/`revalidate` age when `cacheControl.expire` is absent. Not applied when Next.js provides `expire`. | Production: `staleAge * 2`<br> Other: `staleAge * 1.2` |
|
|
165
|
+
| socketOptions | Redis client socket options for TLS/SSL configuration (e.g., `{ tls: true, rejectUnauthorized: false }`) | `{ connectTimeout: timeoutMs }` |
|
|
166
|
+
| clientOptions | Additional Redis client options (e.g., username, password) | `undefined` |
|
|
167
|
+
| killContainerOnErrorThreshold | Number of consecutive errors before the container is killed. Set to 0 to disable. | `Number.parseInt(process.env.KILL_CONTAINER_ON_ERROR_THRESHOLD) ?? 0 : 0` |
|
|
168
|
+
| valueSerializer | Pluggable wire-format codec for Redis string values (compression, encryption, custom encoding). See [Custom value serializer](#custom-value-serializer-compression-encryption). | `jsonCacheValueSerializer` (`JSON.stringify` with built-in `Buffer` and `Map` encoding) |
|
|
165
169
|
|
|
166
170
|
## Custom value serializer (compression, encryption)
|
|
167
171
|
|
|
@@ -467,7 +471,50 @@ Install the package in your Next.js app:
|
|
|
467
471
|
pnpm add @trieb.work/nextjs-turbo-redis-cache redis
|
|
468
472
|
```
|
|
469
473
|
|
|
470
|
-
|
|
474
|
+
#### Hybrid setup (ISR + Cache Components)
|
|
475
|
+
|
|
476
|
+
Next.js has **two different handler APIs**. They are not interchangeable:
|
|
477
|
+
|
|
478
|
+
| Config key | Next.js loads it as | This package export | Methods |
|
|
479
|
+
| ------------------------- | --------------------------------- | ------------------------------------------ | ---------------------------------------------------------- |
|
|
480
|
+
| `cacheHandler` (singular) | `new Handler(options)` | **default export** (`CachedHandler` class) | `get`, `set`, `revalidateTag`, `resetRequestCache` |
|
|
481
|
+
| `cacheHandlers` (plural) | imported object (not constructed) | **`redisCacheHandler`** | `get`, `set`, `getExpiration`, `updateTags`, `refreshTags` |
|
|
482
|
+
|
|
483
|
+
`redisCacheHandler` is not a constructor (`new redisCacheHandler()` throws). Pointing `cacheHandler` at `./cache-handler.js` (the Cache Components object) will fail at runtime. Pointing `cacheHandlers` at the default class export will not provide `getExpiration` / `updateTags`.
|
|
484
|
+
|
|
485
|
+
For a self-hosted app that needs both ISR and `'use cache'` / `'use cache: remote'`:
|
|
486
|
+
|
|
487
|
+
```ts
|
|
488
|
+
// next.config.ts
|
|
489
|
+
import type { NextConfig } from 'next';
|
|
490
|
+
|
|
491
|
+
const nextConfig: NextConfig = {
|
|
492
|
+
cacheComponents: true,
|
|
493
|
+
cacheHandler: require.resolve('@trieb.work/nextjs-turbo-redis-cache'),
|
|
494
|
+
cacheHandlers: {
|
|
495
|
+
default: require.resolve('./cache-handler.js'),
|
|
496
|
+
remote: require.resolve('./cache-handler.js'),
|
|
497
|
+
},
|
|
498
|
+
cacheMaxMemorySize: 0,
|
|
499
|
+
};
|
|
500
|
+
|
|
501
|
+
export default nextConfig;
|
|
502
|
+
```
|
|
503
|
+
|
|
504
|
+
```js
|
|
505
|
+
// cache-handler.js — Cache Components only (`cacheHandlers.default` / `.remote`)
|
|
506
|
+
const { redisCacheHandler } = require('@trieb.work/nextjs-turbo-redis-cache');
|
|
507
|
+
|
|
508
|
+
module.exports = redisCacheHandler;
|
|
509
|
+
```
|
|
510
|
+
|
|
511
|
+
`default` and `remote` may be the same `redisCacheHandler` module: `'use cache'` uses `default`, `'use cache: remote'` uses `remote`. `cacheMaxMemorySize: 0` disables Next's in-process memory cache so Redis is shared across instances.
|
|
512
|
+
|
|
513
|
+
Do not wrap ISR and Cache Components in one file unless you implement **both** interfaces (class constructed with `new`, and a separate object export). This package ships them as two exports on purpose.
|
|
514
|
+
|
|
515
|
+
#### Cache Components only
|
|
516
|
+
|
|
517
|
+
If you only need Cache Components (no ISR `cacheHandler`), enable Cache Components and point `cacheHandlers` at `redisCacheHandler`. Include `remote` if you use `'use cache: remote'`.
|
|
471
518
|
|
|
472
519
|
```ts
|
|
473
520
|
// next.config.ts
|
|
@@ -477,7 +524,9 @@ const nextConfig: NextConfig = {
|
|
|
477
524
|
cacheComponents: true,
|
|
478
525
|
cacheHandlers: {
|
|
479
526
|
default: require.resolve('./cache-handler.js'),
|
|
527
|
+
remote: require.resolve('./cache-handler.js'),
|
|
480
528
|
},
|
|
529
|
+
cacheMaxMemorySize: 0,
|
|
481
530
|
};
|
|
482
531
|
|
|
483
532
|
export default nextConfig;
|
|
@@ -508,6 +557,19 @@ Optional:
|
|
|
508
557
|
- `VERCEL_URL`: used as a key prefix for multi-tenant isolation (also useful in tests). If unset, a default prefix is used.
|
|
509
558
|
- `REDIS_COMMAND_TIMEOUT_MS`: timeout (ms) for Redis commands used by the handler.
|
|
510
559
|
|
|
560
|
+
### Official caching semantics (Vercel / Next.js self-hosting docs)
|
|
561
|
+
|
|
562
|
+
This package follows the semantics documented in the [Next.js self-hosting guide](https://nextjs.org/docs/app/guides/self-hosting#configuring-caching) and the official `cache-handler-redis` example:
|
|
563
|
+
|
|
564
|
+
| Topic | Behavior |
|
|
565
|
+
| --------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
|
|
566
|
+
| **ISR Redis TTL** | Key TTL on `cacheControl.expire`, not `revalidate`. Past `revalidate` an entry is only stale (SWR); evicting at that boundary would defeat background refresh. Legacy callers that only pass `revalidate` still get `estimateExpireAge(revalidate)`. |
|
|
567
|
+
| **Tag sources (ISR)** | `APP_PAGE` / `APP_ROUTE` tags come from `data.headers['x-next-cache-tags']` plus `ctx.tags`. `FETCH` tags come from `ctx.tags`. |
|
|
568
|
+
| **Buffer / Map serialization** | `rscData` (`Buffer`) and `segmentData` (`Map`) require custom JSON encoding — use the built-in `jsonCacheValueSerializer` or wrap it. Plain `JSON.stringify` causes `segmentData.get is not a function` on RSC navigation. |
|
|
569
|
+
| **`updateTags(tags, durations)`** | Persists Next.js tag-manifest fields in Redis (`stale` / `expired`). No `durations` or `{ expire: 0 }` hard-expires (`expired = now`). `expire > 0` (including `'max'` ~1 year) is the SWR window: `stale = now`, `expired = now + expire * 1000`, and `get()` returns `revalidate: -1` until that deadline. |
|
|
570
|
+
| **`getExpiration` pattern** | Returns max tag `expired` (may be in the future). Next.js uses this for implicit/soft tags. Explicit `cacheTag()`s are checked in `get()` via `areTagsExpired` / `areTagsStale`. |
|
|
571
|
+
| **Build without Redis** | During `next build` (`NEXT_PHASE`), Redis connections are skipped so CI/build pipelines without Redis still succeed. |
|
|
572
|
+
|
|
511
573
|
### Lazy initialization
|
|
512
574
|
|
|
513
575
|
The `redisCacheHandler` export is **lazily initialized** — importing the package does **not** open a Redis connection. The connection is deferred until the first method call on the handler (when Next.js invokes it). This means:
|
|
@@ -536,6 +598,8 @@ Then open the Cache Lab pages:
|
|
|
536
598
|
- `/cache-lab/tag-invalidation`
|
|
537
599
|
- `/cache-lab/stale-while-revalidate`
|
|
538
600
|
- `/cache-lab/runtime-data-suspense`
|
|
601
|
+
- `/cache-lab/use-cache-remote`
|
|
602
|
+
- `/cache-lab/revalidate-durations`
|
|
539
603
|
|
|
540
604
|
To run the Playwright E2E tests against a running dev server:
|
|
541
605
|
|
|
@@ -545,13 +609,12 @@ PLAYWRIGHT_BASE_URL=http://localhost:3101 pnpm test:e2e
|
|
|
545
609
|
|
|
546
610
|
## Some words on nextjs caching internals
|
|
547
611
|
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
app/<segment>/route.ts files will request using the APP_ROUTE kind.
|
|
551
|
-
app/<segment>/page.tsx files will request using the APP_PAGE kind.
|
|
552
|
-
/favicon.ico file will request using the APP_ROUTE kind.
|
|
612
|
+
Next.js uses different cache entry kinds. This handler supports `APP_PAGE`, `APP_ROUTE`, `FETCH`, `PAGES`, and `REDIRECT` (plus Pages Router `notFound` stored as a null value).
|
|
553
613
|
|
|
554
|
-
|
|
614
|
+
- `app/<segment>/page.tsx` → `APP_PAGE`
|
|
615
|
+
- `app/<segment>/route.ts` (and `/favicon.ico`) → `APP_ROUTE`
|
|
616
|
+
- `fetch()` inside App Router → `FETCH`
|
|
617
|
+
- Pages Router `getStaticProps` → `PAGES` / `REDIRECT`
|
|
555
618
|
|
|
556
619
|
For details on how these kinds are handled internally (tag maps, deduplication, value transformation), see [ARCHITECTURE.md](./ARCHITECTURE.md).
|
|
557
620
|
|
package/dist/index.d.mts
CHANGED
|
@@ -221,10 +221,12 @@ declare class RedisStringsHandler {
|
|
|
221
221
|
private estimateExpireAge;
|
|
222
222
|
private killContainerOnErrorThreshold;
|
|
223
223
|
private valueSerializer;
|
|
224
|
+
private redisConnectionDeferred;
|
|
224
225
|
constructor({ redisUrl, database, keyPrefix, sharedTagsKey, getTimeoutMs, revalidateTagQuerySize, avgResyncIntervalMs, redisGetDeduplication, inMemoryCachingTime, defaultStaleAge, estimateExpireAge, killContainerOnErrorThreshold, socketOptions, clientOptions, valueSerializer, }: CreateRedisStringsHandlerOptions);
|
|
225
226
|
resetRequestCache(): void;
|
|
226
227
|
private clientReadyCalls;
|
|
227
228
|
private assertClientIsReady;
|
|
229
|
+
private isClientUnavailable;
|
|
228
230
|
get(key: string, ctx: GetContext): Promise<CacheEntry | null>;
|
|
229
231
|
set(key: string, data: SetCacheValue, ctx: {
|
|
230
232
|
isRoutePPREnabled: boolean;
|
|
@@ -253,6 +255,43 @@ declare class CachedHandler {
|
|
|
253
255
|
declare function bufferAndMapReviver(_: string, value: any): any;
|
|
254
256
|
declare function bufferAndMapReplacer(_: string, value: any): any;
|
|
255
257
|
|
|
258
|
+
type ResolveCacheEntryTtlContext = {
|
|
259
|
+
revalidate?: number | false;
|
|
260
|
+
cacheControl?: {
|
|
261
|
+
revalidate?: number | false;
|
|
262
|
+
expire?: number | undefined;
|
|
263
|
+
};
|
|
264
|
+
};
|
|
265
|
+
type ResolveCacheEntryTtlData = {
|
|
266
|
+
kind?: string;
|
|
267
|
+
revalidate?: number | false;
|
|
268
|
+
} | null;
|
|
269
|
+
type ResolveCacheEntryTtlOptions = {
|
|
270
|
+
estimateExpireAge: (staleAge: number) => number;
|
|
271
|
+
defaultStaleAge: number;
|
|
272
|
+
};
|
|
273
|
+
/**
|
|
274
|
+
* Resolves the Redis TTL (seconds) for an ISR / incremental-cache entry.
|
|
275
|
+
*
|
|
276
|
+
* Official Next.js semantics (cache-handler-redis example + self-hosting docs):
|
|
277
|
+
* - Key TTL on `cacheControl.expire`, never on `revalidate` alone.
|
|
278
|
+
* - Past `revalidate` an entry is only stale (SWR); evicting at that boundary
|
|
279
|
+
* would defeat background refresh.
|
|
280
|
+
* - When no finite `expire` is provided, fall back to `estimateExpireAge(revalidate)`
|
|
281
|
+
* for legacy Pages Router / pre-cacheLife callers that only pass `revalidate`.
|
|
282
|
+
* - When neither `expire` nor `revalidate` is available, return `undefined` (no TTL;
|
|
283
|
+
* rely on tag-based invalidation). This is intentional — not a missing
|
|
284
|
+
* `defaultStaleAge` fallback. `revalidate: false` is a separate branch above
|
|
285
|
+
* and is covered by unit + Pages Router integration tests (`/static-forever`).
|
|
286
|
+
*/
|
|
287
|
+
declare function resolveCacheEntryTtlSeconds(ctx: ResolveCacheEntryTtlContext, data: ResolveCacheEntryTtlData, options: ResolveCacheEntryTtlOptions): number | undefined;
|
|
288
|
+
|
|
289
|
+
/**
|
|
290
|
+
* Returns true during `next build` so handlers can skip opening Redis
|
|
291
|
+
* connections. Matches the official Next.js cache-handler-redis example.
|
|
292
|
+
*/
|
|
293
|
+
declare function shouldDeferRedisConnection(): boolean;
|
|
294
|
+
|
|
256
295
|
interface CacheComponentsEntry {
|
|
257
296
|
value: ReadableStream<Uint8Array>;
|
|
258
297
|
tags: string[];
|
|
@@ -276,4 +315,4 @@ type CreateCacheComponentsHandlerOptions = CreateRedisStringsHandlerOptions & {
|
|
|
276
315
|
declare function getRedisCacheComponentsHandler(options?: CreateCacheComponentsHandlerOptions): CacheComponentsHandler;
|
|
277
316
|
declare const redisCacheHandler: CacheComponentsHandler;
|
|
278
317
|
|
|
279
|
-
export { type CacheValueSerializer, type CreateRedisStringsHandlerOptions, RedisStringsHandler, bufferAndMapReplacer, bufferAndMapReviver, CachedHandler as default, getRedisCacheComponentsHandler, jsonCacheValueSerializer, redisCacheHandler };
|
|
318
|
+
export { type CacheValueSerializer, type CreateRedisStringsHandlerOptions, RedisStringsHandler, type ResolveCacheEntryTtlContext, type ResolveCacheEntryTtlData, type ResolveCacheEntryTtlOptions, bufferAndMapReplacer, bufferAndMapReviver, CachedHandler as default, getRedisCacheComponentsHandler, jsonCacheValueSerializer, redisCacheHandler, resolveCacheEntryTtlSeconds, shouldDeferRedisConnection };
|
package/dist/index.d.ts
CHANGED
|
@@ -221,10 +221,12 @@ declare class RedisStringsHandler {
|
|
|
221
221
|
private estimateExpireAge;
|
|
222
222
|
private killContainerOnErrorThreshold;
|
|
223
223
|
private valueSerializer;
|
|
224
|
+
private redisConnectionDeferred;
|
|
224
225
|
constructor({ redisUrl, database, keyPrefix, sharedTagsKey, getTimeoutMs, revalidateTagQuerySize, avgResyncIntervalMs, redisGetDeduplication, inMemoryCachingTime, defaultStaleAge, estimateExpireAge, killContainerOnErrorThreshold, socketOptions, clientOptions, valueSerializer, }: CreateRedisStringsHandlerOptions);
|
|
225
226
|
resetRequestCache(): void;
|
|
226
227
|
private clientReadyCalls;
|
|
227
228
|
private assertClientIsReady;
|
|
229
|
+
private isClientUnavailable;
|
|
228
230
|
get(key: string, ctx: GetContext): Promise<CacheEntry | null>;
|
|
229
231
|
set(key: string, data: SetCacheValue, ctx: {
|
|
230
232
|
isRoutePPREnabled: boolean;
|
|
@@ -253,6 +255,43 @@ declare class CachedHandler {
|
|
|
253
255
|
declare function bufferAndMapReviver(_: string, value: any): any;
|
|
254
256
|
declare function bufferAndMapReplacer(_: string, value: any): any;
|
|
255
257
|
|
|
258
|
+
type ResolveCacheEntryTtlContext = {
|
|
259
|
+
revalidate?: number | false;
|
|
260
|
+
cacheControl?: {
|
|
261
|
+
revalidate?: number | false;
|
|
262
|
+
expire?: number | undefined;
|
|
263
|
+
};
|
|
264
|
+
};
|
|
265
|
+
type ResolveCacheEntryTtlData = {
|
|
266
|
+
kind?: string;
|
|
267
|
+
revalidate?: number | false;
|
|
268
|
+
} | null;
|
|
269
|
+
type ResolveCacheEntryTtlOptions = {
|
|
270
|
+
estimateExpireAge: (staleAge: number) => number;
|
|
271
|
+
defaultStaleAge: number;
|
|
272
|
+
};
|
|
273
|
+
/**
|
|
274
|
+
* Resolves the Redis TTL (seconds) for an ISR / incremental-cache entry.
|
|
275
|
+
*
|
|
276
|
+
* Official Next.js semantics (cache-handler-redis example + self-hosting docs):
|
|
277
|
+
* - Key TTL on `cacheControl.expire`, never on `revalidate` alone.
|
|
278
|
+
* - Past `revalidate` an entry is only stale (SWR); evicting at that boundary
|
|
279
|
+
* would defeat background refresh.
|
|
280
|
+
* - When no finite `expire` is provided, fall back to `estimateExpireAge(revalidate)`
|
|
281
|
+
* for legacy Pages Router / pre-cacheLife callers that only pass `revalidate`.
|
|
282
|
+
* - When neither `expire` nor `revalidate` is available, return `undefined` (no TTL;
|
|
283
|
+
* rely on tag-based invalidation). This is intentional — not a missing
|
|
284
|
+
* `defaultStaleAge` fallback. `revalidate: false` is a separate branch above
|
|
285
|
+
* and is covered by unit + Pages Router integration tests (`/static-forever`).
|
|
286
|
+
*/
|
|
287
|
+
declare function resolveCacheEntryTtlSeconds(ctx: ResolveCacheEntryTtlContext, data: ResolveCacheEntryTtlData, options: ResolveCacheEntryTtlOptions): number | undefined;
|
|
288
|
+
|
|
289
|
+
/**
|
|
290
|
+
* Returns true during `next build` so handlers can skip opening Redis
|
|
291
|
+
* connections. Matches the official Next.js cache-handler-redis example.
|
|
292
|
+
*/
|
|
293
|
+
declare function shouldDeferRedisConnection(): boolean;
|
|
294
|
+
|
|
256
295
|
interface CacheComponentsEntry {
|
|
257
296
|
value: ReadableStream<Uint8Array>;
|
|
258
297
|
tags: string[];
|
|
@@ -276,4 +315,4 @@ type CreateCacheComponentsHandlerOptions = CreateRedisStringsHandlerOptions & {
|
|
|
276
315
|
declare function getRedisCacheComponentsHandler(options?: CreateCacheComponentsHandlerOptions): CacheComponentsHandler;
|
|
277
316
|
declare const redisCacheHandler: CacheComponentsHandler;
|
|
278
317
|
|
|
279
|
-
export { type CacheValueSerializer, type CreateRedisStringsHandlerOptions, RedisStringsHandler, bufferAndMapReplacer, bufferAndMapReviver, CachedHandler as default, getRedisCacheComponentsHandler, jsonCacheValueSerializer, redisCacheHandler };
|
|
318
|
+
export { type CacheValueSerializer, type CreateRedisStringsHandlerOptions, RedisStringsHandler, type ResolveCacheEntryTtlContext, type ResolveCacheEntryTtlData, type ResolveCacheEntryTtlOptions, bufferAndMapReplacer, bufferAndMapReviver, CachedHandler as default, getRedisCacheComponentsHandler, jsonCacheValueSerializer, redisCacheHandler, resolveCacheEntryTtlSeconds, shouldDeferRedisConnection };
|