@trieb.work/nextjs-turbo-redis-cache 1.15.1 → 1.16.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 (31) hide show
  1. package/.github/workflows/ci.yml +45 -0
  2. package/.github/workflows/release.yml +9 -1
  3. package/CHANGELOG.md +28 -0
  4. package/README.md +13 -2
  5. package/dist/index.d.mts +71 -45
  6. package/dist/index.d.ts +71 -45
  7. package/dist/index.js +45 -8
  8. package/dist/index.js.map +1 -1
  9. package/dist/index.mjs +45 -8
  10. package/dist/index.mjs.map +1 -1
  11. package/docs/index.html +7 -6
  12. package/package.json +2 -1
  13. package/src/CacheComponentsHandler.ts +35 -2
  14. package/src/RedisStringsHandler.ts +125 -66
  15. package/test/README.md +21 -6
  16. package/test/nextjs-test-projects/next-pages-16-2-6/README.md +16 -0
  17. package/test/nextjs-test-projects/next-pages-16-2-6/eslint.config.mjs +18 -0
  18. package/test/nextjs-test-projects/next-pages-16-2-6/next.config.ts +7 -0
  19. package/test/nextjs-test-projects/next-pages-16-2-6/package.json +26 -0
  20. package/test/nextjs-test-projects/next-pages-16-2-6/pnpm-lock.yaml +3896 -0
  21. package/test/nextjs-test-projects/next-pages-16-2-6/src/pages/api/revalidate.ts +24 -0
  22. package/test/nextjs-test-projects/next-pages-16-2-6/src/pages/index.tsx +11 -0
  23. package/test/nextjs-test-projects/next-pages-16-2-6/src/pages/isr/[slug].tsx +49 -0
  24. package/test/nextjs-test-projects/next-pages-16-2-6/src/pages/static-forever.tsx +20 -0
  25. package/test/nextjs-test-projects/next-pages-16-2-6/tsconfig.json +34 -0
  26. package/test/vitest/integration/cache-components/redis-kill-reconnect.test.ts +6 -0
  27. package/test/vitest/integration/cache-components/scripts/redis-kill-reconnect.ts +3 -5
  28. package/test/vitest/integration/pages-router.integration.test.ts +420 -0
  29. package/test/vitest/unit/index.test.ts +49 -2
  30. package/test/vitest/unit/pages-router-kinds.test.ts +292 -0
  31. package/test/vitest/unit/reconnect-socket-already-opened.test.ts +56 -0
package/dist/index.mjs CHANGED
@@ -524,6 +524,19 @@ if (process.env.DEBUG_CACHE_HANDLER) {
524
524
  }
525
525
  var NEXT_CACHE_IMPLICIT_TAG_ID = "_N_T_";
526
526
  var REVALIDATED_TAGS_KEY = "__revalidated_tags__";
527
+ var SUPPORTED_GET_KINDS = [
528
+ "APP_ROUTE",
529
+ "APP_PAGE",
530
+ "PAGES",
531
+ "FETCH"
532
+ ];
533
+ var SUPPORTED_SET_KINDS = [
534
+ "APP_ROUTE",
535
+ "APP_PAGE",
536
+ "PAGES",
537
+ "REDIRECT",
538
+ "FETCH"
539
+ ];
527
540
  var killContainerOnErrorCount = 0;
528
541
  var RedisStringsHandler = class {
529
542
  constructor({
@@ -689,12 +702,12 @@ var RedisStringsHandler = class {
689
702
  }
690
703
  async get(key, ctx) {
691
704
  try {
692
- if (ctx.kind !== "APP_ROUTE" && ctx.kind !== "APP_PAGE" && ctx.kind !== "FETCH") {
705
+ if (!SUPPORTED_GET_KINDS.includes(ctx.kind)) {
693
706
  console.warn(
694
707
  "RedisStringsHandler.get() called with",
695
708
  key,
696
709
  ctx,
697
- " this cache handler is only designed and tested for kind APP_ROUTE and APP_PAGE and not for kind ",
710
+ `this cache handler is only designed and tested for kinds ${SUPPORTED_GET_KINDS.join(", ")} and not for kind`,
698
711
  ctx?.kind
699
712
  );
700
713
  }
@@ -749,7 +762,7 @@ var RedisStringsHandler = class {
749
762
  "cacheEntry is mall formed (missing tags)"
750
763
  );
751
764
  }
752
- if (!cacheEntry?.value) {
765
+ if (cacheEntry?.value === void 0) {
753
766
  console.warn(
754
767
  "RedisStringsHandler.get() called with",
755
768
  key,
@@ -822,21 +835,27 @@ var RedisStringsHandler = class {
822
835
  }
823
836
  async set(key, data, ctx) {
824
837
  try {
825
- if (data.kind !== "APP_ROUTE" && data.kind !== "APP_PAGE" && data.kind !== "FETCH") {
838
+ if (data !== null && !SUPPORTED_SET_KINDS.includes(data.kind)) {
826
839
  console.warn(
827
840
  "RedisStringsHandler.set() called with",
828
841
  key,
829
842
  ctx,
830
843
  data,
831
- " this cache handler is only designed and tested for kind APP_ROUTE and APP_PAGE and not for kind ",
844
+ `this cache handler is only designed and tested for kinds ${SUPPORTED_SET_KINDS.join(", ")} and not for kind`,
832
845
  data?.kind
833
846
  );
834
847
  }
835
848
  await this.assertClientIsReady();
836
- if (data.kind === "APP_PAGE" || data.kind === "APP_ROUTE") {
849
+ if (data?.kind === "APP_PAGE" || data?.kind === "APP_ROUTE") {
837
850
  const tags = data.headers["x-next-cache-tags"]?.split(",");
838
851
  ctx.tags = [...ctx.tags || [], ...tags || []];
839
852
  }
853
+ if (data === null || data.kind === "PAGES" || data.kind === "REDIRECT") {
854
+ const implicitTag = NEXT_CACHE_IMPLICIT_TAG_ID + key;
855
+ if (!ctx.tags?.includes(implicitTag)) {
856
+ ctx.tags = [...ctx.tags || [], implicitTag];
857
+ }
858
+ }
840
859
  const cacheEntry = {
841
860
  lastModified: Date.now(),
842
861
  tags: ctx?.tags || [],
@@ -851,7 +870,10 @@ var RedisStringsHandler = class {
851
870
  }
852
871
  const revalidate = (
853
872
  // For fetch requests in newest versions, the revalidate context property is never used, and instead the revalidate property of the passed-in data is used
854
- data.kind === "FETCH" && data.revalidate || ctx.revalidate || ctx.cacheControl?.revalidate || data?.revalidate
873
+ data?.kind === "FETCH" && data.revalidate || ctx.revalidate || ctx.cacheControl?.revalidate || // Legacy fallback: older Next.js versions attached `revalidate` directly
874
+ // to the data payload. FETCH is already handled above, so this only
875
+ // matters for those older, non-discriminated shapes.
876
+ data?.revalidate
855
877
  );
856
878
  const expireAt = revalidate && Number.isSafeInteger(revalidate) && revalidate > 0 ? this.estimateExpireAge(revalidate) : this.estimateExpireAge(this.defaultStaleAge);
857
879
  const setOperation = redisErrorHandler(
@@ -1404,7 +1426,22 @@ function getRedisCacheComponentsHandler(options = {}) {
1404
1426
  }
1405
1427
  return singletonHandler;
1406
1428
  }
1407
- var redisCacheHandler = getRedisCacheComponentsHandler();
1429
+ var resolvedHandler;
1430
+ var redisCacheHandler = new Proxy(
1431
+ {},
1432
+ {
1433
+ get(_target, prop) {
1434
+ if (!resolvedHandler) {
1435
+ resolvedHandler = getRedisCacheComponentsHandler();
1436
+ }
1437
+ const value = resolvedHandler[prop];
1438
+ return typeof value === "function" ? value.bind(resolvedHandler) : value;
1439
+ },
1440
+ has(_target, prop) {
1441
+ return prop in RedisCacheComponentsHandler.prototype;
1442
+ }
1443
+ }
1444
+ );
1408
1445
 
1409
1446
  // src/index.ts
1410
1447
  var index_default = CachedHandler;