import { cache as reactCache } from "react"; import { HttpLink,ApolloLink } from "@apollo/client"; import { SetContextLink } from "@apollo/client/link/context"; import { ApolloClient, InMemoryCache, } from "@apollo/client-integration-nextjs"; import { ErrorLink } from "@apollo/client/link/error"; import {CombinedProtocolErrors} from "@apollo/client/errors"; import {handleErrorForErrorLink} from "@/lib/ApolloErrorHandler"; import { getSession } from "next-auth/react"; import { getCartToken } from "@/utils/getCartToken"; import { BagistoSession } from "@/types/types"; // 这里注册的是客户端使用的apollo client CombinedProtocolErrors.formatMessage = (errors,{defaultFormatMessage})=>{ return "[Subscription Error] " + defaultFormatMessage(errors); }; let sessionCache: { session: BagistoSession | null; timestamp: number } | null = null; const SESSION_CACHE_TTL = 5000; const getSessionForRequest = reactCache(async () => { return (await getSession()) as BagistoSession | null; }); async function getCachedSession(): Promise { if (typeof window === "undefined") { return getSessionForRequest(); } const now = Date.now(); if (sessionCache && now - sessionCache.timestamp < SESSION_CACHE_TTL) { return sessionCache.session; } const session = (await getSession()) as BagistoSession | null; sessionCache = { session, timestamp: now }; return session; } export default function makeClient() { const httpLink = new HttpLink({ uri: "/api/graphql", credentials: "include", /*fetchOptions: { // Optional: Next.js-specific fetch options // Note: This doesn't work with `export const dynamic = "force-static"` },*/ }); const errorLink = new ErrorLink(({ error }) => { handleErrorForErrorLink(error); }); const authLink = new SetContextLink(async (prevContext) => { const session = await getCachedSession(); const userToken = session?.user?.accessToken; const guestToken = !userToken ? getCartToken() : null; const token = userToken || guestToken; return { headers: { ...prevContext.headers, ...(token && { Authorization: `Bearer ${token}` }), "Content-Type": "application/json", }, }; }); // httpLink 要放在最后 const link = ApolloLink.from([errorLink, authLink, httpLink]); return new ApolloClient({ // ssrMode, link, cache: new InMemoryCache(), // defaultOptions: { // watchQuery: { // fetchPolicy: "cache-first", // nextFetchPolicy: "cache-first", // }, // query: { // fetchPolicy: "cache-first", // }, // }, }); }