import fetchRetry from "fetch-retry" import { GraphQLClient } from "graphql-request" import { cache as reactCache } from "react" import { env } from "@/env/server" import { getPreviewHash, isPreviewByUid } from "@/lib/previewContext" import { type CacheTime, getCacheClient } from "@/services/dataCache" import { request as _request } from "./_request" import type { DocumentNode } from "graphql" import type { Data } from "@/types/request" export async function request( query: string | DocumentNode, variables?: Record, cacheOptions?: { key: string | string[] ttl: CacheTime } ): Promise> { const doCall = () => internalRequest(query, variables) if (!cacheOptions) { console.warn("[NO CACHE] for query", query) return doCall() } const cacheKey: string = Array.isArray(cacheOptions.key) ? cacheOptions.key.join("_") : cacheOptions.key const _dataCache = await getCacheClient() return _dataCache.cacheOrGet(cacheKey, doCall, cacheOptions.ttl) } function internalRequest( query: string | DocumentNode, variables?: Record ): Promise> { const shouldUsePreview = variables?.uid ? isPreviewByUid(variables.uid) : false const previewHash = getPreviewHash() const cmsUrl = shouldUsePreview ? env.CMS_PREVIEW_URL : env.CMS_URL // Creating a new client for each request to avoid conflicting parameters const client = new GraphQLClient(cmsUrl, { fetch: reactCache(async function ( url: URL | RequestInfo, params?: RequestInit ) { const wrappedFetch = fetchRetry(fetch, { retries: 3, retryDelay: function (attempt) { return Math.pow(2, attempt) * 150 // 150, 300, 600 }, }) return wrappedFetch(url, params) }), }) const mergedParams = shouldUsePreview && previewHash ? { headers: { live_preview: previewHash, preview_token: env.CMS_PREVIEW_TOKEN, }, } : {} return _request(client, query, variables, mergedParams) }