diff --git a/components/ConvexClientProvider.tsx b/components/ConvexClientProvider.tsx index 04eb04c..b4b5a37 100644 --- a/components/ConvexClientProvider.tsx +++ b/components/ConvexClientProvider.tsx @@ -1,16 +1,22 @@ 'use client'; -import { ReactNode, useCallback, useState } from 'react'; +import { ReactNode, useCallback, useState, useRef } from 'react'; import { ConvexReactClient } from 'convex/react'; import { ConvexProviderWithAuth } from 'convex/react'; import { AuthKitProvider, useAuth, useAccessToken } from '@workos-inc/authkit-nextjs/components'; +const noop = () => {}; + export function ConvexClientProvider({ children }: { children: ReactNode }) { const [convex] = useState(() => { - return new ConvexReactClient(process.env.NEXT_PUBLIC_CONVEX_URL!); + const client = new ConvexReactClient(process.env.NEXT_PUBLIC_CONVEX_URL!); + return client; }); + return ( - + // Prevent AuthKit's default window.location.reload() on session expiration. + // We handle auth state gracefully via Convex token refresh and middleware checks. + {children} @@ -20,7 +26,9 @@ export function ConvexClientProvider({ children }: { children: ReactNode }) { function useAuthFromAuthKit() { const { user, loading: isLoading } = useAuth(); - const { getAccessToken, refresh } = useAccessToken(); + const { getAccessToken, accessToken, refresh } = useAccessToken(); + const accessTokenRef = useRef(undefined); + accessTokenRef.current = accessToken; const isAuthenticated = !!user; @@ -31,17 +39,18 @@ function useAuthFromAuthKit() { } try { - if (forceRefreshToken) { - return (await refresh()) ?? null; - } - - return (await getAccessToken()) ?? null; + // If Convex requests a forced refresh (e.g., token was rejected by server), + // always get a fresh token. Otherwise, return cached token if still valid. + return forceRefreshToken ? ((await refresh()) ?? null) : ((await getAccessToken()) ?? null); } catch (error) { - console.error('Failed to get access token:', error); - return null; + // On network errors during laptop wake, fall back to cached token. + // Even if expired, Convex will treat it like null and clear auth. + // AuthKit's tokenStore schedules automatic retries in the background. + console.log('[Convex Auth] Using cached token during network issues'); + return accessTokenRef.current ?? null; } }, - [user, refresh, getAccessToken], + [user, getAccessToken, refresh], ); return { diff --git a/convex/_generated/api.d.ts b/convex/_generated/api.d.ts index 6a067d5..bdff014 100644 --- a/convex/_generated/api.d.ts +++ b/convex/_generated/api.d.ts @@ -8,12 +8,13 @@ * @module */ +import type * as myFunctions from "../myFunctions.js"; + import type { ApiFromModules, FilterApi, FunctionReference, } from "convex/server"; -import type * as myFunctions from "../myFunctions.js"; /** * A utility for referencing Convex functions in your app's API. @@ -26,11 +27,15 @@ import type * as myFunctions from "../myFunctions.js"; declare const fullApi: ApiFromModules<{ myFunctions: typeof myFunctions; }>; +declare const fullApiWithMounts: typeof fullApi; + export declare const api: FilterApi< - typeof fullApi, + typeof fullApiWithMounts, FunctionReference >; export declare const internal: FilterApi< - typeof fullApi, + typeof fullApiWithMounts, FunctionReference >; + +export declare const components: {}; diff --git a/convex/_generated/api.js b/convex/_generated/api.js index 3f9c482..44bf985 100644 --- a/convex/_generated/api.js +++ b/convex/_generated/api.js @@ -8,7 +8,7 @@ * @module */ -import { anyApi } from "convex/server"; +import { anyApi, componentsGeneric } from "convex/server"; /** * A utility for referencing Convex functions in your app's API. @@ -20,3 +20,4 @@ import { anyApi } from "convex/server"; */ export const api = anyApi; export const internal = anyApi; +export const components = componentsGeneric(); diff --git a/convex/_generated/server.d.ts b/convex/_generated/server.d.ts index 7f337a4..b5c6828 100644 --- a/convex/_generated/server.d.ts +++ b/convex/_generated/server.d.ts @@ -10,6 +10,7 @@ import { ActionBuilder, + AnyComponents, HttpActionBuilder, MutationBuilder, QueryBuilder, @@ -18,9 +19,15 @@ import { GenericQueryCtx, GenericDatabaseReader, GenericDatabaseWriter, + FunctionReference, } from "convex/server"; import type { DataModel } from "./dataModel.js"; +type GenericCtx = + | GenericActionCtx + | GenericMutationCtx + | GenericQueryCtx; + /** * Define a query in this Convex app's public API. * diff --git a/convex/_generated/server.js b/convex/_generated/server.js index 566d485..4a21df4 100644 --- a/convex/_generated/server.js +++ b/convex/_generated/server.js @@ -16,6 +16,7 @@ import { internalActionGeneric, internalMutationGeneric, internalQueryGeneric, + componentsGeneric, } from "convex/server"; /**