From fb15d63e609cfc829173a372c16a05b1a27abc16 Mon Sep 17 00:00:00 2001 From: simodrws Date: Wed, 14 Jun 2023 18:32:05 +0200 Subject: [PATCH] feat: more refactor, session cleanup --- .../masa-client-provider.tsx | 6 +- src/refactor/masa-feature/use-session.ts | 96 +++++++++++-------- src/refactor/masa-provider.tsx | 2 +- src/refactor/masanew.stories.tsx | 29 +++--- .../wallet-client/wallet/use-wallet.ts | 6 +- 5 files changed, 79 insertions(+), 60 deletions(-) rename src/refactor/{masa-client => }/masa-client-provider.tsx (84%) diff --git a/src/refactor/masa-client/masa-client-provider.tsx b/src/refactor/masa-client-provider.tsx similarity index 84% rename from src/refactor/masa-client/masa-client-provider.tsx rename to src/refactor/masa-client-provider.tsx index 9b223879..4f19c47a 100644 --- a/src/refactor/masa-client/masa-client-provider.tsx +++ b/src/refactor/masa-client-provider.tsx @@ -1,7 +1,7 @@ import React, { ReactNode, createContext, useContext, useMemo } from 'react'; -import { useMasaClient } from './use-masa-client'; -import { useIdentity } from '../masa-feature/use-identity'; -import { useSession } from '../masa-feature/use-session'; +import { useMasaClient } from './masa-client/use-masa-client'; +import { useIdentity } from './masa-feature/use-identity'; +import { useSession } from './masa-feature/use-session'; export interface MasaClientProviderValue { masa?: ReturnType['sdk']; diff --git a/src/refactor/masa-feature/use-session.ts b/src/refactor/masa-feature/use-session.ts index 259c4bb2..8205ec8c 100644 --- a/src/refactor/masa-feature/use-session.ts +++ b/src/refactor/masa-feature/use-session.ts @@ -5,26 +5,32 @@ import { useWallet } from '../wallet-client/wallet/use-wallet'; import { useMasaClient } from '../masa-client/use-masa-client'; import { QcContext } from '../masa-provider'; +// * NOTE: react-query does not allow us to pass undefined as a function return, +// * NOTE: so we need to convert an undefined result in every query to null +// * TODO: split up the queries, pass context via function variable to avoid dependency cycle +// * FIXME: we are getting the session 3 times on every change, we should only get it once export const useSession = () => { const { address, isDisconnected, previousAddress } = useWallet(); const { masa } = useMasaClient(); const queryClient = useQueryClient({ context: QcContext }); - // console.log({ address, previousAddress }); - const [{ loading: isCheckingSession }, checkSession] = + + // * callbacks + const [{ loading: isCheckingSession }, checkSessionAsync] = useAsyncFn(async () => { if (!address) return null; if (!masa) return null; + if (isDisconnected) return null; const hasSesh = await masa?.session.checkLogin(); if (hasSesh !== undefined || hasSesh !== null) return hasSesh; return null; - }, [masa, address]); + }, [masa, address, isDisconnected]); - const [{ loading: isLoggingIn }, loginSession] = useAsyncFn(async () => { + const [, loginSessionAsync] = useAsyncFn(async () => { if (!masa) return null; if (!address) return null; - + if (isDisconnected) return null; const loginObj = await masa.session.login(); if (!loginObj) { @@ -35,7 +41,7 @@ export const useSession = () => { userId: string; address: string; }; - }, [masa, address]); + }, [masa, address, isDisconnected]); const [, getSessionAsync] = useAsyncFn(async () => { if (!masa) return null; @@ -50,17 +56,19 @@ export const useSession = () => { return seshFromGet; }, [address, masa]); + // * queries const { - data: sessionFromGet, + data: session, isLoading: isFetchingSession, - refetch: getSessionCB, + refetch: getSession, + isRefetching: isRefetchingSession, } = useQuery({ - queryKey: ['session-obj', address], + queryKey: ['session', address], enabled: false, context: QcContext, onSuccess: async (data: ISession | null) => { if (data) { - const resultCheck = await checkSession(); + const resultCheck = await checkSessionAsync(); if (!resultCheck) { // await queryClient.invalidateQueries(['session-check', address]); } @@ -69,39 +77,43 @@ export const useSession = () => { queryFn: async () => getSessionAsync(), }); - const { data: hasSession, refetch: checkLogin } = useQuery({ + const { + data: hasSession, + refetch: checkLogin, + isRefetching: isCheckingLogin, + } = useQuery({ queryKey: ['session-check', address], enabled: !!masa, context: QcContext, onSuccess: async (data: boolean) => { switch (data) { case true: { - const checkedLogin = await checkSession(); + const checkedLogin = await checkSessionAsync(); if (!checkedLogin) { - await queryClient.invalidateQueries(['session-obj', address]); - await queryClient.invalidateQueries(['session-check', address]); await queryClient.invalidateQueries(['session', address]); + await queryClient.invalidateQueries(['session-check', address]); + await queryClient.invalidateQueries(['session-login', address]); return; } - if (sessionFromGet && address === sessionFromGet?.user.address) { + if (session && address === session?.user.address) { return; } - await queryClient.invalidateQueries(['session-obj', address]); - await queryClient.fetchQuery(['session-obj', address]); + await queryClient.invalidateQueries(['session', address]); + await queryClient.fetchQuery(['session', address]); break; } case false: { + queryClient.setQueryData(['session-login', address], null); queryClient.setQueryData(['session', address], null); - queryClient.setQueryData(['session-obj', address], null); break; } case undefined: { + queryClient.setQueryData(['session-login', address], null); queryClient.setQueryData(['session', address], null); - queryClient.setQueryData(['session-obj', address], null); break; } default: { @@ -114,7 +126,7 @@ export const useSession = () => { if (!address) return false; if (!masa) return false; - const hasSesh = await checkSession(); + const hasSesh = await checkSessionAsync(); if (hasSesh) { return hasSesh; @@ -124,18 +136,19 @@ export const useSession = () => { }, }); + // * logout callback const [{ loading: isLoggingOut }, logoutSession] = useAsyncFn(async () => { if (hasSession) { await masa?.session.logout(); } await queryClient.invalidateQueries(['session-check', address]); + await queryClient.invalidateQueries(['session-login', address]); await queryClient.invalidateQueries(['session', address]); - await queryClient.invalidateQueries(['session-obj', address]); }, [masa, queryClient, address, hasSession]); - const { data: session, refetch: getSession } = useQuery({ - queryKey: ['session', address], + const { refetch: loginSession, isRefetching: isLoggingIn } = useQuery({ + queryKey: ['session-login', address], enabled: false, context: QcContext, refetchOnMount: false, @@ -145,23 +158,13 @@ export const useSession = () => { }, queryFn: async () => { - const hasIt = await checkSession(); - - if (hasIt) { - const sesshFromGet = await masa?.session.getSession(); + if (isDisconnected) return null; + const hasIt = await checkSessionAsync(); - if (sesshFromGet === undefined || sesshFromGet === null) { - return null; - } - - return sesshFromGet; - } - - const sesh = await loginSession(); - - if (sesh === undefined || sesh === null) return null; + if (hasIt) return null; - return sesh; + await loginSessionAsync(); + return null; }, }); @@ -169,6 +172,7 @@ export const useSession = () => { if (isDisconnected) { await logoutSession(); } + if (previousAddress !== address) { await checkLogin(); } @@ -176,17 +180,25 @@ export const useSession = () => { return { session, - sessionFromGet, - getSessionCB, + getSession, isFetchingSession, + isRefetchingSession, hasSession, - checkSession, + checkSessionAsync, isCheckingSession, + isCheckingLogin, loginSession, logoutSession, isLoggingIn, isLoggingOut, - getSession, + isLoggedIn: hasSession, checkLogin, + isLoadingSession: + isLoggingIn || + isLoggingOut || + isFetchingSession || + isCheckingLogin || + isCheckingSession || + isRefetchingSession, }; }; diff --git a/src/refactor/masa-provider.tsx b/src/refactor/masa-provider.tsx index 485e4709..aa48afbb 100644 --- a/src/refactor/masa-provider.tsx +++ b/src/refactor/masa-provider.tsx @@ -5,7 +5,7 @@ import MasaBaseProvider from './base-provider'; import { MasaReactConfig } from './config'; import WalletProvider from './wallet-client/wallet-client-provider'; import WagmiRainbowkitProvider from './wallet-client/wagmi-rainbowkit-provider'; -import MasaClientProvider from './masa-client/masa-client-provider'; +import MasaClientProvider from './masa-client-provider'; import { createQueryClient } from './masa-client/query-client'; diff --git a/src/refactor/masanew.stories.tsx b/src/refactor/masanew.stories.tsx index 55d04202..7096f22a 100644 --- a/src/refactor/masanew.stories.tsx +++ b/src/refactor/masanew.stories.tsx @@ -225,15 +225,16 @@ const MasaInfo = () => { // const { identity, isLoadingIdentity } = useIdentity(); const { session, - // loginSession, + loginSession, logoutSession, isLoggingIn, isLoggingOut, - sessionFromGet, + hasSession, - getSession, + isLoadingSession, checkLogin, } = useSession(); + const { isDisconnected } = useWallet(); // console.log('STORY', { hasSession, session }); return ( @@ -251,6 +252,7 @@ const MasaInfo = () => {
    • Session

      +
    • isLoadingSession: {String(isLoadingSession)}
    • hasSession: {String(hasSession)}
    • isLoggingIn: {String(isLoggingIn)}
    • isLoggingOut: {String(isLoggingOut)}
    • @@ -258,10 +260,7 @@ const MasaInfo = () => { Session:
      {JSON.stringify(session, null, 4)} -
    • - Session From Get:
      - {JSON.stringify(sessionFromGet, null, 4)} -
    • + {/*
    • Session User: {JSON.stringify(session?.user, null, 2)}
    • Session Challenge: {session?.challenge}
    • session cookie: {JSON.stringify(session?.cookie, null, 2)}
    • */} @@ -271,9 +270,9 @@ const MasaInfo = () => {
      • @@ -288,12 +287,20 @@ const MasaInfo = () => {
      • */}
      • -
      • -
      • diff --git a/src/refactor/wallet-client/wallet/use-wallet.ts b/src/refactor/wallet-client/wallet/use-wallet.ts index b223507a..dcc83acc 100644 --- a/src/refactor/wallet-client/wallet/use-wallet.ts +++ b/src/refactor/wallet-client/wallet/use-wallet.ts @@ -19,7 +19,9 @@ const useWallet = () => { const { openAccountModal } = useAccountModal(); const { isConnected, isConnecting, isDisconnected, connector, address } = useAccount(); - const [previousAddress, setPreviousAddress] = useState(address); + const [previousAddress, setPreviousAddress] = useState< + `0x${string}` | undefined + >(undefined); const [compareAddress, setCompareAddress] = useState(address); const { data: signer, isLoading: isLoadingSigner } = useSigner(); const { disconnect, disconnectAsync } = useDisconnect(); @@ -39,8 +41,6 @@ const useWallet = () => { setPreviousAddress(undefined); } - console.log('addr changed', { address }); - if (compareAddress !== address) { setPreviousAddress(compareAddress); setCompareAddress(address);