@gigadrive/network-config 3.4.11 → 3.4.12
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/dist/index.js +1 -0
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +1 -0
- package/dist/index.mjs.map +1 -1
- package/dist/nextjs-cache-components-handler.js +16 -4
- package/dist/nextjs-cache-components-handler.js.map +1 -1
- package/dist/nextjs-cache-components-handler.mjs +16 -4
- package/dist/nextjs-cache-components-handler.mjs.map +1 -1
- package/dist/nextjs-cache-handler.d.mts +1 -0
- package/dist/nextjs-cache-handler.d.ts +1 -0
- package/dist/nextjs-cache-handler.js +17 -9
- package/dist/nextjs-cache-handler.js.map +1 -1
- package/dist/nextjs-cache-handler.mjs +17 -9
- package/dist/nextjs-cache-handler.mjs.map +1 -1
- package/package.json +1 -1
|
@@ -147,6 +147,7 @@ var isSerializedCacheComponentEntry = (value) => {
|
|
|
147
147
|
return entry.value instanceof Uint8Array && Array.isArray(entry.tags) && entry.tags.every((tag) => typeof tag === "string") && typeof entry.stale === "number" && typeof entry.timestamp === "number" && typeof entry.expire === "number" && typeof entry.revalidate === "number";
|
|
148
148
|
};
|
|
149
149
|
var pendingWrites = /* @__PURE__ */ new Map();
|
|
150
|
+
var buildEntries = /* @__PURE__ */ new Map();
|
|
150
151
|
var streamToBytes = async (stream) => {
|
|
151
152
|
const chunks = [];
|
|
152
153
|
let size = 0;
|
|
@@ -168,9 +169,9 @@ var streamToBytes = async (stream) => {
|
|
|
168
169
|
var cacheHandler = {
|
|
169
170
|
async get(cacheKey, softTags) {
|
|
170
171
|
await pendingWrites.get(cacheKey);
|
|
171
|
-
const value = await readRuntimeCache("component", cacheKey);
|
|
172
|
+
const value = process.env.GIGADRIVE_NEXT_BUILD === "1" ? buildEntries.get(cacheKey) : await readRuntimeCache("component", cacheKey);
|
|
172
173
|
if (!isSerializedCacheComponentEntry(value)) return void 0;
|
|
173
|
-
const tagState = await getRuntimeCacheTagState("component", [.../* @__PURE__ */ new Set([...value.tags, ...softTags])]);
|
|
174
|
+
const tagState = process.env.GIGADRIVE_NEXT_BUILD === "1" ? { stale: 0, expired: 0 } : await getRuntimeCacheTagState("component", [.../* @__PURE__ */ new Set([...value.tags, ...softTags])]);
|
|
174
175
|
if (tagState.expired > value.timestamp) return void 0;
|
|
175
176
|
return {
|
|
176
177
|
...value,
|
|
@@ -187,7 +188,12 @@ var cacheHandler = {
|
|
|
187
188
|
const write = (async () => {
|
|
188
189
|
const entry = await pendingEntry;
|
|
189
190
|
const value = await streamToBytes(entry.value);
|
|
190
|
-
|
|
191
|
+
const serializedEntry = { ...entry, value };
|
|
192
|
+
if (process.env.GIGADRIVE_NEXT_BUILD === "1") {
|
|
193
|
+
buildEntries.set(cacheKey, serializedEntry);
|
|
194
|
+
} else {
|
|
195
|
+
await writeRuntimeCache("component", cacheKey, serializedEntry, entry.tags);
|
|
196
|
+
}
|
|
191
197
|
})();
|
|
192
198
|
pendingWrites.set(cacheKey, write);
|
|
193
199
|
try {
|
|
@@ -201,7 +207,13 @@ var cacheHandler = {
|
|
|
201
207
|
getExpiration() {
|
|
202
208
|
return Promise.resolve(Infinity);
|
|
203
209
|
},
|
|
204
|
-
updateTags(tags, durations) {
|
|
210
|
+
async updateTags(tags, durations) {
|
|
211
|
+
if (process.env.GIGADRIVE_NEXT_BUILD === "1") {
|
|
212
|
+
for (const [key, entry] of buildEntries) {
|
|
213
|
+
if (entry.tags.some((tag) => tags.includes(tag))) buildEntries.delete(key);
|
|
214
|
+
}
|
|
215
|
+
return;
|
|
216
|
+
}
|
|
205
217
|
return revalidateRuntimeCacheTags("component", tags, durations);
|
|
206
218
|
}
|
|
207
219
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/nextjs-cache-components-handler.ts","../src/nextjs-runtime-cache-client.ts"],"sourcesContent":["import {\n getRuntimeCacheTagState,\n readRuntimeCache,\n revalidateRuntimeCacheTags,\n writeRuntimeCache,\n} from './nextjs-runtime-cache-client';\n\ninterface CacheComponentEntry {\n value: ReadableStream<Uint8Array>;\n tags: string[];\n stale: number;\n timestamp: number;\n expire: number;\n revalidate: number;\n}\n\ninterface SerializedCacheComponentEntry extends Omit<CacheComponentEntry, 'value'> {\n value: Uint8Array;\n}\n\nconst isSerializedCacheComponentEntry = (value: unknown): value is SerializedCacheComponentEntry => {\n if (typeof value !== 'object' || value === null) return false;\n const entry = value as Partial<SerializedCacheComponentEntry>;\n return (\n entry.value instanceof Uint8Array &&\n Array.isArray(entry.tags) &&\n entry.tags.every((tag) => typeof tag === 'string') &&\n typeof entry.stale === 'number' &&\n typeof entry.timestamp === 'number' &&\n typeof entry.expire === 'number' &&\n typeof entry.revalidate === 'number'\n );\n};\n\nconst pendingWrites = new Map<string, Promise<void>>();\n\nconst streamToBytes = async (stream: ReadableStream<Uint8Array>): Promise<Uint8Array> => {\n const chunks: Uint8Array[] = [];\n let size = 0;\n const reader = stream.getReader();\n while (true) {\n const result = await reader.read();\n if (result.done) break;\n chunks.push(result.value);\n size += result.value.byteLength;\n }\n const bytes = new Uint8Array(size);\n let offset = 0;\n for (const chunk of chunks) {\n bytes.set(chunk, offset);\n offset += chunk.byteLength;\n }\n return bytes;\n};\n\n/** Shared Network cache handler for Next.js Cache Components and `use cache`. */\nconst cacheHandler = {\n async get(cacheKey: string, softTags: string[]): Promise<CacheComponentEntry | undefined> {\n await pendingWrites.get(cacheKey);\n const value = await readRuntimeCache('component', cacheKey);\n if (!isSerializedCacheComponentEntry(value)) return undefined;\n const tagState = await getRuntimeCacheTagState('component', [...new Set([...value.tags, ...softTags])]);\n if (tagState.expired > value.timestamp) return undefined;\n return {\n ...value,\n ...(tagState.stale > value.timestamp ? { revalidate: -1 } : {}),\n value: new ReadableStream<Uint8Array>({\n start(controller) {\n controller.enqueue(value.value);\n controller.close();\n },\n }),\n };\n },\n\n async set(cacheKey: string, pendingEntry: Promise<CacheComponentEntry>): Promise<void> {\n const write = (async () => {\n const entry = await pendingEntry;\n const value = await streamToBytes(entry.value);\n await writeRuntimeCache('component', cacheKey, { ...entry, value }, entry.tags);\n })();\n pendingWrites.set(cacheKey, write);\n try {\n await write;\n } finally {\n if (pendingWrites.get(cacheKey) === write) pendingWrites.delete(cacheKey);\n }\n },\n\n async refreshTags(): Promise<void> {},\n\n getExpiration(): Promise<number> {\n return Promise.resolve(Infinity);\n },\n\n updateTags(tags: string[], durations?: { expire?: number }): Promise<void> {\n return revalidateRuntimeCacheTags('component', tags, durations);\n },\n};\n\nexport default cacheHandler;\n","interface RuntimeCacheEnvelope {\n value: unknown;\n}\n\ninterface AccessTokenResponse {\n access_token: string;\n expires_in?: number;\n}\n\nexport interface RuntimeCacheTagState {\n stale: number;\n expired: number;\n}\n\nlet cachedToken: { value: string; expiresAt: number } | undefined;\n\nconst apiBaseUrl = (): string => (process.env.GIGADRIVE_API_URL ?? 'https://api.gigadrive.network').replace(/\\/$/, '');\n\nconst encodeBinary = (value: unknown, seen = new WeakSet<object>()): unknown => {\n if (value instanceof Uint8Array) {\n return { __gigadriveType: 'bytes', value: Buffer.from(value).toString('base64') };\n }\n if (value instanceof ArrayBuffer) {\n return { __gigadriveType: 'bytes', value: Buffer.from(value).toString('base64') };\n }\n if (Array.isArray(value)) return value.map((item) => encodeBinary(item, seen));\n if (typeof value !== 'object' || value === null) return value;\n if (seen.has(value)) throw new Error('Next.js cache entry contains a circular value');\n seen.add(value);\n const result: Record<string, unknown> = {};\n for (const [key, item] of Object.entries(value)) result[key] = encodeBinary(item, seen);\n seen.delete(value);\n return result;\n};\n\nconst decodeBinary = (value: unknown): unknown => {\n if (Array.isArray(value)) return value.map(decodeBinary);\n if (typeof value !== 'object' || value === null) return value;\n const record = value as Record<string, unknown>;\n if (record.__gigadriveType === 'bytes' && typeof record.value === 'string')\n return Buffer.from(record.value, 'base64');\n return Object.fromEntries(Object.entries(record).map(([key, item]) => [key, decodeBinary(item)]));\n};\n\nconst getAccessToken = async (): Promise<string> => {\n if (cachedToken && cachedToken.expiresAt > Date.now() + 30_000) return cachedToken.value;\n const clientId = process.env.GIGADRIVE_CLIENT_ID;\n const clientSecret = process.env.GIGADRIVE_CLIENT_SECRET;\n if (!clientId || !clientSecret) throw new Error('Gigadrive workload credentials are unavailable');\n\n const response = await fetch(`${apiBaseUrl()}/oauth2/token`, {\n method: 'POST',\n headers: {\n authorization: `Basic ${Buffer.from(`${clientId}:${clientSecret}`).toString('base64')}`,\n 'content-type': 'application/x-www-form-urlencoded',\n },\n body: 'grant_type=client_credentials',\n });\n if (!response.ok) throw new Error(`Gigadrive workload authentication failed with status ${response.status}`);\n const token = (await response.json()) as AccessTokenResponse;\n if (!token.access_token) throw new Error('Gigadrive workload authentication returned no access token');\n cachedToken = {\n value: token.access_token,\n expiresAt: Date.now() + Math.max(60, token.expires_in ?? 300) * 1000,\n };\n return token.access_token;\n};\n\nconst request = async (pathname: string, init: RequestInit, attempt = 0): Promise<Response> => {\n const token = await getAccessToken();\n try {\n const response = await fetch(`${apiBaseUrl()}${pathname}`, {\n ...init,\n headers: {\n authorization: `Bearer ${token}`,\n 'content-type': 'application/json',\n 'x-gigadrive-deployment-id': process.env.GIGADRIVE_DEPLOYMENT_ID ?? process.env.NEBULA_DEPLOYMENT_ID ?? '',\n 'x-gigadrive-build-id': process.env.NEXT_BUILD_ID ?? '',\n ...init.headers,\n },\n });\n if (response.status === 401 && attempt === 0) {\n cachedToken = undefined;\n return request(pathname, init, attempt + 1);\n }\n if (response.status >= 500 && attempt < 2) return request(pathname, init, attempt + 1);\n return response;\n } catch (error) {\n if (attempt < 2) return request(pathname, init, attempt + 1);\n throw error;\n }\n};\n\nconst cachePath = (kind: string, key: string): string =>\n `/internal/runtime-cache/v1/entries/${encodeURIComponent(kind)}/${encodeURIComponent(key)}`;\n\nexport const readRuntimeCache = async (kind: string, key: string): Promise<unknown | undefined> => {\n try {\n const response = await request(cachePath(kind, key), { method: 'GET' });\n if (response.status === 404) return undefined;\n if (!response.ok) return undefined;\n const envelope = (await response.json()) as RuntimeCacheEnvelope;\n return decodeBinary(envelope.value);\n } catch {\n return undefined;\n }\n};\n\nexport const writeRuntimeCache = async (\n kind: string,\n key: string,\n value: unknown,\n tags: readonly string[] = []\n): Promise<void> => {\n const response = await request(cachePath(kind, key), {\n method: 'PUT',\n body: JSON.stringify({ value: encodeBinary(value), tags }),\n });\n if (!response.ok) throw new Error(`Gigadrive runtime cache write failed with status ${response.status}`);\n};\n\nexport const revalidateRuntimeCacheTags = async (\n kind: string,\n tags: readonly string[],\n durations?: { expire?: number }\n): Promise<void> => {\n const response = await request('/internal/runtime-cache/v1/tags/revalidate', {\n method: 'POST',\n body: JSON.stringify({ kind, tags, durations }),\n });\n if (!response.ok) throw new Error(`Gigadrive runtime cache revalidation failed with status ${response.status}`);\n};\n\nexport const getRuntimeCacheTagExpiration = async (kind: string, tags: readonly string[]): Promise<number> => {\n try {\n const response = await request('/internal/runtime-cache/v1/tags/expiration', {\n method: 'POST',\n body: JSON.stringify({ kind, tags }),\n });\n if (!response.ok) return 0;\n const value = (await response.json()) as { expiration?: unknown };\n return typeof value.expiration === 'number' ? value.expiration : 0;\n } catch {\n return 0;\n }\n};\n\nexport const getRuntimeCacheTagState = async (kind: string, tags: readonly string[]): Promise<RuntimeCacheTagState> => {\n try {\n const response = await request('/internal/runtime-cache/v1/tags/state', {\n method: 'POST',\n body: JSON.stringify({ kind, tags }),\n });\n if (!response.ok) return { stale: 0, expired: 0 };\n const value = (await response.json()) as { stale?: unknown; expired?: unknown };\n return {\n stale: typeof value.stale === 'number' ? value.stale : 0,\n expired: typeof value.expired === 'number' ? value.expired : 0,\n };\n } catch {\n return { stale: 0, expired: 0 };\n }\n};\n\nexport const resetRuntimeCacheClientForTests = (): void => {\n cachedToken = undefined;\n};\n"],"mappings":"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","names":[]}
|
|
1
|
+
{"version":3,"sources":["../src/nextjs-cache-components-handler.ts","../src/nextjs-runtime-cache-client.ts"],"sourcesContent":["import {\n getRuntimeCacheTagState,\n readRuntimeCache,\n revalidateRuntimeCacheTags,\n writeRuntimeCache,\n} from './nextjs-runtime-cache-client';\n\ninterface CacheComponentEntry {\n value: ReadableStream<Uint8Array>;\n tags: string[];\n stale: number;\n timestamp: number;\n expire: number;\n revalidate: number;\n}\n\ninterface SerializedCacheComponentEntry extends Omit<CacheComponentEntry, 'value'> {\n value: Uint8Array;\n}\n\nconst isSerializedCacheComponentEntry = (value: unknown): value is SerializedCacheComponentEntry => {\n if (typeof value !== 'object' || value === null) return false;\n const entry = value as Partial<SerializedCacheComponentEntry>;\n return (\n entry.value instanceof Uint8Array &&\n Array.isArray(entry.tags) &&\n entry.tags.every((tag) => typeof tag === 'string') &&\n typeof entry.stale === 'number' &&\n typeof entry.timestamp === 'number' &&\n typeof entry.expire === 'number' &&\n typeof entry.revalidate === 'number'\n );\n};\n\nconst pendingWrites = new Map<string, Promise<void>>();\nconst buildEntries = new Map<string, SerializedCacheComponentEntry>();\n\nconst streamToBytes = async (stream: ReadableStream<Uint8Array>): Promise<Uint8Array> => {\n const chunks: Uint8Array[] = [];\n let size = 0;\n const reader = stream.getReader();\n while (true) {\n const result = await reader.read();\n if (result.done) break;\n chunks.push(result.value);\n size += result.value.byteLength;\n }\n const bytes = new Uint8Array(size);\n let offset = 0;\n for (const chunk of chunks) {\n bytes.set(chunk, offset);\n offset += chunk.byteLength;\n }\n return bytes;\n};\n\n/** Shared Network cache handler for Next.js Cache Components and `use cache`. */\nconst cacheHandler = {\n async get(cacheKey: string, softTags: string[]): Promise<CacheComponentEntry | undefined> {\n await pendingWrites.get(cacheKey);\n const value =\n process.env.GIGADRIVE_NEXT_BUILD === '1'\n ? buildEntries.get(cacheKey)\n : await readRuntimeCache('component', cacheKey);\n if (!isSerializedCacheComponentEntry(value)) return undefined;\n const tagState =\n process.env.GIGADRIVE_NEXT_BUILD === '1'\n ? { stale: 0, expired: 0 }\n : await getRuntimeCacheTagState('component', [...new Set([...value.tags, ...softTags])]);\n if (tagState.expired > value.timestamp) return undefined;\n return {\n ...value,\n ...(tagState.stale > value.timestamp ? { revalidate: -1 } : {}),\n value: new ReadableStream<Uint8Array>({\n start(controller) {\n controller.enqueue(value.value);\n controller.close();\n },\n }),\n };\n },\n\n async set(cacheKey: string, pendingEntry: Promise<CacheComponentEntry>): Promise<void> {\n const write = (async () => {\n const entry = await pendingEntry;\n const value = await streamToBytes(entry.value);\n const serializedEntry = { ...entry, value };\n if (process.env.GIGADRIVE_NEXT_BUILD === '1') {\n buildEntries.set(cacheKey, serializedEntry);\n } else {\n await writeRuntimeCache('component', cacheKey, serializedEntry, entry.tags);\n }\n })();\n pendingWrites.set(cacheKey, write);\n try {\n await write;\n } finally {\n if (pendingWrites.get(cacheKey) === write) pendingWrites.delete(cacheKey);\n }\n },\n\n async refreshTags(): Promise<void> {},\n\n getExpiration(): Promise<number> {\n return Promise.resolve(Infinity);\n },\n\n async updateTags(tags: string[], durations?: { expire?: number }): Promise<void> {\n if (process.env.GIGADRIVE_NEXT_BUILD === '1') {\n for (const [key, entry] of buildEntries) {\n if (entry.tags.some((tag) => tags.includes(tag))) buildEntries.delete(key);\n }\n return;\n }\n return revalidateRuntimeCacheTags('component', tags, durations);\n },\n};\n\nexport default cacheHandler;\n","interface RuntimeCacheEnvelope {\n value: unknown;\n}\n\ninterface AccessTokenResponse {\n access_token: string;\n expires_in?: number;\n}\n\nexport interface RuntimeCacheTagState {\n stale: number;\n expired: number;\n}\n\nlet cachedToken: { value: string; expiresAt: number } | undefined;\n\nconst apiBaseUrl = (): string => (process.env.GIGADRIVE_API_URL ?? 'https://api.gigadrive.network').replace(/\\/$/, '');\n\nconst encodeBinary = (value: unknown, seen = new WeakSet<object>()): unknown => {\n if (value instanceof Uint8Array) {\n return { __gigadriveType: 'bytes', value: Buffer.from(value).toString('base64') };\n }\n if (value instanceof ArrayBuffer) {\n return { __gigadriveType: 'bytes', value: Buffer.from(value).toString('base64') };\n }\n if (Array.isArray(value)) return value.map((item) => encodeBinary(item, seen));\n if (typeof value !== 'object' || value === null) return value;\n if (seen.has(value)) throw new Error('Next.js cache entry contains a circular value');\n seen.add(value);\n const result: Record<string, unknown> = {};\n for (const [key, item] of Object.entries(value)) result[key] = encodeBinary(item, seen);\n seen.delete(value);\n return result;\n};\n\nconst decodeBinary = (value: unknown): unknown => {\n if (Array.isArray(value)) return value.map(decodeBinary);\n if (typeof value !== 'object' || value === null) return value;\n const record = value as Record<string, unknown>;\n if (record.__gigadriveType === 'bytes' && typeof record.value === 'string')\n return Buffer.from(record.value, 'base64');\n return Object.fromEntries(Object.entries(record).map(([key, item]) => [key, decodeBinary(item)]));\n};\n\nconst getAccessToken = async (): Promise<string> => {\n if (cachedToken && cachedToken.expiresAt > Date.now() + 30_000) return cachedToken.value;\n const clientId = process.env.GIGADRIVE_CLIENT_ID;\n const clientSecret = process.env.GIGADRIVE_CLIENT_SECRET;\n if (!clientId || !clientSecret) throw new Error('Gigadrive workload credentials are unavailable');\n\n const response = await fetch(`${apiBaseUrl()}/oauth2/token`, {\n method: 'POST',\n headers: {\n authorization: `Basic ${Buffer.from(`${clientId}:${clientSecret}`).toString('base64')}`,\n 'content-type': 'application/x-www-form-urlencoded',\n },\n body: 'grant_type=client_credentials',\n });\n if (!response.ok) throw new Error(`Gigadrive workload authentication failed with status ${response.status}`);\n const token = (await response.json()) as AccessTokenResponse;\n if (!token.access_token) throw new Error('Gigadrive workload authentication returned no access token');\n cachedToken = {\n value: token.access_token,\n expiresAt: Date.now() + Math.max(60, token.expires_in ?? 300) * 1000,\n };\n return token.access_token;\n};\n\nconst request = async (pathname: string, init: RequestInit, attempt = 0): Promise<Response> => {\n const token = await getAccessToken();\n try {\n const response = await fetch(`${apiBaseUrl()}${pathname}`, {\n ...init,\n headers: {\n authorization: `Bearer ${token}`,\n 'content-type': 'application/json',\n 'x-gigadrive-deployment-id': process.env.GIGADRIVE_DEPLOYMENT_ID ?? process.env.NEBULA_DEPLOYMENT_ID ?? '',\n 'x-gigadrive-build-id': process.env.NEXT_BUILD_ID ?? '',\n ...init.headers,\n },\n });\n if (response.status === 401 && attempt === 0) {\n cachedToken = undefined;\n return request(pathname, init, attempt + 1);\n }\n if (response.status >= 500 && attempt < 2) return request(pathname, init, attempt + 1);\n return response;\n } catch (error) {\n if (attempt < 2) return request(pathname, init, attempt + 1);\n throw error;\n }\n};\n\nconst cachePath = (kind: string, key: string): string =>\n `/internal/runtime-cache/v1/entries/${encodeURIComponent(kind)}/${encodeURIComponent(key)}`;\n\nexport const readRuntimeCache = async (kind: string, key: string): Promise<unknown | undefined> => {\n try {\n const response = await request(cachePath(kind, key), { method: 'GET' });\n if (response.status === 404) return undefined;\n if (!response.ok) return undefined;\n const envelope = (await response.json()) as RuntimeCacheEnvelope;\n return decodeBinary(envelope.value);\n } catch {\n return undefined;\n }\n};\n\nexport const writeRuntimeCache = async (\n kind: string,\n key: string,\n value: unknown,\n tags: readonly string[] = []\n): Promise<void> => {\n const response = await request(cachePath(kind, key), {\n method: 'PUT',\n body: JSON.stringify({ value: encodeBinary(value), tags }),\n });\n if (!response.ok) throw new Error(`Gigadrive runtime cache write failed with status ${response.status}`);\n};\n\nexport const revalidateRuntimeCacheTags = async (\n kind: string,\n tags: readonly string[],\n durations?: { expire?: number }\n): Promise<void> => {\n const response = await request('/internal/runtime-cache/v1/tags/revalidate', {\n method: 'POST',\n body: JSON.stringify({ kind, tags, durations }),\n });\n if (!response.ok) throw new Error(`Gigadrive runtime cache revalidation failed with status ${response.status}`);\n};\n\nexport const getRuntimeCacheTagExpiration = async (kind: string, tags: readonly string[]): Promise<number> => {\n try {\n const response = await request('/internal/runtime-cache/v1/tags/expiration', {\n method: 'POST',\n body: JSON.stringify({ kind, tags }),\n });\n if (!response.ok) return 0;\n const value = (await response.json()) as { expiration?: unknown };\n return typeof value.expiration === 'number' ? value.expiration : 0;\n } catch {\n return 0;\n }\n};\n\nexport const getRuntimeCacheTagState = async (kind: string, tags: readonly string[]): Promise<RuntimeCacheTagState> => {\n try {\n const response = await request('/internal/runtime-cache/v1/tags/state', {\n method: 'POST',\n body: JSON.stringify({ kind, tags }),\n });\n if (!response.ok) return { stale: 0, expired: 0 };\n const value = (await response.json()) as { stale?: unknown; expired?: unknown };\n return {\n stale: typeof value.stale === 'number' ? value.stale : 0,\n expired: typeof value.expired === 'number' ? value.expired : 0,\n };\n } catch {\n return { stale: 0, expired: 0 };\n }\n};\n\nexport const resetRuntimeCacheClientForTests = (): void => {\n cachedToken = undefined;\n};\n"],"mappings":";;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;;;ACcA,IAAI;AAEJ,IAAM,aAAa,OAAe,QAAQ,IAAI,qBAAqB,iCAAiC,QAAQ,OAAO,EAAE;AAErH,IAAM,eAAe,CAAC,OAAgB,OAAO,oBAAI,QAAgB,MAAe;AAC9E,MAAI,iBAAiB,YAAY;AAC/B,WAAO,EAAE,iBAAiB,SAAS,OAAO,OAAO,KAAK,KAAK,EAAE,SAAS,QAAQ,EAAE;AAAA,EAClF;AACA,MAAI,iBAAiB,aAAa;AAChC,WAAO,EAAE,iBAAiB,SAAS,OAAO,OAAO,KAAK,KAAK,EAAE,SAAS,QAAQ,EAAE;AAAA,EAClF;AACA,MAAI,MAAM,QAAQ,KAAK,EAAG,QAAO,MAAM,IAAI,CAAC,SAAS,aAAa,MAAM,IAAI,CAAC;AAC7E,MAAI,OAAO,UAAU,YAAY,UAAU,KAAM,QAAO;AACxD,MAAI,KAAK,IAAI,KAAK,EAAG,OAAM,IAAI,MAAM,+CAA+C;AACpF,OAAK,IAAI,KAAK;AACd,QAAM,SAAkC,CAAC;AACzC,aAAW,CAAC,KAAK,IAAI,KAAK,OAAO,QAAQ,KAAK,EAAG,QAAO,GAAG,IAAI,aAAa,MAAM,IAAI;AACtF,OAAK,OAAO,KAAK;AACjB,SAAO;AACT;AAEA,IAAM,eAAe,CAAC,UAA4B;AAChD,MAAI,MAAM,QAAQ,KAAK,EAAG,QAAO,MAAM,IAAI,YAAY;AACvD,MAAI,OAAO,UAAU,YAAY,UAAU,KAAM,QAAO;AACxD,QAAM,SAAS;AACf,MAAI,OAAO,oBAAoB,WAAW,OAAO,OAAO,UAAU;AAChE,WAAO,OAAO,KAAK,OAAO,OAAO,QAAQ;AAC3C,SAAO,OAAO,YAAY,OAAO,QAAQ,MAAM,EAAE,IAAI,CAAC,CAAC,KAAK,IAAI,MAAM,CAAC,KAAK,aAAa,IAAI,CAAC,CAAC,CAAC;AAClG;AAEA,IAAM,iBAAiB,YAA6B;AAClD,MAAI,eAAe,YAAY,YAAY,KAAK,IAAI,IAAI,IAAQ,QAAO,YAAY;AACnF,QAAM,WAAW,QAAQ,IAAI;AAC7B,QAAM,eAAe,QAAQ,IAAI;AACjC,MAAI,CAAC,YAAY,CAAC,aAAc,OAAM,IAAI,MAAM,gDAAgD;AAEhG,QAAM,WAAW,MAAM,MAAM,GAAG,WAAW,CAAC,iBAAiB;AAAA,IAC3D,QAAQ;AAAA,IACR,SAAS;AAAA,MACP,eAAe,SAAS,OAAO,KAAK,GAAG,QAAQ,IAAI,YAAY,EAAE,EAAE,SAAS,QAAQ,CAAC;AAAA,MACrF,gBAAgB;AAAA,IAClB;AAAA,IACA,MAAM;AAAA,EACR,CAAC;AACD,MAAI,CAAC,SAAS,GAAI,OAAM,IAAI,MAAM,wDAAwD,SAAS,MAAM,EAAE;AAC3G,QAAM,QAAS,MAAM,SAAS,KAAK;AACnC,MAAI,CAAC,MAAM,aAAc,OAAM,IAAI,MAAM,4DAA4D;AACrG,gBAAc;AAAA,IACZ,OAAO,MAAM;AAAA,IACb,WAAW,KAAK,IAAI,IAAI,KAAK,IAAI,IAAI,MAAM,cAAc,GAAG,IAAI;AAAA,EAClE;AACA,SAAO,MAAM;AACf;AAEA,IAAM,UAAU,OAAO,UAAkB,MAAmB,UAAU,MAAyB;AAC7F,QAAM,QAAQ,MAAM,eAAe;AACnC,MAAI;AACF,UAAM,WAAW,MAAM,MAAM,GAAG,WAAW,CAAC,GAAG,QAAQ,IAAI;AAAA,MACzD,GAAG;AAAA,MACH,SAAS;AAAA,QACP,eAAe,UAAU,KAAK;AAAA,QAC9B,gBAAgB;AAAA,QAChB,6BAA6B,QAAQ,IAAI,2BAA2B,QAAQ,IAAI,wBAAwB;AAAA,QACxG,wBAAwB,QAAQ,IAAI,iBAAiB;AAAA,QACrD,GAAG,KAAK;AAAA,MACV;AAAA,IACF,CAAC;AACD,QAAI,SAAS,WAAW,OAAO,YAAY,GAAG;AAC5C,oBAAc;AACd,aAAO,QAAQ,UAAU,MAAM,UAAU,CAAC;AAAA,IAC5C;AACA,QAAI,SAAS,UAAU,OAAO,UAAU,EAAG,QAAO,QAAQ,UAAU,MAAM,UAAU,CAAC;AACrF,WAAO;AAAA,EACT,SAAS,OAAO;AACd,QAAI,UAAU,EAAG,QAAO,QAAQ,UAAU,MAAM,UAAU,CAAC;AAC3D,UAAM;AAAA,EACR;AACF;AAEA,IAAM,YAAY,CAAC,MAAc,QAC/B,sCAAsC,mBAAmB,IAAI,CAAC,IAAI,mBAAmB,GAAG,CAAC;AAEpF,IAAM,mBAAmB,OAAO,MAAc,QAA8C;AACjG,MAAI;AACF,UAAM,WAAW,MAAM,QAAQ,UAAU,MAAM,GAAG,GAAG,EAAE,QAAQ,MAAM,CAAC;AACtE,QAAI,SAAS,WAAW,IAAK,QAAO;AACpC,QAAI,CAAC,SAAS,GAAI,QAAO;AACzB,UAAM,WAAY,MAAM,SAAS,KAAK;AACtC,WAAO,aAAa,SAAS,KAAK;AAAA,EACpC,QAAQ;AACN,WAAO;AAAA,EACT;AACF;AAEO,IAAM,oBAAoB,OAC/B,MACA,KACA,OACA,OAA0B,CAAC,MACT;AAClB,QAAM,WAAW,MAAM,QAAQ,UAAU,MAAM,GAAG,GAAG;AAAA,IACnD,QAAQ;AAAA,IACR,MAAM,KAAK,UAAU,EAAE,OAAO,aAAa,KAAK,GAAG,KAAK,CAAC;AAAA,EAC3D,CAAC;AACD,MAAI,CAAC,SAAS,GAAI,OAAM,IAAI,MAAM,oDAAoD,SAAS,MAAM,EAAE;AACzG;AAEO,IAAM,6BAA6B,OACxC,MACA,MACA,cACkB;AAClB,QAAM,WAAW,MAAM,QAAQ,8CAA8C;AAAA,IAC3E,QAAQ;AAAA,IACR,MAAM,KAAK,UAAU,EAAE,MAAM,MAAM,UAAU,CAAC;AAAA,EAChD,CAAC;AACD,MAAI,CAAC,SAAS,GAAI,OAAM,IAAI,MAAM,2DAA2D,SAAS,MAAM,EAAE;AAChH;AAgBO,IAAM,0BAA0B,OAAO,MAAc,SAA2D;AACrH,MAAI;AACF,UAAM,WAAW,MAAM,QAAQ,yCAAyC;AAAA,MACtE,QAAQ;AAAA,MACR,MAAM,KAAK,UAAU,EAAE,MAAM,KAAK,CAAC;AAAA,IACrC,CAAC;AACD,QAAI,CAAC,SAAS,GAAI,QAAO,EAAE,OAAO,GAAG,SAAS,EAAE;AAChD,UAAM,QAAS,MAAM,SAAS,KAAK;AACnC,WAAO;AAAA,MACL,OAAO,OAAO,MAAM,UAAU,WAAW,MAAM,QAAQ;AAAA,MACvD,SAAS,OAAO,MAAM,YAAY,WAAW,MAAM,UAAU;AAAA,IAC/D;AAAA,EACF,QAAQ;AACN,WAAO,EAAE,OAAO,GAAG,SAAS,EAAE;AAAA,EAChC;AACF;;;AD9IA,IAAM,kCAAkC,CAAC,UAA2D;AAClG,MAAI,OAAO,UAAU,YAAY,UAAU,KAAM,QAAO;AACxD,QAAM,QAAQ;AACd,SACE,MAAM,iBAAiB,cACvB,MAAM,QAAQ,MAAM,IAAI,KACxB,MAAM,KAAK,MAAM,CAAC,QAAQ,OAAO,QAAQ,QAAQ,KACjD,OAAO,MAAM,UAAU,YACvB,OAAO,MAAM,cAAc,YAC3B,OAAO,MAAM,WAAW,YACxB,OAAO,MAAM,eAAe;AAEhC;AAEA,IAAM,gBAAgB,oBAAI,IAA2B;AACrD,IAAM,eAAe,oBAAI,IAA2C;AAEpE,IAAM,gBAAgB,OAAO,WAA4D;AACvF,QAAM,SAAuB,CAAC;AAC9B,MAAI,OAAO;AACX,QAAM,SAAS,OAAO,UAAU;AAChC,SAAO,MAAM;AACX,UAAM,SAAS,MAAM,OAAO,KAAK;AACjC,QAAI,OAAO,KAAM;AACjB,WAAO,KAAK,OAAO,KAAK;AACxB,YAAQ,OAAO,MAAM;AAAA,EACvB;AACA,QAAM,QAAQ,IAAI,WAAW,IAAI;AACjC,MAAI,SAAS;AACb,aAAW,SAAS,QAAQ;AAC1B,UAAM,IAAI,OAAO,MAAM;AACvB,cAAU,MAAM;AAAA,EAClB;AACA,SAAO;AACT;AAGA,IAAM,eAAe;AAAA,EACnB,MAAM,IAAI,UAAkB,UAA8D;AACxF,UAAM,cAAc,IAAI,QAAQ;AAChC,UAAM,QACJ,QAAQ,IAAI,yBAAyB,MACjC,aAAa,IAAI,QAAQ,IACzB,MAAM,iBAAiB,aAAa,QAAQ;AAClD,QAAI,CAAC,gCAAgC,KAAK,EAAG,QAAO;AACpD,UAAM,WACJ,QAAQ,IAAI,yBAAyB,MACjC,EAAE,OAAO,GAAG,SAAS,EAAE,IACvB,MAAM,wBAAwB,aAAa,CAAC,GAAG,oBAAI,IAAI,CAAC,GAAG,MAAM,MAAM,GAAG,QAAQ,CAAC,CAAC,CAAC;AAC3F,QAAI,SAAS,UAAU,MAAM,UAAW,QAAO;AAC/C,WAAO;AAAA,MACL,GAAG;AAAA,MACH,GAAI,SAAS,QAAQ,MAAM,YAAY,EAAE,YAAY,GAAG,IAAI,CAAC;AAAA,MAC7D,OAAO,IAAI,eAA2B;AAAA,QACpC,MAAM,YAAY;AAChB,qBAAW,QAAQ,MAAM,KAAK;AAC9B,qBAAW,MAAM;AAAA,QACnB;AAAA,MACF,CAAC;AAAA,IACH;AAAA,EACF;AAAA,EAEA,MAAM,IAAI,UAAkB,cAA2D;AACrF,UAAM,SAAS,YAAY;AACzB,YAAM,QAAQ,MAAM;AACpB,YAAM,QAAQ,MAAM,cAAc,MAAM,KAAK;AAC7C,YAAM,kBAAkB,EAAE,GAAG,OAAO,MAAM;AAC1C,UAAI,QAAQ,IAAI,yBAAyB,KAAK;AAC5C,qBAAa,IAAI,UAAU,eAAe;AAAA,MAC5C,OAAO;AACL,cAAM,kBAAkB,aAAa,UAAU,iBAAiB,MAAM,IAAI;AAAA,MAC5E;AAAA,IACF,GAAG;AACH,kBAAc,IAAI,UAAU,KAAK;AACjC,QAAI;AACF,YAAM;AAAA,IACR,UAAE;AACA,UAAI,cAAc,IAAI,QAAQ,MAAM,MAAO,eAAc,OAAO,QAAQ;AAAA,IAC1E;AAAA,EACF;AAAA,EAEA,MAAM,cAA6B;AAAA,EAAC;AAAA,EAEpC,gBAAiC;AAC/B,WAAO,QAAQ,QAAQ,QAAQ;AAAA,EACjC;AAAA,EAEA,MAAM,WAAW,MAAgB,WAAgD;AAC/E,QAAI,QAAQ,IAAI,yBAAyB,KAAK;AAC5C,iBAAW,CAAC,KAAK,KAAK,KAAK,cAAc;AACvC,YAAI,MAAM,KAAK,KAAK,CAAC,QAAQ,KAAK,SAAS,GAAG,CAAC,EAAG,cAAa,OAAO,GAAG;AAAA,MAC3E;AACA;AAAA,IACF;AACA,WAAO,2BAA2B,aAAa,MAAM,SAAS;AAAA,EAChE;AACF;AAEA,IAAO,0CAAQ;","names":[]}
|
|
@@ -121,6 +121,7 @@ var isSerializedCacheComponentEntry = (value) => {
|
|
|
121
121
|
return entry.value instanceof Uint8Array && Array.isArray(entry.tags) && entry.tags.every((tag) => typeof tag === "string") && typeof entry.stale === "number" && typeof entry.timestamp === "number" && typeof entry.expire === "number" && typeof entry.revalidate === "number";
|
|
122
122
|
};
|
|
123
123
|
var pendingWrites = /* @__PURE__ */ new Map();
|
|
124
|
+
var buildEntries = /* @__PURE__ */ new Map();
|
|
124
125
|
var streamToBytes = async (stream) => {
|
|
125
126
|
const chunks = [];
|
|
126
127
|
let size = 0;
|
|
@@ -142,9 +143,9 @@ var streamToBytes = async (stream) => {
|
|
|
142
143
|
var cacheHandler = {
|
|
143
144
|
async get(cacheKey, softTags) {
|
|
144
145
|
await pendingWrites.get(cacheKey);
|
|
145
|
-
const value = await readRuntimeCache("component", cacheKey);
|
|
146
|
+
const value = process.env.GIGADRIVE_NEXT_BUILD === "1" ? buildEntries.get(cacheKey) : await readRuntimeCache("component", cacheKey);
|
|
146
147
|
if (!isSerializedCacheComponentEntry(value)) return void 0;
|
|
147
|
-
const tagState = await getRuntimeCacheTagState("component", [.../* @__PURE__ */ new Set([...value.tags, ...softTags])]);
|
|
148
|
+
const tagState = process.env.GIGADRIVE_NEXT_BUILD === "1" ? { stale: 0, expired: 0 } : await getRuntimeCacheTagState("component", [.../* @__PURE__ */ new Set([...value.tags, ...softTags])]);
|
|
148
149
|
if (tagState.expired > value.timestamp) return void 0;
|
|
149
150
|
return {
|
|
150
151
|
...value,
|
|
@@ -161,7 +162,12 @@ var cacheHandler = {
|
|
|
161
162
|
const write = (async () => {
|
|
162
163
|
const entry = await pendingEntry;
|
|
163
164
|
const value = await streamToBytes(entry.value);
|
|
164
|
-
|
|
165
|
+
const serializedEntry = { ...entry, value };
|
|
166
|
+
if (process.env.GIGADRIVE_NEXT_BUILD === "1") {
|
|
167
|
+
buildEntries.set(cacheKey, serializedEntry);
|
|
168
|
+
} else {
|
|
169
|
+
await writeRuntimeCache("component", cacheKey, serializedEntry, entry.tags);
|
|
170
|
+
}
|
|
165
171
|
})();
|
|
166
172
|
pendingWrites.set(cacheKey, write);
|
|
167
173
|
try {
|
|
@@ -175,7 +181,13 @@ var cacheHandler = {
|
|
|
175
181
|
getExpiration() {
|
|
176
182
|
return Promise.resolve(Infinity);
|
|
177
183
|
},
|
|
178
|
-
updateTags(tags, durations) {
|
|
184
|
+
async updateTags(tags, durations) {
|
|
185
|
+
if (process.env.GIGADRIVE_NEXT_BUILD === "1") {
|
|
186
|
+
for (const [key, entry] of buildEntries) {
|
|
187
|
+
if (entry.tags.some((tag) => tags.includes(tag))) buildEntries.delete(key);
|
|
188
|
+
}
|
|
189
|
+
return;
|
|
190
|
+
}
|
|
179
191
|
return revalidateRuntimeCacheTags("component", tags, durations);
|
|
180
192
|
}
|
|
181
193
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/nextjs-runtime-cache-client.ts","../src/nextjs-cache-components-handler.ts"],"sourcesContent":["interface RuntimeCacheEnvelope {\n value: unknown;\n}\n\ninterface AccessTokenResponse {\n access_token: string;\n expires_in?: number;\n}\n\nexport interface RuntimeCacheTagState {\n stale: number;\n expired: number;\n}\n\nlet cachedToken: { value: string; expiresAt: number } | undefined;\n\nconst apiBaseUrl = (): string => (process.env.GIGADRIVE_API_URL ?? 'https://api.gigadrive.network').replace(/\\/$/, '');\n\nconst encodeBinary = (value: unknown, seen = new WeakSet<object>()): unknown => {\n if (value instanceof Uint8Array) {\n return { __gigadriveType: 'bytes', value: Buffer.from(value).toString('base64') };\n }\n if (value instanceof ArrayBuffer) {\n return { __gigadriveType: 'bytes', value: Buffer.from(value).toString('base64') };\n }\n if (Array.isArray(value)) return value.map((item) => encodeBinary(item, seen));\n if (typeof value !== 'object' || value === null) return value;\n if (seen.has(value)) throw new Error('Next.js cache entry contains a circular value');\n seen.add(value);\n const result: Record<string, unknown> = {};\n for (const [key, item] of Object.entries(value)) result[key] = encodeBinary(item, seen);\n seen.delete(value);\n return result;\n};\n\nconst decodeBinary = (value: unknown): unknown => {\n if (Array.isArray(value)) return value.map(decodeBinary);\n if (typeof value !== 'object' || value === null) return value;\n const record = value as Record<string, unknown>;\n if (record.__gigadriveType === 'bytes' && typeof record.value === 'string')\n return Buffer.from(record.value, 'base64');\n return Object.fromEntries(Object.entries(record).map(([key, item]) => [key, decodeBinary(item)]));\n};\n\nconst getAccessToken = async (): Promise<string> => {\n if (cachedToken && cachedToken.expiresAt > Date.now() + 30_000) return cachedToken.value;\n const clientId = process.env.GIGADRIVE_CLIENT_ID;\n const clientSecret = process.env.GIGADRIVE_CLIENT_SECRET;\n if (!clientId || !clientSecret) throw new Error('Gigadrive workload credentials are unavailable');\n\n const response = await fetch(`${apiBaseUrl()}/oauth2/token`, {\n method: 'POST',\n headers: {\n authorization: `Basic ${Buffer.from(`${clientId}:${clientSecret}`).toString('base64')}`,\n 'content-type': 'application/x-www-form-urlencoded',\n },\n body: 'grant_type=client_credentials',\n });\n if (!response.ok) throw new Error(`Gigadrive workload authentication failed with status ${response.status}`);\n const token = (await response.json()) as AccessTokenResponse;\n if (!token.access_token) throw new Error('Gigadrive workload authentication returned no access token');\n cachedToken = {\n value: token.access_token,\n expiresAt: Date.now() + Math.max(60, token.expires_in ?? 300) * 1000,\n };\n return token.access_token;\n};\n\nconst request = async (pathname: string, init: RequestInit, attempt = 0): Promise<Response> => {\n const token = await getAccessToken();\n try {\n const response = await fetch(`${apiBaseUrl()}${pathname}`, {\n ...init,\n headers: {\n authorization: `Bearer ${token}`,\n 'content-type': 'application/json',\n 'x-gigadrive-deployment-id': process.env.GIGADRIVE_DEPLOYMENT_ID ?? process.env.NEBULA_DEPLOYMENT_ID ?? '',\n 'x-gigadrive-build-id': process.env.NEXT_BUILD_ID ?? '',\n ...init.headers,\n },\n });\n if (response.status === 401 && attempt === 0) {\n cachedToken = undefined;\n return request(pathname, init, attempt + 1);\n }\n if (response.status >= 500 && attempt < 2) return request(pathname, init, attempt + 1);\n return response;\n } catch (error) {\n if (attempt < 2) return request(pathname, init, attempt + 1);\n throw error;\n }\n};\n\nconst cachePath = (kind: string, key: string): string =>\n `/internal/runtime-cache/v1/entries/${encodeURIComponent(kind)}/${encodeURIComponent(key)}`;\n\nexport const readRuntimeCache = async (kind: string, key: string): Promise<unknown | undefined> => {\n try {\n const response = await request(cachePath(kind, key), { method: 'GET' });\n if (response.status === 404) return undefined;\n if (!response.ok) return undefined;\n const envelope = (await response.json()) as RuntimeCacheEnvelope;\n return decodeBinary(envelope.value);\n } catch {\n return undefined;\n }\n};\n\nexport const writeRuntimeCache = async (\n kind: string,\n key: string,\n value: unknown,\n tags: readonly string[] = []\n): Promise<void> => {\n const response = await request(cachePath(kind, key), {\n method: 'PUT',\n body: JSON.stringify({ value: encodeBinary(value), tags }),\n });\n if (!response.ok) throw new Error(`Gigadrive runtime cache write failed with status ${response.status}`);\n};\n\nexport const revalidateRuntimeCacheTags = async (\n kind: string,\n tags: readonly string[],\n durations?: { expire?: number }\n): Promise<void> => {\n const response = await request('/internal/runtime-cache/v1/tags/revalidate', {\n method: 'POST',\n body: JSON.stringify({ kind, tags, durations }),\n });\n if (!response.ok) throw new Error(`Gigadrive runtime cache revalidation failed with status ${response.status}`);\n};\n\nexport const getRuntimeCacheTagExpiration = async (kind: string, tags: readonly string[]): Promise<number> => {\n try {\n const response = await request('/internal/runtime-cache/v1/tags/expiration', {\n method: 'POST',\n body: JSON.stringify({ kind, tags }),\n });\n if (!response.ok) return 0;\n const value = (await response.json()) as { expiration?: unknown };\n return typeof value.expiration === 'number' ? value.expiration : 0;\n } catch {\n return 0;\n }\n};\n\nexport const getRuntimeCacheTagState = async (kind: string, tags: readonly string[]): Promise<RuntimeCacheTagState> => {\n try {\n const response = await request('/internal/runtime-cache/v1/tags/state', {\n method: 'POST',\n body: JSON.stringify({ kind, tags }),\n });\n if (!response.ok) return { stale: 0, expired: 0 };\n const value = (await response.json()) as { stale?: unknown; expired?: unknown };\n return {\n stale: typeof value.stale === 'number' ? value.stale : 0,\n expired: typeof value.expired === 'number' ? value.expired : 0,\n };\n } catch {\n return { stale: 0, expired: 0 };\n }\n};\n\nexport const resetRuntimeCacheClientForTests = (): void => {\n cachedToken = undefined;\n};\n","import {\n getRuntimeCacheTagState,\n readRuntimeCache,\n revalidateRuntimeCacheTags,\n writeRuntimeCache,\n} from './nextjs-runtime-cache-client';\n\ninterface CacheComponentEntry {\n value: ReadableStream<Uint8Array>;\n tags: string[];\n stale: number;\n timestamp: number;\n expire: number;\n revalidate: number;\n}\n\ninterface SerializedCacheComponentEntry extends Omit<CacheComponentEntry, 'value'> {\n value: Uint8Array;\n}\n\nconst isSerializedCacheComponentEntry = (value: unknown): value is SerializedCacheComponentEntry => {\n if (typeof value !== 'object' || value === null) return false;\n const entry = value as Partial<SerializedCacheComponentEntry>;\n return (\n entry.value instanceof Uint8Array &&\n Array.isArray(entry.tags) &&\n entry.tags.every((tag) => typeof tag === 'string') &&\n typeof entry.stale === 'number' &&\n typeof entry.timestamp === 'number' &&\n typeof entry.expire === 'number' &&\n typeof entry.revalidate === 'number'\n );\n};\n\nconst pendingWrites = new Map<string, Promise<void>>();\n\nconst streamToBytes = async (stream: ReadableStream<Uint8Array>): Promise<Uint8Array> => {\n const chunks: Uint8Array[] = [];\n let size = 0;\n const reader = stream.getReader();\n while (true) {\n const result = await reader.read();\n if (result.done) break;\n chunks.push(result.value);\n size += result.value.byteLength;\n }\n const bytes = new Uint8Array(size);\n let offset = 0;\n for (const chunk of chunks) {\n bytes.set(chunk, offset);\n offset += chunk.byteLength;\n }\n return bytes;\n};\n\n/** Shared Network cache handler for Next.js Cache Components and `use cache`. */\nconst cacheHandler = {\n async get(cacheKey: string, softTags: string[]): Promise<CacheComponentEntry | undefined> {\n await pendingWrites.get(cacheKey);\n const value = await readRuntimeCache('component', cacheKey);\n if (!isSerializedCacheComponentEntry(value)) return undefined;\n const tagState = await getRuntimeCacheTagState('component', [...new Set([...value.tags, ...softTags])]);\n if (tagState.expired > value.timestamp) return undefined;\n return {\n ...value,\n ...(tagState.stale > value.timestamp ? { revalidate: -1 } : {}),\n value: new ReadableStream<Uint8Array>({\n start(controller) {\n controller.enqueue(value.value);\n controller.close();\n },\n }),\n };\n },\n\n async set(cacheKey: string, pendingEntry: Promise<CacheComponentEntry>): Promise<void> {\n const write = (async () => {\n const entry = await pendingEntry;\n const value = await streamToBytes(entry.value);\n await writeRuntimeCache('component', cacheKey, { ...entry, value }, entry.tags);\n })();\n pendingWrites.set(cacheKey, write);\n try {\n await write;\n } finally {\n if (pendingWrites.get(cacheKey) === write) pendingWrites.delete(cacheKey);\n }\n },\n\n async refreshTags(): Promise<void> {},\n\n getExpiration(): Promise<number> {\n return Promise.resolve(Infinity);\n },\n\n updateTags(tags: string[], durations?: { expire?: number }): Promise<void> {\n return revalidateRuntimeCacheTags('component', tags, durations);\n },\n};\n\nexport default cacheHandler;\n"],"mappings":"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","names":[]}
|
|
1
|
+
{"version":3,"sources":["../src/nextjs-runtime-cache-client.ts","../src/nextjs-cache-components-handler.ts"],"sourcesContent":["interface RuntimeCacheEnvelope {\n value: unknown;\n}\n\ninterface AccessTokenResponse {\n access_token: string;\n expires_in?: number;\n}\n\nexport interface RuntimeCacheTagState {\n stale: number;\n expired: number;\n}\n\nlet cachedToken: { value: string; expiresAt: number } | undefined;\n\nconst apiBaseUrl = (): string => (process.env.GIGADRIVE_API_URL ?? 'https://api.gigadrive.network').replace(/\\/$/, '');\n\nconst encodeBinary = (value: unknown, seen = new WeakSet<object>()): unknown => {\n if (value instanceof Uint8Array) {\n return { __gigadriveType: 'bytes', value: Buffer.from(value).toString('base64') };\n }\n if (value instanceof ArrayBuffer) {\n return { __gigadriveType: 'bytes', value: Buffer.from(value).toString('base64') };\n }\n if (Array.isArray(value)) return value.map((item) => encodeBinary(item, seen));\n if (typeof value !== 'object' || value === null) return value;\n if (seen.has(value)) throw new Error('Next.js cache entry contains a circular value');\n seen.add(value);\n const result: Record<string, unknown> = {};\n for (const [key, item] of Object.entries(value)) result[key] = encodeBinary(item, seen);\n seen.delete(value);\n return result;\n};\n\nconst decodeBinary = (value: unknown): unknown => {\n if (Array.isArray(value)) return value.map(decodeBinary);\n if (typeof value !== 'object' || value === null) return value;\n const record = value as Record<string, unknown>;\n if (record.__gigadriveType === 'bytes' && typeof record.value === 'string')\n return Buffer.from(record.value, 'base64');\n return Object.fromEntries(Object.entries(record).map(([key, item]) => [key, decodeBinary(item)]));\n};\n\nconst getAccessToken = async (): Promise<string> => {\n if (cachedToken && cachedToken.expiresAt > Date.now() + 30_000) return cachedToken.value;\n const clientId = process.env.GIGADRIVE_CLIENT_ID;\n const clientSecret = process.env.GIGADRIVE_CLIENT_SECRET;\n if (!clientId || !clientSecret) throw new Error('Gigadrive workload credentials are unavailable');\n\n const response = await fetch(`${apiBaseUrl()}/oauth2/token`, {\n method: 'POST',\n headers: {\n authorization: `Basic ${Buffer.from(`${clientId}:${clientSecret}`).toString('base64')}`,\n 'content-type': 'application/x-www-form-urlencoded',\n },\n body: 'grant_type=client_credentials',\n });\n if (!response.ok) throw new Error(`Gigadrive workload authentication failed with status ${response.status}`);\n const token = (await response.json()) as AccessTokenResponse;\n if (!token.access_token) throw new Error('Gigadrive workload authentication returned no access token');\n cachedToken = {\n value: token.access_token,\n expiresAt: Date.now() + Math.max(60, token.expires_in ?? 300) * 1000,\n };\n return token.access_token;\n};\n\nconst request = async (pathname: string, init: RequestInit, attempt = 0): Promise<Response> => {\n const token = await getAccessToken();\n try {\n const response = await fetch(`${apiBaseUrl()}${pathname}`, {\n ...init,\n headers: {\n authorization: `Bearer ${token}`,\n 'content-type': 'application/json',\n 'x-gigadrive-deployment-id': process.env.GIGADRIVE_DEPLOYMENT_ID ?? process.env.NEBULA_DEPLOYMENT_ID ?? '',\n 'x-gigadrive-build-id': process.env.NEXT_BUILD_ID ?? '',\n ...init.headers,\n },\n });\n if (response.status === 401 && attempt === 0) {\n cachedToken = undefined;\n return request(pathname, init, attempt + 1);\n }\n if (response.status >= 500 && attempt < 2) return request(pathname, init, attempt + 1);\n return response;\n } catch (error) {\n if (attempt < 2) return request(pathname, init, attempt + 1);\n throw error;\n }\n};\n\nconst cachePath = (kind: string, key: string): string =>\n `/internal/runtime-cache/v1/entries/${encodeURIComponent(kind)}/${encodeURIComponent(key)}`;\n\nexport const readRuntimeCache = async (kind: string, key: string): Promise<unknown | undefined> => {\n try {\n const response = await request(cachePath(kind, key), { method: 'GET' });\n if (response.status === 404) return undefined;\n if (!response.ok) return undefined;\n const envelope = (await response.json()) as RuntimeCacheEnvelope;\n return decodeBinary(envelope.value);\n } catch {\n return undefined;\n }\n};\n\nexport const writeRuntimeCache = async (\n kind: string,\n key: string,\n value: unknown,\n tags: readonly string[] = []\n): Promise<void> => {\n const response = await request(cachePath(kind, key), {\n method: 'PUT',\n body: JSON.stringify({ value: encodeBinary(value), tags }),\n });\n if (!response.ok) throw new Error(`Gigadrive runtime cache write failed with status ${response.status}`);\n};\n\nexport const revalidateRuntimeCacheTags = async (\n kind: string,\n tags: readonly string[],\n durations?: { expire?: number }\n): Promise<void> => {\n const response = await request('/internal/runtime-cache/v1/tags/revalidate', {\n method: 'POST',\n body: JSON.stringify({ kind, tags, durations }),\n });\n if (!response.ok) throw new Error(`Gigadrive runtime cache revalidation failed with status ${response.status}`);\n};\n\nexport const getRuntimeCacheTagExpiration = async (kind: string, tags: readonly string[]): Promise<number> => {\n try {\n const response = await request('/internal/runtime-cache/v1/tags/expiration', {\n method: 'POST',\n body: JSON.stringify({ kind, tags }),\n });\n if (!response.ok) return 0;\n const value = (await response.json()) as { expiration?: unknown };\n return typeof value.expiration === 'number' ? value.expiration : 0;\n } catch {\n return 0;\n }\n};\n\nexport const getRuntimeCacheTagState = async (kind: string, tags: readonly string[]): Promise<RuntimeCacheTagState> => {\n try {\n const response = await request('/internal/runtime-cache/v1/tags/state', {\n method: 'POST',\n body: JSON.stringify({ kind, tags }),\n });\n if (!response.ok) return { stale: 0, expired: 0 };\n const value = (await response.json()) as { stale?: unknown; expired?: unknown };\n return {\n stale: typeof value.stale === 'number' ? value.stale : 0,\n expired: typeof value.expired === 'number' ? value.expired : 0,\n };\n } catch {\n return { stale: 0, expired: 0 };\n }\n};\n\nexport const resetRuntimeCacheClientForTests = (): void => {\n cachedToken = undefined;\n};\n","import {\n getRuntimeCacheTagState,\n readRuntimeCache,\n revalidateRuntimeCacheTags,\n writeRuntimeCache,\n} from './nextjs-runtime-cache-client';\n\ninterface CacheComponentEntry {\n value: ReadableStream<Uint8Array>;\n tags: string[];\n stale: number;\n timestamp: number;\n expire: number;\n revalidate: number;\n}\n\ninterface SerializedCacheComponentEntry extends Omit<CacheComponentEntry, 'value'> {\n value: Uint8Array;\n}\n\nconst isSerializedCacheComponentEntry = (value: unknown): value is SerializedCacheComponentEntry => {\n if (typeof value !== 'object' || value === null) return false;\n const entry = value as Partial<SerializedCacheComponentEntry>;\n return (\n entry.value instanceof Uint8Array &&\n Array.isArray(entry.tags) &&\n entry.tags.every((tag) => typeof tag === 'string') &&\n typeof entry.stale === 'number' &&\n typeof entry.timestamp === 'number' &&\n typeof entry.expire === 'number' &&\n typeof entry.revalidate === 'number'\n );\n};\n\nconst pendingWrites = new Map<string, Promise<void>>();\nconst buildEntries = new Map<string, SerializedCacheComponentEntry>();\n\nconst streamToBytes = async (stream: ReadableStream<Uint8Array>): Promise<Uint8Array> => {\n const chunks: Uint8Array[] = [];\n let size = 0;\n const reader = stream.getReader();\n while (true) {\n const result = await reader.read();\n if (result.done) break;\n chunks.push(result.value);\n size += result.value.byteLength;\n }\n const bytes = new Uint8Array(size);\n let offset = 0;\n for (const chunk of chunks) {\n bytes.set(chunk, offset);\n offset += chunk.byteLength;\n }\n return bytes;\n};\n\n/** Shared Network cache handler for Next.js Cache Components and `use cache`. */\nconst cacheHandler = {\n async get(cacheKey: string, softTags: string[]): Promise<CacheComponentEntry | undefined> {\n await pendingWrites.get(cacheKey);\n const value =\n process.env.GIGADRIVE_NEXT_BUILD === '1'\n ? buildEntries.get(cacheKey)\n : await readRuntimeCache('component', cacheKey);\n if (!isSerializedCacheComponentEntry(value)) return undefined;\n const tagState =\n process.env.GIGADRIVE_NEXT_BUILD === '1'\n ? { stale: 0, expired: 0 }\n : await getRuntimeCacheTagState('component', [...new Set([...value.tags, ...softTags])]);\n if (tagState.expired > value.timestamp) return undefined;\n return {\n ...value,\n ...(tagState.stale > value.timestamp ? { revalidate: -1 } : {}),\n value: new ReadableStream<Uint8Array>({\n start(controller) {\n controller.enqueue(value.value);\n controller.close();\n },\n }),\n };\n },\n\n async set(cacheKey: string, pendingEntry: Promise<CacheComponentEntry>): Promise<void> {\n const write = (async () => {\n const entry = await pendingEntry;\n const value = await streamToBytes(entry.value);\n const serializedEntry = { ...entry, value };\n if (process.env.GIGADRIVE_NEXT_BUILD === '1') {\n buildEntries.set(cacheKey, serializedEntry);\n } else {\n await writeRuntimeCache('component', cacheKey, serializedEntry, entry.tags);\n }\n })();\n pendingWrites.set(cacheKey, write);\n try {\n await write;\n } finally {\n if (pendingWrites.get(cacheKey) === write) pendingWrites.delete(cacheKey);\n }\n },\n\n async refreshTags(): Promise<void> {},\n\n getExpiration(): Promise<number> {\n return Promise.resolve(Infinity);\n },\n\n async updateTags(tags: string[], durations?: { expire?: number }): Promise<void> {\n if (process.env.GIGADRIVE_NEXT_BUILD === '1') {\n for (const [key, entry] of buildEntries) {\n if (entry.tags.some((tag) => tags.includes(tag))) buildEntries.delete(key);\n }\n return;\n }\n return revalidateRuntimeCacheTags('component', tags, durations);\n },\n};\n\nexport default cacheHandler;\n"],"mappings":"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","names":[]}
|
|
@@ -11,6 +11,7 @@ interface IncrementalCacheEntry {
|
|
|
11
11
|
}
|
|
12
12
|
/** Shared Network cache handler for ISR, server responses, fetches, and image metadata. */
|
|
13
13
|
declare class GigadriveNextCacheHandler {
|
|
14
|
+
private readonly buildEntries;
|
|
14
15
|
get(key: string, context?: IncrementalCacheContext): Promise<IncrementalCacheEntry | null>;
|
|
15
16
|
set(key: string, data: unknown, context: IncrementalCacheContext): Promise<void>;
|
|
16
17
|
revalidateTag(tags: string | string[], durations?: {
|
|
@@ -11,6 +11,7 @@ interface IncrementalCacheEntry {
|
|
|
11
11
|
}
|
|
12
12
|
/** Shared Network cache handler for ISR, server responses, fetches, and image metadata. */
|
|
13
13
|
declare class GigadriveNextCacheHandler {
|
|
14
|
+
private readonly buildEntries;
|
|
14
15
|
get(key: string, context?: IncrementalCacheContext): Promise<IncrementalCacheEntry | null>;
|
|
15
16
|
set(key: string, data: unknown, context: IncrementalCacheContext): Promise<void>;
|
|
16
17
|
revalidateTag(tags: string | string[], durations?: {
|
|
@@ -143,26 +143,34 @@ var getRuntimeCacheTagState = async (kind, tags) => {
|
|
|
143
143
|
// src/nextjs-cache-handler.ts
|
|
144
144
|
var isIncrementalCacheEntry = (value) => typeof value === "object" && value !== null && typeof value.lastModified === "number" && "value" in value;
|
|
145
145
|
var GigadriveNextCacheHandler = class {
|
|
146
|
+
buildEntries = /* @__PURE__ */ new Map();
|
|
146
147
|
async get(key, context = {}) {
|
|
147
|
-
const entry = await readRuntimeCache("incremental", key);
|
|
148
|
+
const entry = process.env.GIGADRIVE_NEXT_BUILD === "1" ? this.buildEntries.get(key) ?? null : await readRuntimeCache("incremental", key);
|
|
148
149
|
if (!isIncrementalCacheEntry(entry)) return null;
|
|
149
150
|
const tags = [.../* @__PURE__ */ new Set([...entry.tags ?? [], ...context.tags ?? [], ...context.softTags ?? []])];
|
|
150
|
-
if (tags.length === 0) return entry;
|
|
151
|
+
if (process.env.GIGADRIVE_NEXT_BUILD === "1" || tags.length === 0) return entry;
|
|
151
152
|
const tagState = await getRuntimeCacheTagState("incremental", tags);
|
|
152
153
|
if (tagState.expired > entry.lastModified) return null;
|
|
153
154
|
return tagState.stale > entry.lastModified ? { ...entry, lastModified: 1 } : entry;
|
|
154
155
|
}
|
|
155
156
|
async set(key, data, context) {
|
|
156
157
|
const tags = context.tags ?? [];
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
key,
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
);
|
|
158
|
+
const entry = { lastModified: Date.now(), value: data, tags, cacheControl: context.cacheControl };
|
|
159
|
+
if (process.env.GIGADRIVE_NEXT_BUILD === "1") {
|
|
160
|
+
this.buildEntries.set(key, entry);
|
|
161
|
+
return;
|
|
162
|
+
}
|
|
163
|
+
await writeRuntimeCache("incremental", key, entry, tags);
|
|
163
164
|
}
|
|
164
165
|
async revalidateTag(tags, durations) {
|
|
165
|
-
|
|
166
|
+
const normalizedTags = Array.isArray(tags) ? tags : [tags];
|
|
167
|
+
if (process.env.GIGADRIVE_NEXT_BUILD === "1") {
|
|
168
|
+
for (const [key, entry] of this.buildEntries) {
|
|
169
|
+
if (entry.tags?.some((tag) => normalizedTags.includes(tag))) this.buildEntries.delete(key);
|
|
170
|
+
}
|
|
171
|
+
return;
|
|
172
|
+
}
|
|
173
|
+
await revalidateRuntimeCacheTags("incremental", normalizedTags, durations);
|
|
166
174
|
}
|
|
167
175
|
resetRequestCache() {
|
|
168
176
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/nextjs-cache-handler.ts","../src/nextjs-runtime-cache-client.ts"],"sourcesContent":["import {\n getRuntimeCacheTagState,\n readRuntimeCache,\n revalidateRuntimeCacheTags,\n writeRuntimeCache,\n} from './nextjs-runtime-cache-client';\n\ninterface IncrementalCacheContext {\n tags?: string[];\n softTags?: string[];\n cacheControl?: unknown;\n}\n\ninterface IncrementalCacheEntry {\n lastModified: number;\n value: unknown | null;\n tags?: string[];\n cacheControl?: unknown;\n}\n\nconst isIncrementalCacheEntry = (value: unknown): value is IncrementalCacheEntry =>\n typeof value === 'object' &&\n value !== null &&\n typeof (value as Partial<IncrementalCacheEntry>).lastModified === 'number' &&\n 'value' in value;\n\n/** Shared Network cache handler for ISR, server responses, fetches, and image metadata. */\nexport default class GigadriveNextCacheHandler {\n async get(key: string, context: IncrementalCacheContext = {}): Promise<IncrementalCacheEntry | null> {\n const entry = await readRuntimeCache('incremental', key);\n if (!isIncrementalCacheEntry(entry)) return null;\n const tags = [...new Set([...(entry.tags ?? []), ...(context.tags ?? []), ...(context.softTags ?? [])])];\n if (tags.length === 0) return entry;\n const tagState = await getRuntimeCacheTagState('incremental', tags);\n if (tagState.expired > entry.lastModified) return null;\n return tagState.stale > entry.lastModified ? { ...entry, lastModified: 1 } : entry;\n }\n\n async set(key: string, data: unknown, context: IncrementalCacheContext): Promise<void> {\n const tags = context.tags ?? [];\n await writeRuntimeCache(\n 'incremental',\n key,\n { lastModified: Date.now(), value: data, tags, cacheControl: context.cacheControl },\n tags\n );\n }\n\n async revalidateTag(tags: string | string[], durations?: { expire?: number }): Promise<void> {\n await revalidateRuntimeCacheTags('incremental', Array.isArray(tags) ? tags : [tags], durations);\n }\n\n resetRequestCache(): void {}\n}\n","interface RuntimeCacheEnvelope {\n value: unknown;\n}\n\ninterface AccessTokenResponse {\n access_token: string;\n expires_in?: number;\n}\n\nexport interface RuntimeCacheTagState {\n stale: number;\n expired: number;\n}\n\nlet cachedToken: { value: string; expiresAt: number } | undefined;\n\nconst apiBaseUrl = (): string => (process.env.GIGADRIVE_API_URL ?? 'https://api.gigadrive.network').replace(/\\/$/, '');\n\nconst encodeBinary = (value: unknown, seen = new WeakSet<object>()): unknown => {\n if (value instanceof Uint8Array) {\n return { __gigadriveType: 'bytes', value: Buffer.from(value).toString('base64') };\n }\n if (value instanceof ArrayBuffer) {\n return { __gigadriveType: 'bytes', value: Buffer.from(value).toString('base64') };\n }\n if (Array.isArray(value)) return value.map((item) => encodeBinary(item, seen));\n if (typeof value !== 'object' || value === null) return value;\n if (seen.has(value)) throw new Error('Next.js cache entry contains a circular value');\n seen.add(value);\n const result: Record<string, unknown> = {};\n for (const [key, item] of Object.entries(value)) result[key] = encodeBinary(item, seen);\n seen.delete(value);\n return result;\n};\n\nconst decodeBinary = (value: unknown): unknown => {\n if (Array.isArray(value)) return value.map(decodeBinary);\n if (typeof value !== 'object' || value === null) return value;\n const record = value as Record<string, unknown>;\n if (record.__gigadriveType === 'bytes' && typeof record.value === 'string')\n return Buffer.from(record.value, 'base64');\n return Object.fromEntries(Object.entries(record).map(([key, item]) => [key, decodeBinary(item)]));\n};\n\nconst getAccessToken = async (): Promise<string> => {\n if (cachedToken && cachedToken.expiresAt > Date.now() + 30_000) return cachedToken.value;\n const clientId = process.env.GIGADRIVE_CLIENT_ID;\n const clientSecret = process.env.GIGADRIVE_CLIENT_SECRET;\n if (!clientId || !clientSecret) throw new Error('Gigadrive workload credentials are unavailable');\n\n const response = await fetch(`${apiBaseUrl()}/oauth2/token`, {\n method: 'POST',\n headers: {\n authorization: `Basic ${Buffer.from(`${clientId}:${clientSecret}`).toString('base64')}`,\n 'content-type': 'application/x-www-form-urlencoded',\n },\n body: 'grant_type=client_credentials',\n });\n if (!response.ok) throw new Error(`Gigadrive workload authentication failed with status ${response.status}`);\n const token = (await response.json()) as AccessTokenResponse;\n if (!token.access_token) throw new Error('Gigadrive workload authentication returned no access token');\n cachedToken = {\n value: token.access_token,\n expiresAt: Date.now() + Math.max(60, token.expires_in ?? 300) * 1000,\n };\n return token.access_token;\n};\n\nconst request = async (pathname: string, init: RequestInit, attempt = 0): Promise<Response> => {\n const token = await getAccessToken();\n try {\n const response = await fetch(`${apiBaseUrl()}${pathname}`, {\n ...init,\n headers: {\n authorization: `Bearer ${token}`,\n 'content-type': 'application/json',\n 'x-gigadrive-deployment-id': process.env.GIGADRIVE_DEPLOYMENT_ID ?? process.env.NEBULA_DEPLOYMENT_ID ?? '',\n 'x-gigadrive-build-id': process.env.NEXT_BUILD_ID ?? '',\n ...init.headers,\n },\n });\n if (response.status === 401 && attempt === 0) {\n cachedToken = undefined;\n return request(pathname, init, attempt + 1);\n }\n if (response.status >= 500 && attempt < 2) return request(pathname, init, attempt + 1);\n return response;\n } catch (error) {\n if (attempt < 2) return request(pathname, init, attempt + 1);\n throw error;\n }\n};\n\nconst cachePath = (kind: string, key: string): string =>\n `/internal/runtime-cache/v1/entries/${encodeURIComponent(kind)}/${encodeURIComponent(key)}`;\n\nexport const readRuntimeCache = async (kind: string, key: string): Promise<unknown | undefined> => {\n try {\n const response = await request(cachePath(kind, key), { method: 'GET' });\n if (response.status === 404) return undefined;\n if (!response.ok) return undefined;\n const envelope = (await response.json()) as RuntimeCacheEnvelope;\n return decodeBinary(envelope.value);\n } catch {\n return undefined;\n }\n};\n\nexport const writeRuntimeCache = async (\n kind: string,\n key: string,\n value: unknown,\n tags: readonly string[] = []\n): Promise<void> => {\n const response = await request(cachePath(kind, key), {\n method: 'PUT',\n body: JSON.stringify({ value: encodeBinary(value), tags }),\n });\n if (!response.ok) throw new Error(`Gigadrive runtime cache write failed with status ${response.status}`);\n};\n\nexport const revalidateRuntimeCacheTags = async (\n kind: string,\n tags: readonly string[],\n durations?: { expire?: number }\n): Promise<void> => {\n const response = await request('/internal/runtime-cache/v1/tags/revalidate', {\n method: 'POST',\n body: JSON.stringify({ kind, tags, durations }),\n });\n if (!response.ok) throw new Error(`Gigadrive runtime cache revalidation failed with status ${response.status}`);\n};\n\nexport const getRuntimeCacheTagExpiration = async (kind: string, tags: readonly string[]): Promise<number> => {\n try {\n const response = await request('/internal/runtime-cache/v1/tags/expiration', {\n method: 'POST',\n body: JSON.stringify({ kind, tags }),\n });\n if (!response.ok) return 0;\n const value = (await response.json()) as { expiration?: unknown };\n return typeof value.expiration === 'number' ? value.expiration : 0;\n } catch {\n return 0;\n }\n};\n\nexport const getRuntimeCacheTagState = async (kind: string, tags: readonly string[]): Promise<RuntimeCacheTagState> => {\n try {\n const response = await request('/internal/runtime-cache/v1/tags/state', {\n method: 'POST',\n body: JSON.stringify({ kind, tags }),\n });\n if (!response.ok) return { stale: 0, expired: 0 };\n const value = (await response.json()) as { stale?: unknown; expired?: unknown };\n return {\n stale: typeof value.stale === 'number' ? value.stale : 0,\n expired: typeof value.expired === 'number' ? value.expired : 0,\n };\n } catch {\n return { stale: 0, expired: 0 };\n }\n};\n\nexport const resetRuntimeCacheClientForTests = (): void => {\n cachedToken = undefined;\n};\n"],"mappings":"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","names":[]}
|
|
1
|
+
{"version":3,"sources":["../src/nextjs-cache-handler.ts","../src/nextjs-runtime-cache-client.ts"],"sourcesContent":["import {\n getRuntimeCacheTagState,\n readRuntimeCache,\n revalidateRuntimeCacheTags,\n writeRuntimeCache,\n} from './nextjs-runtime-cache-client';\n\ninterface IncrementalCacheContext {\n tags?: string[];\n softTags?: string[];\n cacheControl?: unknown;\n}\n\ninterface IncrementalCacheEntry {\n lastModified: number;\n value: unknown | null;\n tags?: string[];\n cacheControl?: unknown;\n}\n\nconst isIncrementalCacheEntry = (value: unknown): value is IncrementalCacheEntry =>\n typeof value === 'object' &&\n value !== null &&\n typeof (value as Partial<IncrementalCacheEntry>).lastModified === 'number' &&\n 'value' in value;\n\n/** Shared Network cache handler for ISR, server responses, fetches, and image metadata. */\nexport default class GigadriveNextCacheHandler {\n private readonly buildEntries = new Map<string, IncrementalCacheEntry>();\n\n async get(key: string, context: IncrementalCacheContext = {}): Promise<IncrementalCacheEntry | null> {\n const entry =\n process.env.GIGADRIVE_NEXT_BUILD === '1'\n ? (this.buildEntries.get(key) ?? null)\n : await readRuntimeCache('incremental', key);\n if (!isIncrementalCacheEntry(entry)) return null;\n const tags = [...new Set([...(entry.tags ?? []), ...(context.tags ?? []), ...(context.softTags ?? [])])];\n if (process.env.GIGADRIVE_NEXT_BUILD === '1' || tags.length === 0) return entry;\n const tagState = await getRuntimeCacheTagState('incremental', tags);\n if (tagState.expired > entry.lastModified) return null;\n return tagState.stale > entry.lastModified ? { ...entry, lastModified: 1 } : entry;\n }\n\n async set(key: string, data: unknown, context: IncrementalCacheContext): Promise<void> {\n const tags = context.tags ?? [];\n const entry = { lastModified: Date.now(), value: data, tags, cacheControl: context.cacheControl };\n if (process.env.GIGADRIVE_NEXT_BUILD === '1') {\n this.buildEntries.set(key, entry);\n return;\n }\n await writeRuntimeCache('incremental', key, entry, tags);\n }\n\n async revalidateTag(tags: string | string[], durations?: { expire?: number }): Promise<void> {\n const normalizedTags = Array.isArray(tags) ? tags : [tags];\n if (process.env.GIGADRIVE_NEXT_BUILD === '1') {\n for (const [key, entry] of this.buildEntries) {\n if (entry.tags?.some((tag) => normalizedTags.includes(tag))) this.buildEntries.delete(key);\n }\n return;\n }\n await revalidateRuntimeCacheTags('incremental', normalizedTags, durations);\n }\n\n resetRequestCache(): void {}\n}\n","interface RuntimeCacheEnvelope {\n value: unknown;\n}\n\ninterface AccessTokenResponse {\n access_token: string;\n expires_in?: number;\n}\n\nexport interface RuntimeCacheTagState {\n stale: number;\n expired: number;\n}\n\nlet cachedToken: { value: string; expiresAt: number } | undefined;\n\nconst apiBaseUrl = (): string => (process.env.GIGADRIVE_API_URL ?? 'https://api.gigadrive.network').replace(/\\/$/, '');\n\nconst encodeBinary = (value: unknown, seen = new WeakSet<object>()): unknown => {\n if (value instanceof Uint8Array) {\n return { __gigadriveType: 'bytes', value: Buffer.from(value).toString('base64') };\n }\n if (value instanceof ArrayBuffer) {\n return { __gigadriveType: 'bytes', value: Buffer.from(value).toString('base64') };\n }\n if (Array.isArray(value)) return value.map((item) => encodeBinary(item, seen));\n if (typeof value !== 'object' || value === null) return value;\n if (seen.has(value)) throw new Error('Next.js cache entry contains a circular value');\n seen.add(value);\n const result: Record<string, unknown> = {};\n for (const [key, item] of Object.entries(value)) result[key] = encodeBinary(item, seen);\n seen.delete(value);\n return result;\n};\n\nconst decodeBinary = (value: unknown): unknown => {\n if (Array.isArray(value)) return value.map(decodeBinary);\n if (typeof value !== 'object' || value === null) return value;\n const record = value as Record<string, unknown>;\n if (record.__gigadriveType === 'bytes' && typeof record.value === 'string')\n return Buffer.from(record.value, 'base64');\n return Object.fromEntries(Object.entries(record).map(([key, item]) => [key, decodeBinary(item)]));\n};\n\nconst getAccessToken = async (): Promise<string> => {\n if (cachedToken && cachedToken.expiresAt > Date.now() + 30_000) return cachedToken.value;\n const clientId = process.env.GIGADRIVE_CLIENT_ID;\n const clientSecret = process.env.GIGADRIVE_CLIENT_SECRET;\n if (!clientId || !clientSecret) throw new Error('Gigadrive workload credentials are unavailable');\n\n const response = await fetch(`${apiBaseUrl()}/oauth2/token`, {\n method: 'POST',\n headers: {\n authorization: `Basic ${Buffer.from(`${clientId}:${clientSecret}`).toString('base64')}`,\n 'content-type': 'application/x-www-form-urlencoded',\n },\n body: 'grant_type=client_credentials',\n });\n if (!response.ok) throw new Error(`Gigadrive workload authentication failed with status ${response.status}`);\n const token = (await response.json()) as AccessTokenResponse;\n if (!token.access_token) throw new Error('Gigadrive workload authentication returned no access token');\n cachedToken = {\n value: token.access_token,\n expiresAt: Date.now() + Math.max(60, token.expires_in ?? 300) * 1000,\n };\n return token.access_token;\n};\n\nconst request = async (pathname: string, init: RequestInit, attempt = 0): Promise<Response> => {\n const token = await getAccessToken();\n try {\n const response = await fetch(`${apiBaseUrl()}${pathname}`, {\n ...init,\n headers: {\n authorization: `Bearer ${token}`,\n 'content-type': 'application/json',\n 'x-gigadrive-deployment-id': process.env.GIGADRIVE_DEPLOYMENT_ID ?? process.env.NEBULA_DEPLOYMENT_ID ?? '',\n 'x-gigadrive-build-id': process.env.NEXT_BUILD_ID ?? '',\n ...init.headers,\n },\n });\n if (response.status === 401 && attempt === 0) {\n cachedToken = undefined;\n return request(pathname, init, attempt + 1);\n }\n if (response.status >= 500 && attempt < 2) return request(pathname, init, attempt + 1);\n return response;\n } catch (error) {\n if (attempt < 2) return request(pathname, init, attempt + 1);\n throw error;\n }\n};\n\nconst cachePath = (kind: string, key: string): string =>\n `/internal/runtime-cache/v1/entries/${encodeURIComponent(kind)}/${encodeURIComponent(key)}`;\n\nexport const readRuntimeCache = async (kind: string, key: string): Promise<unknown | undefined> => {\n try {\n const response = await request(cachePath(kind, key), { method: 'GET' });\n if (response.status === 404) return undefined;\n if (!response.ok) return undefined;\n const envelope = (await response.json()) as RuntimeCacheEnvelope;\n return decodeBinary(envelope.value);\n } catch {\n return undefined;\n }\n};\n\nexport const writeRuntimeCache = async (\n kind: string,\n key: string,\n value: unknown,\n tags: readonly string[] = []\n): Promise<void> => {\n const response = await request(cachePath(kind, key), {\n method: 'PUT',\n body: JSON.stringify({ value: encodeBinary(value), tags }),\n });\n if (!response.ok) throw new Error(`Gigadrive runtime cache write failed with status ${response.status}`);\n};\n\nexport const revalidateRuntimeCacheTags = async (\n kind: string,\n tags: readonly string[],\n durations?: { expire?: number }\n): Promise<void> => {\n const response = await request('/internal/runtime-cache/v1/tags/revalidate', {\n method: 'POST',\n body: JSON.stringify({ kind, tags, durations }),\n });\n if (!response.ok) throw new Error(`Gigadrive runtime cache revalidation failed with status ${response.status}`);\n};\n\nexport const getRuntimeCacheTagExpiration = async (kind: string, tags: readonly string[]): Promise<number> => {\n try {\n const response = await request('/internal/runtime-cache/v1/tags/expiration', {\n method: 'POST',\n body: JSON.stringify({ kind, tags }),\n });\n if (!response.ok) return 0;\n const value = (await response.json()) as { expiration?: unknown };\n return typeof value.expiration === 'number' ? value.expiration : 0;\n } catch {\n return 0;\n }\n};\n\nexport const getRuntimeCacheTagState = async (kind: string, tags: readonly string[]): Promise<RuntimeCacheTagState> => {\n try {\n const response = await request('/internal/runtime-cache/v1/tags/state', {\n method: 'POST',\n body: JSON.stringify({ kind, tags }),\n });\n if (!response.ok) return { stale: 0, expired: 0 };\n const value = (await response.json()) as { stale?: unknown; expired?: unknown };\n return {\n stale: typeof value.stale === 'number' ? value.stale : 0,\n expired: typeof value.expired === 'number' ? value.expired : 0,\n };\n } catch {\n return { stale: 0, expired: 0 };\n }\n};\n\nexport const resetRuntimeCacheClientForTests = (): void => {\n cachedToken = undefined;\n};\n"],"mappings":"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","names":[]}
|
|
@@ -117,26 +117,34 @@ var getRuntimeCacheTagState = async (kind, tags) => {
|
|
|
117
117
|
// src/nextjs-cache-handler.ts
|
|
118
118
|
var isIncrementalCacheEntry = (value) => typeof value === "object" && value !== null && typeof value.lastModified === "number" && "value" in value;
|
|
119
119
|
var GigadriveNextCacheHandler = class {
|
|
120
|
+
buildEntries = /* @__PURE__ */ new Map();
|
|
120
121
|
async get(key, context = {}) {
|
|
121
|
-
const entry = await readRuntimeCache("incremental", key);
|
|
122
|
+
const entry = process.env.GIGADRIVE_NEXT_BUILD === "1" ? this.buildEntries.get(key) ?? null : await readRuntimeCache("incremental", key);
|
|
122
123
|
if (!isIncrementalCacheEntry(entry)) return null;
|
|
123
124
|
const tags = [.../* @__PURE__ */ new Set([...entry.tags ?? [], ...context.tags ?? [], ...context.softTags ?? []])];
|
|
124
|
-
if (tags.length === 0) return entry;
|
|
125
|
+
if (process.env.GIGADRIVE_NEXT_BUILD === "1" || tags.length === 0) return entry;
|
|
125
126
|
const tagState = await getRuntimeCacheTagState("incremental", tags);
|
|
126
127
|
if (tagState.expired > entry.lastModified) return null;
|
|
127
128
|
return tagState.stale > entry.lastModified ? { ...entry, lastModified: 1 } : entry;
|
|
128
129
|
}
|
|
129
130
|
async set(key, data, context) {
|
|
130
131
|
const tags = context.tags ?? [];
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
key,
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
);
|
|
132
|
+
const entry = { lastModified: Date.now(), value: data, tags, cacheControl: context.cacheControl };
|
|
133
|
+
if (process.env.GIGADRIVE_NEXT_BUILD === "1") {
|
|
134
|
+
this.buildEntries.set(key, entry);
|
|
135
|
+
return;
|
|
136
|
+
}
|
|
137
|
+
await writeRuntimeCache("incremental", key, entry, tags);
|
|
137
138
|
}
|
|
138
139
|
async revalidateTag(tags, durations) {
|
|
139
|
-
|
|
140
|
+
const normalizedTags = Array.isArray(tags) ? tags : [tags];
|
|
141
|
+
if (process.env.GIGADRIVE_NEXT_BUILD === "1") {
|
|
142
|
+
for (const [key, entry] of this.buildEntries) {
|
|
143
|
+
if (entry.tags?.some((tag) => normalizedTags.includes(tag))) this.buildEntries.delete(key);
|
|
144
|
+
}
|
|
145
|
+
return;
|
|
146
|
+
}
|
|
147
|
+
await revalidateRuntimeCacheTags("incremental", normalizedTags, durations);
|
|
140
148
|
}
|
|
141
149
|
resetRequestCache() {
|
|
142
150
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/nextjs-runtime-cache-client.ts","../src/nextjs-cache-handler.ts"],"sourcesContent":["interface RuntimeCacheEnvelope {\n value: unknown;\n}\n\ninterface AccessTokenResponse {\n access_token: string;\n expires_in?: number;\n}\n\nexport interface RuntimeCacheTagState {\n stale: number;\n expired: number;\n}\n\nlet cachedToken: { value: string; expiresAt: number } | undefined;\n\nconst apiBaseUrl = (): string => (process.env.GIGADRIVE_API_URL ?? 'https://api.gigadrive.network').replace(/\\/$/, '');\n\nconst encodeBinary = (value: unknown, seen = new WeakSet<object>()): unknown => {\n if (value instanceof Uint8Array) {\n return { __gigadriveType: 'bytes', value: Buffer.from(value).toString('base64') };\n }\n if (value instanceof ArrayBuffer) {\n return { __gigadriveType: 'bytes', value: Buffer.from(value).toString('base64') };\n }\n if (Array.isArray(value)) return value.map((item) => encodeBinary(item, seen));\n if (typeof value !== 'object' || value === null) return value;\n if (seen.has(value)) throw new Error('Next.js cache entry contains a circular value');\n seen.add(value);\n const result: Record<string, unknown> = {};\n for (const [key, item] of Object.entries(value)) result[key] = encodeBinary(item, seen);\n seen.delete(value);\n return result;\n};\n\nconst decodeBinary = (value: unknown): unknown => {\n if (Array.isArray(value)) return value.map(decodeBinary);\n if (typeof value !== 'object' || value === null) return value;\n const record = value as Record<string, unknown>;\n if (record.__gigadriveType === 'bytes' && typeof record.value === 'string')\n return Buffer.from(record.value, 'base64');\n return Object.fromEntries(Object.entries(record).map(([key, item]) => [key, decodeBinary(item)]));\n};\n\nconst getAccessToken = async (): Promise<string> => {\n if (cachedToken && cachedToken.expiresAt > Date.now() + 30_000) return cachedToken.value;\n const clientId = process.env.GIGADRIVE_CLIENT_ID;\n const clientSecret = process.env.GIGADRIVE_CLIENT_SECRET;\n if (!clientId || !clientSecret) throw new Error('Gigadrive workload credentials are unavailable');\n\n const response = await fetch(`${apiBaseUrl()}/oauth2/token`, {\n method: 'POST',\n headers: {\n authorization: `Basic ${Buffer.from(`${clientId}:${clientSecret}`).toString('base64')}`,\n 'content-type': 'application/x-www-form-urlencoded',\n },\n body: 'grant_type=client_credentials',\n });\n if (!response.ok) throw new Error(`Gigadrive workload authentication failed with status ${response.status}`);\n const token = (await response.json()) as AccessTokenResponse;\n if (!token.access_token) throw new Error('Gigadrive workload authentication returned no access token');\n cachedToken = {\n value: token.access_token,\n expiresAt: Date.now() + Math.max(60, token.expires_in ?? 300) * 1000,\n };\n return token.access_token;\n};\n\nconst request = async (pathname: string, init: RequestInit, attempt = 0): Promise<Response> => {\n const token = await getAccessToken();\n try {\n const response = await fetch(`${apiBaseUrl()}${pathname}`, {\n ...init,\n headers: {\n authorization: `Bearer ${token}`,\n 'content-type': 'application/json',\n 'x-gigadrive-deployment-id': process.env.GIGADRIVE_DEPLOYMENT_ID ?? process.env.NEBULA_DEPLOYMENT_ID ?? '',\n 'x-gigadrive-build-id': process.env.NEXT_BUILD_ID ?? '',\n ...init.headers,\n },\n });\n if (response.status === 401 && attempt === 0) {\n cachedToken = undefined;\n return request(pathname, init, attempt + 1);\n }\n if (response.status >= 500 && attempt < 2) return request(pathname, init, attempt + 1);\n return response;\n } catch (error) {\n if (attempt < 2) return request(pathname, init, attempt + 1);\n throw error;\n }\n};\n\nconst cachePath = (kind: string, key: string): string =>\n `/internal/runtime-cache/v1/entries/${encodeURIComponent(kind)}/${encodeURIComponent(key)}`;\n\nexport const readRuntimeCache = async (kind: string, key: string): Promise<unknown | undefined> => {\n try {\n const response = await request(cachePath(kind, key), { method: 'GET' });\n if (response.status === 404) return undefined;\n if (!response.ok) return undefined;\n const envelope = (await response.json()) as RuntimeCacheEnvelope;\n return decodeBinary(envelope.value);\n } catch {\n return undefined;\n }\n};\n\nexport const writeRuntimeCache = async (\n kind: string,\n key: string,\n value: unknown,\n tags: readonly string[] = []\n): Promise<void> => {\n const response = await request(cachePath(kind, key), {\n method: 'PUT',\n body: JSON.stringify({ value: encodeBinary(value), tags }),\n });\n if (!response.ok) throw new Error(`Gigadrive runtime cache write failed with status ${response.status}`);\n};\n\nexport const revalidateRuntimeCacheTags = async (\n kind: string,\n tags: readonly string[],\n durations?: { expire?: number }\n): Promise<void> => {\n const response = await request('/internal/runtime-cache/v1/tags/revalidate', {\n method: 'POST',\n body: JSON.stringify({ kind, tags, durations }),\n });\n if (!response.ok) throw new Error(`Gigadrive runtime cache revalidation failed with status ${response.status}`);\n};\n\nexport const getRuntimeCacheTagExpiration = async (kind: string, tags: readonly string[]): Promise<number> => {\n try {\n const response = await request('/internal/runtime-cache/v1/tags/expiration', {\n method: 'POST',\n body: JSON.stringify({ kind, tags }),\n });\n if (!response.ok) return 0;\n const value = (await response.json()) as { expiration?: unknown };\n return typeof value.expiration === 'number' ? value.expiration : 0;\n } catch {\n return 0;\n }\n};\n\nexport const getRuntimeCacheTagState = async (kind: string, tags: readonly string[]): Promise<RuntimeCacheTagState> => {\n try {\n const response = await request('/internal/runtime-cache/v1/tags/state', {\n method: 'POST',\n body: JSON.stringify({ kind, tags }),\n });\n if (!response.ok) return { stale: 0, expired: 0 };\n const value = (await response.json()) as { stale?: unknown; expired?: unknown };\n return {\n stale: typeof value.stale === 'number' ? value.stale : 0,\n expired: typeof value.expired === 'number' ? value.expired : 0,\n };\n } catch {\n return { stale: 0, expired: 0 };\n }\n};\n\nexport const resetRuntimeCacheClientForTests = (): void => {\n cachedToken = undefined;\n};\n","import {\n getRuntimeCacheTagState,\n readRuntimeCache,\n revalidateRuntimeCacheTags,\n writeRuntimeCache,\n} from './nextjs-runtime-cache-client';\n\ninterface IncrementalCacheContext {\n tags?: string[];\n softTags?: string[];\n cacheControl?: unknown;\n}\n\ninterface IncrementalCacheEntry {\n lastModified: number;\n value: unknown | null;\n tags?: string[];\n cacheControl?: unknown;\n}\n\nconst isIncrementalCacheEntry = (value: unknown): value is IncrementalCacheEntry =>\n typeof value === 'object' &&\n value !== null &&\n typeof (value as Partial<IncrementalCacheEntry>).lastModified === 'number' &&\n 'value' in value;\n\n/** Shared Network cache handler for ISR, server responses, fetches, and image metadata. */\nexport default class GigadriveNextCacheHandler {\n async get(key: string, context: IncrementalCacheContext = {}): Promise<IncrementalCacheEntry | null> {\n const entry = await readRuntimeCache('incremental', key);\n if (!isIncrementalCacheEntry(entry)) return null;\n const tags = [...new Set([...(entry.tags ?? []), ...(context.tags ?? []), ...(context.softTags ?? [])])];\n if (tags.length === 0) return entry;\n const tagState = await getRuntimeCacheTagState('incremental', tags);\n if (tagState.expired > entry.lastModified) return null;\n return tagState.stale > entry.lastModified ? { ...entry, lastModified: 1 } : entry;\n }\n\n async set(key: string, data: unknown, context: IncrementalCacheContext): Promise<void> {\n const tags = context.tags ?? [];\n await writeRuntimeCache(\n 'incremental',\n key,\n { lastModified: Date.now(), value: data, tags, cacheControl: context.cacheControl },\n tags\n );\n }\n\n async revalidateTag(tags: string | string[], durations?: { expire?: number }): Promise<void> {\n await revalidateRuntimeCacheTags('incremental', Array.isArray(tags) ? tags : [tags], durations);\n }\n\n resetRequestCache(): void {}\n}\n"],"mappings":"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","names":[]}
|
|
1
|
+
{"version":3,"sources":["../src/nextjs-runtime-cache-client.ts","../src/nextjs-cache-handler.ts"],"sourcesContent":["interface RuntimeCacheEnvelope {\n value: unknown;\n}\n\ninterface AccessTokenResponse {\n access_token: string;\n expires_in?: number;\n}\n\nexport interface RuntimeCacheTagState {\n stale: number;\n expired: number;\n}\n\nlet cachedToken: { value: string; expiresAt: number } | undefined;\n\nconst apiBaseUrl = (): string => (process.env.GIGADRIVE_API_URL ?? 'https://api.gigadrive.network').replace(/\\/$/, '');\n\nconst encodeBinary = (value: unknown, seen = new WeakSet<object>()): unknown => {\n if (value instanceof Uint8Array) {\n return { __gigadriveType: 'bytes', value: Buffer.from(value).toString('base64') };\n }\n if (value instanceof ArrayBuffer) {\n return { __gigadriveType: 'bytes', value: Buffer.from(value).toString('base64') };\n }\n if (Array.isArray(value)) return value.map((item) => encodeBinary(item, seen));\n if (typeof value !== 'object' || value === null) return value;\n if (seen.has(value)) throw new Error('Next.js cache entry contains a circular value');\n seen.add(value);\n const result: Record<string, unknown> = {};\n for (const [key, item] of Object.entries(value)) result[key] = encodeBinary(item, seen);\n seen.delete(value);\n return result;\n};\n\nconst decodeBinary = (value: unknown): unknown => {\n if (Array.isArray(value)) return value.map(decodeBinary);\n if (typeof value !== 'object' || value === null) return value;\n const record = value as Record<string, unknown>;\n if (record.__gigadriveType === 'bytes' && typeof record.value === 'string')\n return Buffer.from(record.value, 'base64');\n return Object.fromEntries(Object.entries(record).map(([key, item]) => [key, decodeBinary(item)]));\n};\n\nconst getAccessToken = async (): Promise<string> => {\n if (cachedToken && cachedToken.expiresAt > Date.now() + 30_000) return cachedToken.value;\n const clientId = process.env.GIGADRIVE_CLIENT_ID;\n const clientSecret = process.env.GIGADRIVE_CLIENT_SECRET;\n if (!clientId || !clientSecret) throw new Error('Gigadrive workload credentials are unavailable');\n\n const response = await fetch(`${apiBaseUrl()}/oauth2/token`, {\n method: 'POST',\n headers: {\n authorization: `Basic ${Buffer.from(`${clientId}:${clientSecret}`).toString('base64')}`,\n 'content-type': 'application/x-www-form-urlencoded',\n },\n body: 'grant_type=client_credentials',\n });\n if (!response.ok) throw new Error(`Gigadrive workload authentication failed with status ${response.status}`);\n const token = (await response.json()) as AccessTokenResponse;\n if (!token.access_token) throw new Error('Gigadrive workload authentication returned no access token');\n cachedToken = {\n value: token.access_token,\n expiresAt: Date.now() + Math.max(60, token.expires_in ?? 300) * 1000,\n };\n return token.access_token;\n};\n\nconst request = async (pathname: string, init: RequestInit, attempt = 0): Promise<Response> => {\n const token = await getAccessToken();\n try {\n const response = await fetch(`${apiBaseUrl()}${pathname}`, {\n ...init,\n headers: {\n authorization: `Bearer ${token}`,\n 'content-type': 'application/json',\n 'x-gigadrive-deployment-id': process.env.GIGADRIVE_DEPLOYMENT_ID ?? process.env.NEBULA_DEPLOYMENT_ID ?? '',\n 'x-gigadrive-build-id': process.env.NEXT_BUILD_ID ?? '',\n ...init.headers,\n },\n });\n if (response.status === 401 && attempt === 0) {\n cachedToken = undefined;\n return request(pathname, init, attempt + 1);\n }\n if (response.status >= 500 && attempt < 2) return request(pathname, init, attempt + 1);\n return response;\n } catch (error) {\n if (attempt < 2) return request(pathname, init, attempt + 1);\n throw error;\n }\n};\n\nconst cachePath = (kind: string, key: string): string =>\n `/internal/runtime-cache/v1/entries/${encodeURIComponent(kind)}/${encodeURIComponent(key)}`;\n\nexport const readRuntimeCache = async (kind: string, key: string): Promise<unknown | undefined> => {\n try {\n const response = await request(cachePath(kind, key), { method: 'GET' });\n if (response.status === 404) return undefined;\n if (!response.ok) return undefined;\n const envelope = (await response.json()) as RuntimeCacheEnvelope;\n return decodeBinary(envelope.value);\n } catch {\n return undefined;\n }\n};\n\nexport const writeRuntimeCache = async (\n kind: string,\n key: string,\n value: unknown,\n tags: readonly string[] = []\n): Promise<void> => {\n const response = await request(cachePath(kind, key), {\n method: 'PUT',\n body: JSON.stringify({ value: encodeBinary(value), tags }),\n });\n if (!response.ok) throw new Error(`Gigadrive runtime cache write failed with status ${response.status}`);\n};\n\nexport const revalidateRuntimeCacheTags = async (\n kind: string,\n tags: readonly string[],\n durations?: { expire?: number }\n): Promise<void> => {\n const response = await request('/internal/runtime-cache/v1/tags/revalidate', {\n method: 'POST',\n body: JSON.stringify({ kind, tags, durations }),\n });\n if (!response.ok) throw new Error(`Gigadrive runtime cache revalidation failed with status ${response.status}`);\n};\n\nexport const getRuntimeCacheTagExpiration = async (kind: string, tags: readonly string[]): Promise<number> => {\n try {\n const response = await request('/internal/runtime-cache/v1/tags/expiration', {\n method: 'POST',\n body: JSON.stringify({ kind, tags }),\n });\n if (!response.ok) return 0;\n const value = (await response.json()) as { expiration?: unknown };\n return typeof value.expiration === 'number' ? value.expiration : 0;\n } catch {\n return 0;\n }\n};\n\nexport const getRuntimeCacheTagState = async (kind: string, tags: readonly string[]): Promise<RuntimeCacheTagState> => {\n try {\n const response = await request('/internal/runtime-cache/v1/tags/state', {\n method: 'POST',\n body: JSON.stringify({ kind, tags }),\n });\n if (!response.ok) return { stale: 0, expired: 0 };\n const value = (await response.json()) as { stale?: unknown; expired?: unknown };\n return {\n stale: typeof value.stale === 'number' ? value.stale : 0,\n expired: typeof value.expired === 'number' ? value.expired : 0,\n };\n } catch {\n return { stale: 0, expired: 0 };\n }\n};\n\nexport const resetRuntimeCacheClientForTests = (): void => {\n cachedToken = undefined;\n};\n","import {\n getRuntimeCacheTagState,\n readRuntimeCache,\n revalidateRuntimeCacheTags,\n writeRuntimeCache,\n} from './nextjs-runtime-cache-client';\n\ninterface IncrementalCacheContext {\n tags?: string[];\n softTags?: string[];\n cacheControl?: unknown;\n}\n\ninterface IncrementalCacheEntry {\n lastModified: number;\n value: unknown | null;\n tags?: string[];\n cacheControl?: unknown;\n}\n\nconst isIncrementalCacheEntry = (value: unknown): value is IncrementalCacheEntry =>\n typeof value === 'object' &&\n value !== null &&\n typeof (value as Partial<IncrementalCacheEntry>).lastModified === 'number' &&\n 'value' in value;\n\n/** Shared Network cache handler for ISR, server responses, fetches, and image metadata. */\nexport default class GigadriveNextCacheHandler {\n private readonly buildEntries = new Map<string, IncrementalCacheEntry>();\n\n async get(key: string, context: IncrementalCacheContext = {}): Promise<IncrementalCacheEntry | null> {\n const entry =\n process.env.GIGADRIVE_NEXT_BUILD === '1'\n ? (this.buildEntries.get(key) ?? null)\n : await readRuntimeCache('incremental', key);\n if (!isIncrementalCacheEntry(entry)) return null;\n const tags = [...new Set([...(entry.tags ?? []), ...(context.tags ?? []), ...(context.softTags ?? [])])];\n if (process.env.GIGADRIVE_NEXT_BUILD === '1' || tags.length === 0) return entry;\n const tagState = await getRuntimeCacheTagState('incremental', tags);\n if (tagState.expired > entry.lastModified) return null;\n return tagState.stale > entry.lastModified ? { ...entry, lastModified: 1 } : entry;\n }\n\n async set(key: string, data: unknown, context: IncrementalCacheContext): Promise<void> {\n const tags = context.tags ?? [];\n const entry = { lastModified: Date.now(), value: data, tags, cacheControl: context.cacheControl };\n if (process.env.GIGADRIVE_NEXT_BUILD === '1') {\n this.buildEntries.set(key, entry);\n return;\n }\n await writeRuntimeCache('incremental', key, entry, tags);\n }\n\n async revalidateTag(tags: string | string[], durations?: { expire?: number }): Promise<void> {\n const normalizedTags = Array.isArray(tags) ? tags : [tags];\n if (process.env.GIGADRIVE_NEXT_BUILD === '1') {\n for (const [key, entry] of this.buildEntries) {\n if (entry.tags?.some((tag) => normalizedTags.includes(tag))) this.buildEntries.delete(key);\n }\n return;\n }\n await revalidateRuntimeCacheTags('incremental', normalizedTags, durations);\n }\n\n resetRequestCache(): void {}\n}\n"],"mappings":"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","names":[]}
|