From d5f8efdbecb148f8a99f3b5326c05cbbfbd114dd Mon Sep 17 00:00:00 2001 From: samcx Date: Fri, 19 Apr 2024 14:58:46 -0400 Subject: [PATCH 1/6] fix(fetch-cache): update logic for checking memory cache --- packages/next/src/server/lib/incremental-cache/fetch-cache.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/next/src/server/lib/incremental-cache/fetch-cache.ts b/packages/next/src/server/lib/incremental-cache/fetch-cache.ts index 134586d46fa05..0c36b728ec713 100644 --- a/packages/next/src/server/lib/incremental-cache/fetch-cache.ts +++ b/packages/next/src/server/lib/incremental-cache/fetch-cache.ts @@ -189,7 +189,7 @@ export default class FetchCache implements CacheHandler { // Get data from fetch cache. Also check if new tags have been // specified with the same cache key (fetch URL) - if (this.cacheEndpoint && (!data || !hasFetchKindAndMatchingTags)) { + if ((this.cacheEndpoint && !data) || !hasFetchKindAndMatchingTags) { try { const start = Date.now() const fetchParams: NextFetchCacheParams = { From 0a380b8ea4f2110f361fd4a97bf355ad66580138 Mon Sep 17 00:00:00 2001 From: samcx Date: Sat, 20 Apr 2024 00:34:33 -0400 Subject: [PATCH 2/6] fix(fetch-cache): fix typo --- packages/next/src/server/lib/incremental-cache/fetch-cache.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/next/src/server/lib/incremental-cache/fetch-cache.ts b/packages/next/src/server/lib/incremental-cache/fetch-cache.ts index 0c36b728ec713..83876964f1987 100644 --- a/packages/next/src/server/lib/incremental-cache/fetch-cache.ts +++ b/packages/next/src/server/lib/incremental-cache/fetch-cache.ts @@ -189,7 +189,7 @@ export default class FetchCache implements CacheHandler { // Get data from fetch cache. Also check if new tags have been // specified with the same cache key (fetch URL) - if ((this.cacheEndpoint && !data) || !hasFetchKindAndMatchingTags) { + if (this.cacheEndpoint && (!data || !hasFetchKindAndMatchingTags)) { try { const start = Date.now() const fetchParams: NextFetchCacheParams = { @@ -245,7 +245,7 @@ export default class FetchCache implements CacheHandler { cached.tags ??= [] for (const tag of tags ?? []) { if (!cached.tags.includes(tag)) { - cached.tag.push(tag) + cached.tags.push(tag) } } } From 53244ce3be9dcdc80e3cbcdc06510c01d5a5e4e5 Mon Sep 17 00:00:00 2001 From: samcx Date: Mon, 22 Apr 2024 14:35:11 -0400 Subject: [PATCH 3/6] fix(fetch-cache): add type to json response --- packages/next/src/server/lib/incremental-cache/fetch-cache.ts | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/packages/next/src/server/lib/incremental-cache/fetch-cache.ts b/packages/next/src/server/lib/incremental-cache/fetch-cache.ts index 83876964f1987..6f98b4fa7bdc6 100644 --- a/packages/next/src/server/lib/incremental-cache/fetch-cache.ts +++ b/packages/next/src/server/lib/incremental-cache/fetch-cache.ts @@ -1,6 +1,8 @@ import type { CacheHandler, CacheHandlerContext, CacheHandlerValue } from './' +import type { IncrementalCacheValue } from '../../response-cache' import LRUCache from 'next/dist/compiled/lru-cache' + import { CACHE_ONE_YEAR, NEXT_CACHE_SOFT_TAGS_HEADER, @@ -233,7 +235,7 @@ export default class FetchCache implements CacheHandler { throw new Error(`invalid response from cache ${res.status}`) } - const cached = await res.json() + const cached: IncrementalCacheValue = await res.json() if (!cached || cached.kind !== 'FETCH') { this.debug && console.log({ cached }) From cc9e714a70793a0bfea1b7297df0f08e12b02720 Mon Sep 17 00:00:00 2001 From: samcx Date: Mon, 22 Apr 2024 15:44:20 -0400 Subject: [PATCH 4/6] fix(fetch-cache): add zod validation --- .../lib/incremental-cache/fetch-cache.ts | 25 ++++++++++++++++--- 1 file changed, 22 insertions(+), 3 deletions(-) diff --git a/packages/next/src/server/lib/incremental-cache/fetch-cache.ts b/packages/next/src/server/lib/incremental-cache/fetch-cache.ts index 6f98b4fa7bdc6..2b13818089cb3 100644 --- a/packages/next/src/server/lib/incremental-cache/fetch-cache.ts +++ b/packages/next/src/server/lib/incremental-cache/fetch-cache.ts @@ -1,8 +1,14 @@ import type { CacheHandler, CacheHandlerContext, CacheHandlerValue } from './' -import type { IncrementalCacheValue } from '../../response-cache' +import type { + CachedFetchValue, + IncrementalCacheValue, +} from '../../response-cache' import LRUCache from 'next/dist/compiled/lru-cache' +import { z } from 'next/dist/compiled/zod' +import type zod from 'next/dist/compiled/zod' + import { CACHE_ONE_YEAR, NEXT_CACHE_SOFT_TAGS_HEADER, @@ -25,6 +31,18 @@ const CACHE_REVALIDATE_HEADER = 'x-vercel-revalidate' as const const CACHE_FETCH_URL_HEADER = 'x-vercel-cache-item-name' as const const CACHE_CONTROL_VALUE_HEADER = 'x-vercel-cache-control' as const +const zCachedFetchValue: zod.ZodType = z.object({ + kind: z.literal('FETCH'), + data: z.object({ + headers: z.record(z.string()), + body: z.string(), + url: z.string(), + status: z.number().optional(), + }), + tags: z.array(z.string()).optional(), + revalidate: z.number(), +}) + export default class FetchCache implements CacheHandler { private headers: Record private cacheEndpoint?: string @@ -236,10 +254,11 @@ export default class FetchCache implements CacheHandler { } const cached: IncrementalCacheValue = await res.json() + const cachedParsed = zCachedFetchValue.safeParse(cached) - if (!cached || cached.kind !== 'FETCH') { + if (!cached || !cachedParsed.success) { this.debug && console.log({ cached }) - throw new Error(`invalid cache value`) + throw new Error('invalid cache value') } // if new tags were specified, merge those tags to the existing tags From a5831b1ab887174ee8bc09ab401a1660c0c112a7 Mon Sep 17 00:00:00 2001 From: samcx Date: Mon, 22 Apr 2024 16:18:06 -0400 Subject: [PATCH 5/6] fix(fetch-cache): remove unecessary !cached check --- packages/next/src/server/lib/incremental-cache/fetch-cache.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/next/src/server/lib/incremental-cache/fetch-cache.ts b/packages/next/src/server/lib/incremental-cache/fetch-cache.ts index 2b13818089cb3..f00da82b107fe 100644 --- a/packages/next/src/server/lib/incremental-cache/fetch-cache.ts +++ b/packages/next/src/server/lib/incremental-cache/fetch-cache.ts @@ -256,7 +256,7 @@ export default class FetchCache implements CacheHandler { const cached: IncrementalCacheValue = await res.json() const cachedParsed = zCachedFetchValue.safeParse(cached) - if (!cached || !cachedParsed.success) { + if (!cachedParsed.success) { this.debug && console.log({ cached }) throw new Error('invalid cache value') } From 8f72817b4e780d43d5a8dfbc822dcea70b060d97 Mon Sep 17 00:00:00 2001 From: samcx Date: Mon, 22 Apr 2024 17:12:24 -0400 Subject: [PATCH 6/6] fix(fetch-cache): add suggestions --- .../src/server/lib/incremental-cache/fetch-cache.ts | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/packages/next/src/server/lib/incremental-cache/fetch-cache.ts b/packages/next/src/server/lib/incremental-cache/fetch-cache.ts index f00da82b107fe..9e8467f3176e1 100644 --- a/packages/next/src/server/lib/incremental-cache/fetch-cache.ts +++ b/packages/next/src/server/lib/incremental-cache/fetch-cache.ts @@ -253,14 +253,16 @@ export default class FetchCache implements CacheHandler { throw new Error(`invalid response from cache ${res.status}`) } - const cached: IncrementalCacheValue = await res.json() - const cachedParsed = zCachedFetchValue.safeParse(cached) + const json: IncrementalCacheValue = await res.json() + const parsed = zCachedFetchValue.safeParse(json) - if (!cachedParsed.success) { - this.debug && console.log({ cached }) + if (!parsed.success) { + this.debug && console.log({ json }) throw new Error('invalid cache value') } + const { data: cached } = parsed + // if new tags were specified, merge those tags to the existing tags if (cached.kind === 'FETCH') { cached.tags ??= []