From 69e99eb1446a89979c34d06b66e4cd3cd9a24415 Mon Sep 17 00:00:00 2001 From: memoyil <2213635+memoyil@users.noreply.github.com> Date: Wed, 13 Nov 2024 10:14:46 +0100 Subject: [PATCH] fix: List cache with different keys returns same result --- apps/web/src/state/lists/hooks.ts | 28 ++++++++++++++++++---------- packages/tokens/src/helpers/index.ts | 8 ++++---- 2 files changed, 22 insertions(+), 14 deletions(-) diff --git a/apps/web/src/state/lists/hooks.ts b/apps/web/src/state/lists/hooks.ts index 8eb8242a4102e..9822815cacb91 100644 --- a/apps/web/src/state/lists/hooks.ts +++ b/apps/web/src/state/lists/hooks.ts @@ -1,7 +1,7 @@ import { ChainId } from '@pancakeswap/chains' import { TokenAddressMap as TTokenAddressMap, TokenInfo, TokenList, WrappedTokenInfo } from '@pancakeswap/token-lists' import { ListsState } from '@pancakeswap/token-lists/react' -import { EMPTY_LIST } from '@pancakeswap/tokens' +import { createEmptyList, EMPTY_LIST } from '@pancakeswap/tokens' import { enumValues } from '@pancakeswap/utils/enumValues' import { DEFAULT_LIST_OF_LISTS, @@ -70,7 +70,7 @@ export const combinedCurrenciesMapFromActiveUrlsAtom = atom(() => { }) const combineTokenMaps = (lists: ListsState['byUrl'], urls: string[]): any => { - if (!urls) return EMPTY_LIST + if (urls?.length) return EMPTY_LIST return ( [...urls] // sort by priority so top priority goes last @@ -79,13 +79,16 @@ const combineTokenMaps = (lists: ListsState['byUrl'], urls: string[]): any => { const current = lists[currentUrl]?.current if (!current) return allTokens try { - const newTokens = Object.assign(listToTokenMap(current, 'address')) - return combineMaps(allTokens, newTokens) + const newTokens = listToTokenMap(current, 'address') + for (const chainId of enumValues(ChainId)) { + Object.assign(allTokens[chainId], newTokens[chainId]) + } + return allTokens } catch (error) { console.error('Could not show token list due to error', error) return allTokens } - }, EMPTY_LIST) + }, createEmptyList()) ) } @@ -149,11 +152,11 @@ export const combinedTokenMapFromWarningUrlsAtom = atom((get) => { return combineMaps(localUnsupportedListMap, loadedUnsupportedListMap) }) -const listCache: WeakMap | null = - typeof WeakMap !== 'undefined' ? new WeakMap() : null +const listCache: WeakMap> | null = + typeof WeakMap !== 'undefined' ? new WeakMap>() : null -export function listToTokenMap(list: TokenList, key?: string): TokenAddressMap { - const result = listCache?.get(list) +export function listToTokenMap(list: TokenList, key: string): TokenAddressMap { + const result = listCache?.get(list)?.get(key) if (result) return result const tokenMap: WrappedTokenInfo[] = uniqBy( @@ -184,7 +187,12 @@ export function listToTokenMap(list: TokenList, key?: string): TokenAddressMap { } }) - listCache?.set(list, tokenAddressMap) + let keyCache = listCache?.get(list) + if (!keyCache) { + keyCache = new Map() + listCache?.set(list, keyCache) + } + keyCache.set(key, tokenAddressMap) return tokenAddressMap } diff --git a/packages/tokens/src/helpers/index.ts b/packages/tokens/src/helpers/index.ts index 6fd32036505ba..a7f0de1cb99a0 100644 --- a/packages/tokens/src/helpers/index.ts +++ b/packages/tokens/src/helpers/index.ts @@ -5,18 +5,18 @@ import { TokenAddressMap } from '@pancakeswap/token-lists' export * from './getTokensByChain' -const createEmptyList = () => { - const list = {} as Record[ChainId]> +export const createEmptyList = () => { + const list = {} as Record[ChainId]>> for (const chainId of enumValues(ChainId)) { list[chainId] = {} } - return list as TokenAddressMap + return list as Readonly> } /** * An empty result, useful as a default. */ -export const EMPTY_LIST: TokenAddressMap = createEmptyList() +export const EMPTY_LIST: Readonly> = createEmptyList() export function serializeTokens(unserializedTokens: any) { const serializedTokens = Object.keys(unserializedTokens).reduce((accum, key) => {