Skip to content

Commit cff9f73

Browse files
committed
refactor: modulurize blobs storage abstractions
1 parent 42977ed commit cff9f73

12 files changed

+236
-209
lines changed

.eslintrc.cjs

+8
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,14 @@ module.exports = {
7272
message: 'Please use `getTracer()` from `./handlers/tracer.cjs` instead',
7373
},
7474
],
75+
patterns: [
76+
{
77+
// only */storage/storage.cjs is allowed to be imported
78+
// rest are implementation details that should not be used directly
79+
group: ['*/storage/*', '!*/storage/storage.cjs'],
80+
message: 'Import public `[...]/storage/storage.cjs` module instead.',
81+
},
82+
],
7583
},
7684
],
7785
},

src/run/config.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ import { join, resolve } from 'node:path'
55
import type { NextConfigComplete } from 'next/dist/server/config-shared.js'
66

77
import { PLUGIN_DIR, RUN_CONFIG } from './constants.js'
8-
import { setInMemoryCacheMaxSizeFromNextConfig } from './regional-blob-store.cjs'
8+
import { setInMemoryCacheMaxSizeFromNextConfig } from './storage/storage.cjs'
99

1010
/**
1111
* Get Next.js config from the build output

src/run/handlers/cache.cts

+1-1
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ import {
2525
import {
2626
getMemoizedKeyValueStoreBackedByRegionalBlobStore,
2727
MemoizedKeyValueStoreBackedByRegionalBlobStore,
28-
} from '../regional-blob-store.cjs'
28+
} from '../storage/storage.cjs'
2929

3030
import { getLogger, getRequestContext } from './request-context.cjs'
3131
import { getTracer, recordWarning } from './tracer.cjs'

src/run/handlers/server.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -13,8 +13,8 @@ import {
1313
setCacheTagsHeaders,
1414
setVaryHeaders,
1515
} from '../headers.js'
16-
import { setFetchBeforeNextPatchedIt } from '../regional-blob-store.cjs'
1716
import { nextResponseProxy } from '../revalidate.js'
17+
import { setFetchBeforeNextPatchedIt } from '../storage/storage.cjs'
1818

1919
import { getLogger, type RequestContext } from './request-context.cjs'
2020
import { getTracer } from './tracer.cjs'

src/run/headers.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ import type { NetlifyCachedRouteValue, NetlifyCacheHandlerValue } from '../share
55

66
import { getLogger, RequestContext } from './handlers/request-context.cjs'
77
import { recordWarning } from './handlers/tracer.cjs'
8-
import { getMemoizedKeyValueStoreBackedByRegionalBlobStore } from './regional-blob-store.cjs'
8+
import { getMemoizedKeyValueStoreBackedByRegionalBlobStore } from './storage/storage.cjs'
99

1010
const ALL_VARIATIONS = Symbol.for('ALL_VARIATIONS')
1111
interface NetlifyVaryValues {

src/run/next.cts

+1-1
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ import { HtmlBlob } from '../shared/cache-types.cjs'
88

99
import { getRequestContext } from './handlers/request-context.cjs'
1010
import { getTracer } from './handlers/tracer.cjs'
11-
import { getMemoizedKeyValueStoreBackedByRegionalBlobStore } from './regional-blob-store.cjs'
11+
import { getMemoizedKeyValueStoreBackedByRegionalBlobStore } from './storage/storage.cjs'
1212

1313
// https://github.com/vercel/next.js/pull/68193/files#diff-37243d614f1f5d3f7ea50bbf2af263f6b1a9a4f70e84427977781e07b02f57f1R49
1414
// This import resulted in importing unbundled React which depending if NODE_ENV is `production` or not would use

src/run/regional-blob-store.cts

-198
This file was deleted.
+62
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
import { getDeployStore, GetWithMetadataOptions, Store } from '@netlify/blobs'
2+
3+
const FETCH_BEFORE_NEXT_PATCHED_IT = Symbol.for('nf-not-patched-fetch')
4+
const extendedGlobalThis = globalThis as typeof globalThis & {
5+
[FETCH_BEFORE_NEXT_PATCHED_IT]?: typeof globalThis.fetch
6+
}
7+
8+
/**
9+
* Attempt to extract original fetch in case it was patched by Next.js already
10+
*
11+
* @see github.com/vercel/next.js/blob/fa214c74c1d8023098c0e94e57f917ef9f1afd1a/packages/next/src/server/lib/patch-fetch.ts#L986
12+
*/
13+
function attemptToGetOriginalFetch(
14+
fetch: typeof globalThis.fetch & {
15+
_nextOriginalFetch?: typeof globalThis.fetch
16+
},
17+
) {
18+
return fetch._nextOriginalFetch ?? fetch
19+
}
20+
21+
function forceOptOutOfUsingDataCache(fetch: typeof globalThis.fetch): typeof globalThis.fetch {
22+
return (input, init) => {
23+
return fetch(input, {
24+
...init,
25+
next: {
26+
...init?.next,
27+
// setting next.internal = true should prevent from trying to use data cache
28+
// https://github.com/vercel/next.js/blob/fa214c74c1d8023098c0e94e57f917ef9f1afd1a/packages/next/src/server/lib/patch-fetch.ts#L174
29+
// https://github.com/vercel/next.js/blob/fa214c74c1d8023098c0e94e57f917ef9f1afd1a/packages/next/src/server/lib/patch-fetch.ts#L210-L213
30+
// this is last line of defense in case we didn't manage to get unpatched fetch that will not affect
31+
// fetch if it's unpatched so it should be safe to apply always if we aren't sure if we use patched fetch
32+
33+
// @ts-expect-error - this is an internal field that Next.js doesn't add to its global
34+
// type overrides for RequestInit type (like `next.revalidate` or `next.tags`)
35+
internal: true,
36+
},
37+
})
38+
}
39+
}
40+
41+
export const setFetchBeforeNextPatchedIt = (fetch: typeof globalThis.fetch) => {
42+
// we store in globalThis in case we have multiple copies of this module
43+
// just as precaution
44+
45+
extendedGlobalThis[FETCH_BEFORE_NEXT_PATCHED_IT] = forceOptOutOfUsingDataCache(
46+
attemptToGetOriginalFetch(fetch),
47+
)
48+
}
49+
50+
const fetchBeforeNextPatchedItFallback = forceOptOutOfUsingDataCache(
51+
attemptToGetOriginalFetch(globalThis.fetch),
52+
)
53+
const getFetchBeforeNextPatchedIt = () =>
54+
extendedGlobalThis[FETCH_BEFORE_NEXT_PATCHED_IT] ?? fetchBeforeNextPatchedItFallback
55+
56+
export const getRegionalBlobStore = (args: GetWithMetadataOptions = {}): Store => {
57+
return getDeployStore({
58+
...args,
59+
fetch: getFetchBeforeNextPatchedIt(),
60+
region: process.env.USE_REGIONAL_BLOBS?.toUpperCase() === 'TRUE' ? undefined : 'us-east-2',
61+
})
62+
}

0 commit comments

Comments
 (0)