Skip to content

Commit

Permalink
Improve performance of API data transformation
Browse files Browse the repository at this point in the history
Related to #1010
  • Loading branch information
nop33 committed Dec 11, 2024
1 parent 08f17d4 commit 0ac396a
Show file tree
Hide file tree
Showing 14 changed files with 257 additions and 119 deletions.
6 changes: 3 additions & 3 deletions apps/desktop-wallet/src/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ along with the library. If not, see <http://www.gnu.org/licenses/>.

import { localStorageNetworkSettingsMigrated } from '@alephium/shared'
import { useInitializeThrottledClient } from '@alephium/shared-react'
import { ReactNode, useCallback, useEffect } from 'react'
import { memo, ReactNode, useCallback, useEffect } from 'react'
import styled, { css, ThemeProvider } from 'styled-components'

import PersistedQueryCacheVersionStorage from '@/api/persistedCacheVersionStorage'
Expand Down Expand Up @@ -54,7 +54,7 @@ import { GlobalStyle } from '@/style/globalStyles'
import { currentVersion } from '@/utils/app-data'
import { migrateGeneralSettings, migrateNetworkSettings, migrateWalletData } from '@/utils/migration'

const App = () => {
const App = memo(() => {
const theme = useAppSelector((s) => s.global.theme)

useAutoLock()
Expand Down Expand Up @@ -90,7 +90,7 @@ const App = () => {
<AppSpinner />
</ThemeProvider>
)
}
})

export default App

Expand Down
32 changes: 32 additions & 0 deletions apps/desktop-wallet/src/api/apiContext.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
/*
Copyright 2018 - 2024 The Alephium Authors
This file is part of the alephium project.
The library is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
The library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License
along with the library. If not, see <http://www.gnu.org/licenses/>.
*/

import { ReactNode } from 'react'

import { UseFetchWalletBalancesTokensArrayContextProvider } from '@/api/apiDataHooks/wallet/useFetchWalletBalancesTokensArray'
import { UseFetchWalletBalancesTokensByAddressContextProvider } from '@/api/apiDataHooks/wallet/useFetchWalletBalancesTokensByAddress'

const ApiContextProvider = ({ children }: { children: ReactNode }) => (
<UseFetchWalletBalancesTokensArrayContextProvider>
<UseFetchWalletBalancesTokensByAddressContextProvider>
{children}
</UseFetchWalletBalancesTokensByAddressContextProvider>
</UseFetchWalletBalancesTokensArrayContextProvider>
)

export default ApiContextProvider
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
/*
Copyright 2018 - 2024 The Alephium Authors
This file is part of the alephium project.
The library is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
The library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License
along with the library. If not, see <http://www.gnu.org/licenses/>.
*/

import { useQueries, UseQueryResult } from '@tanstack/react-query'

import { addressTokensBalancesQuery, AddressTokensBalancesQueryFnData } from '@/api/queries/addressQueries'
import { useAppSelector } from '@/hooks/redux'
import { useUnsortedAddressesHashes } from '@/hooks/useAddresses'
import { selectCurrentlyOnlineNetworkId } from '@/storage/network/networkSelectors'

export const useFetchWalletBalancesTokens = <T>(
combine: (results: UseQueryResult<AddressTokensBalancesQueryFnData>[]) => {
data: T
isLoading: boolean
isFetching?: boolean
error?: boolean
}
) => {
const networkId = useAppSelector(selectCurrentlyOnlineNetworkId)
const allAddressHashes = useUnsortedAddressesHashes()

const { data, isLoading, isFetching, error } = useQueries({
queries: allAddressHashes.map((addressHash) => addressTokensBalancesQuery({ addressHash, networkId })),
combine
})

return {
data,
isLoading,
isFetching,
error
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ along with the library. If not, see <http://www.gnu.org/licenses/>.

import useMergeAllTokensBalances from '@/api/apiDataHooks/utils/useMergeAllTokensBalances'
import { useFetchWalletBalancesAlphArray } from '@/api/apiDataHooks/wallet/useFetchWalletBalancesAlph'
import { useFetchWalletBalancesTokensArray } from '@/api/apiDataHooks/wallet/useFetchWalletBalancesTokens'
import useFetchWalletBalancesTokensArray from '@/api/apiDataHooks/wallet/useFetchWalletBalancesTokensArray'

interface UseFetchWalletBalancesProps {
includeAlph?: boolean
Expand Down

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
/*
Copyright 2018 - 2024 The Alephium Authors
This file is part of the alephium project.
The library is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
The library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License
along with the library. If not, see <http://www.gnu.org/licenses/>.
*/

import { UseQueryResult } from '@tanstack/react-query'
import { createContext, ReactNode, useContext, useMemo } from 'react'

import { combineError, combineIsFetching, combineIsLoading } from '@/api/apiDataHooks/apiDataHooksUtils'
import { useFetchWalletBalancesTokens } from '@/api/apiDataHooks/utils/useFetchWalletBalancesTokens'
import { ApiContextProps } from '@/api/apiTypes'
import { AddressTokensBalancesQueryFnData } from '@/api/queries/addressQueries'
import { ApiBalances, TokenApiBalances, TokenId } from '@/types/tokens'

const useFetchWalletBalancesTokensArray = () => useContext(UseFetchWalletBalancesTokensArrayContext)

export default useFetchWalletBalancesTokensArray

export const UseFetchWalletBalancesTokensArrayContextProvider = ({ children }: { children: ReactNode }) => {
const { data, isLoading, isFetching, error } = useFetchWalletBalancesTokens(combineBalancesToArray)

const value = useMemo(() => ({ data, isLoading, isFetching, error }), [data, isLoading, isFetching, error])

return (
<UseFetchWalletBalancesTokensArrayContext.Provider value={value}>
{children}
</UseFetchWalletBalancesTokensArrayContext.Provider>
)
}

const UseFetchWalletBalancesTokensArrayContext = createContext<ApiContextProps<TokenApiBalances[]>>({
data: [],
isLoading: false,
isFetching: false,
error: false
})

const combineBalancesToArray = (results: UseQueryResult<AddressTokensBalancesQueryFnData>[]) => {
const tokenBalancesByToken = results.reduce(
(tokensBalances, { data: balances }) => {
balances?.balances.forEach(({ id, totalBalance, lockedBalance, availableBalance }) => {
tokensBalances[id] = {
totalBalance: (BigInt(totalBalance) + BigInt(tokensBalances[id]?.totalBalance ?? 0)).toString(),
lockedBalance: (BigInt(lockedBalance) + BigInt(tokensBalances[id]?.lockedBalance ?? 0)).toString(),
availableBalance: (BigInt(availableBalance) + BigInt(tokensBalances[id]?.availableBalance ?? 0)).toString()
}
})
return tokensBalances
},
{} as Record<TokenId, ApiBalances | undefined>
)

return {
data: Object.keys(tokenBalancesByToken).map((id) => ({
id,
...tokenBalancesByToken[id]
})) as TokenApiBalances[],
...combineIsLoading(results),
...combineIsFetching(results),
...combineError(results)
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
/*
Copyright 2018 - 2024 The Alephium Authors
This file is part of the alephium project.
The library is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
The library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License
along with the library. If not, see <http://www.gnu.org/licenses/>.
*/

import { AddressHash } from '@alephium/shared'
import { UseQueryResult } from '@tanstack/react-query'
import { createContext, ReactNode, useContext, useMemo } from 'react'

import { combineIsLoading } from '@/api/apiDataHooks/apiDataHooksUtils'
import { useFetchWalletBalancesTokens } from '@/api/apiDataHooks/utils/useFetchWalletBalancesTokens'
import { ApiContextProps } from '@/api/apiTypes'
import { AddressTokensBalancesQueryFnData } from '@/api/queries/addressQueries'
import { TokenApiBalances } from '@/types/tokens'

const useFetchWalletBalancesTokensByAddress = () => useContext(UseFetchWalletBalancesTokensByAddressContext)

export default useFetchWalletBalancesTokensByAddress

export const UseFetchWalletBalancesTokensByAddressContextProvider = ({ children }: { children: ReactNode }) => {
const { data, isLoading, isFetching, error } = useFetchWalletBalancesTokens(combineBalancesByAddress)

const value = useMemo(() => ({ data, isLoading, isFetching, error }), [data, isLoading, isFetching, error])

return (
<UseFetchWalletBalancesTokensByAddressContext.Provider value={value}>
{children}
</UseFetchWalletBalancesTokensByAddressContext.Provider>
)
}

const UseFetchWalletBalancesTokensByAddressContext = createContext<
ApiContextProps<Record<AddressHash, TokenApiBalances[] | undefined>>
>({
data: {},
isLoading: false,
isFetching: false,
error: false
})

const combineBalancesByAddress = (results: UseQueryResult<AddressTokensBalancesQueryFnData>[]) => ({
data: results.reduce(
(acc, { data }) => {
if (data) {
acc[data.addressHash] = data.balances
}
return acc
},
{} as Record<AddressHash, TokenApiBalances[] | undefined>
),
...combineIsLoading(results)
})
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ along with the library. If not, see <http://www.gnu.org/licenses/>.
import useFetchTokensSeparatedByType from '@/api/apiDataHooks/utils/useFetchTokensSeparatedByType'
import useMergeAllTokensBalances from '@/api/apiDataHooks/utils/useMergeAllTokensBalances'
import { useFetchWalletBalancesAlphArray } from '@/api/apiDataHooks/wallet/useFetchWalletBalancesAlph'
import { useFetchWalletBalancesTokensArray } from '@/api/apiDataHooks/wallet/useFetchWalletBalancesTokens'
import useFetchWalletBalancesTokensArray from '@/api/apiDataHooks/wallet/useFetchWalletBalancesTokensArray'

interface UseFetchWalletTokensByType {
includeAlph: boolean
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ import useFetchListedFtsWorth from '@/api/apiDataHooks/utils/useFetchListedFtsWo
import useFetchTokensSeparatedByListing from '@/api/apiDataHooks/utils/useFetchTokensSeparatedByListing'
import useMergeAllTokensBalances from '@/api/apiDataHooks/utils/useMergeAllTokensBalances'
import { useFetchWalletBalancesAlphArray } from '@/api/apiDataHooks/wallet/useFetchWalletBalancesAlph'
import { useFetchWalletBalancesTokensArray } from '@/api/apiDataHooks/wallet/useFetchWalletBalancesTokens'
import useFetchWalletBalancesTokensArray from '@/api/apiDataHooks/wallet/useFetchWalletBalancesTokensArray'

const useFetchWalletWorth = () => {
const {
Expand Down
Loading

0 comments on commit 0ac396a

Please sign in to comment.