Add in-page cache capabilities to main resolver

This commit is contained in:
Willian Mitsuda 2021-11-01 04:15:12 -03:00
parent 378d5a0c25
commit e22b564a71
4 changed files with 31 additions and 21 deletions

View File

@ -1,7 +1,7 @@
import { BaseProvider } from "@ethersproject/providers"; import { BaseProvider } from "@ethersproject/providers";
import { IAddressResolver } from "./address-resolver"; import { IAddressResolver } from "./address-resolver";
export type SelectedResolvedName<T> = [IAddressResolver<T>, T]; export type SelectedResolvedName<T> = [IAddressResolver<T>, T] | null;
export class CompositeAddressResolver<T = any> export class CompositeAddressResolver<T = any>
implements IAddressResolver<SelectedResolvedName<T>> implements IAddressResolver<SelectedResolvedName<T>>
@ -23,8 +23,6 @@ export class CompositeAddressResolver<T = any>
} }
} }
return undefined; return null;
// TODO: fallback to address itself
// return address;
} }
} }

View File

@ -32,21 +32,25 @@ resolverRendererRegistry.set(ercTokenResolver, tokenRenderer);
// TODO: implement progressive resolving // TODO: implement progressive resolving
export const batchPopulate = async ( export const batchPopulate = async (
provider: BaseProvider, provider: BaseProvider,
addresses: string[] addresses: string[],
currentMap: ResolvedAddresses | undefined
): Promise<ResolvedAddresses> => { ): Promise<ResolvedAddresses> => {
const solvers: Promise<SelectedResolvedName<any> | undefined>[] = []; const solvers: Promise<SelectedResolvedName<any> | undefined>[] = [];
for (const a of addresses) { const unresolvedAddresses = addresses.filter(
(a) => currentMap?.[a] === undefined
);
for (const a of unresolvedAddresses) {
solvers.push(mainResolver.resolveAddress(provider, a)); solvers.push(mainResolver.resolveAddress(provider, a));
} }
const resultMap: ResolvedAddresses = currentMap ? { ...currentMap } : {};
const results = await Promise.all(solvers); const results = await Promise.all(solvers);
const resultMap: ResolvedAddresses = {};
for (let i = 0; i < results.length; i++) { for (let i = 0; i < results.length; i++) {
const r = results[i]; const r = results[i];
if (r === undefined) { if (r === undefined) {
continue; continue;
} }
resultMap[addresses[i]] = r; resultMap[unresolvedAddresses[i]] = r;
} }
return resultMap; return resultMap;

View File

@ -23,7 +23,7 @@ const AddressOrENSName: React.FC<AddressOrENSNameProps> = ({
const resolvedAddress = resolvedAddresses?.[address]; const resolvedAddress = resolvedAddresses?.[address];
const linkable = address !== selectedAddress; const linkable = address !== selectedAddress;
if (resolvedAddress === undefined) { if (!resolvedAddress) {
return ( return (
<PlainAddress <PlainAddress
address={address} address={address}

View File

@ -1,4 +1,4 @@
import { useState, useEffect } from "react"; import { useState, useEffect, useRef } from "react";
import { JsonRpcProvider } from "@ethersproject/providers"; import { JsonRpcProvider } from "@ethersproject/providers";
import { ProcessedTransaction, TransactionData } from "./types"; import { ProcessedTransaction, TransactionData } from "./types";
import { batchPopulate, ResolvedAddresses } from "./api/address-resolver"; import { batchPopulate, ResolvedAddresses } from "./api/address-resolver";
@ -66,19 +66,27 @@ export const useResolvedAddresses = (
addrCollector: AddressCollector addrCollector: AddressCollector
) => { ) => {
const [names, setNames] = useState<ResolvedAddresses>(); const [names, setNames] = useState<ResolvedAddresses>();
const ref = useRef<ResolvedAddresses | undefined>();
useEffect(() => { useEffect(() => {
ref.current = names;
});
useEffect(
() => {
if (!provider) { if (!provider) {
return; return;
} }
const populate = async () => { const populate = async () => {
const _addresses = addrCollector(); const _addresses = addrCollector();
const _names = await batchPopulate(provider, _addresses); const _names = await batchPopulate(provider, _addresses, ref.current);
setNames(_names); setNames(_names);
}; };
populate(); populate();
}, [provider, addrCollector]); },
// DON'T put names variables in dependency array; this is intentional; useRef
[provider, addrCollector]
);
return names; return names;
}; };