Cache promises (#17)
This commit is contained in:
parent
cecf600e58
commit
599e54c415
|
@ -1,6 +1,6 @@
|
||||||
{
|
{
|
||||||
"name": "@project-serum/swap-ui",
|
"name": "@project-serum/swap-ui",
|
||||||
"version": "0.1.0-alpha.10",
|
"version": "0.1.0-alpha.11",
|
||||||
"main": "dist/index.js",
|
"main": "dist/index.js",
|
||||||
"types": "dist/index.d.ts",
|
"types": "dist/index.d.ts",
|
||||||
"homepage": ".",
|
"homepage": ".",
|
||||||
|
|
|
@ -27,8 +27,6 @@ export const BASE_TAKER_FEE_BPS = 0.0022;
|
||||||
type DexContext = {
|
type DexContext = {
|
||||||
// Maps market address to open orders accounts.
|
// Maps market address to open orders accounts.
|
||||||
openOrders: Map<string, Array<OpenOrders>>;
|
openOrders: Map<string, Array<OpenOrders>>;
|
||||||
marketCache: Map<string, Market>;
|
|
||||||
setMarketCache: (c: Map<string, Market>) => void;
|
|
||||||
swapClient: SwapClient;
|
swapClient: SwapClient;
|
||||||
};
|
};
|
||||||
const _DexContext = React.createContext<DexContext | null>(null);
|
const _DexContext = React.createContext<DexContext | null>(null);
|
||||||
|
@ -37,9 +35,6 @@ export function DexContextProvider(props: any) {
|
||||||
const [ooAccounts, setOoAccounts] = useState<Map<string, Array<OpenOrders>>>(
|
const [ooAccounts, setOoAccounts] = useState<Map<string, Array<OpenOrders>>>(
|
||||||
new Map()
|
new Map()
|
||||||
);
|
);
|
||||||
const [marketCache, setMarketCache] = useState<Map<string, Market>>(
|
|
||||||
new Map()
|
|
||||||
);
|
|
||||||
const swapClient = props.swapClient;
|
const swapClient = props.swapClient;
|
||||||
|
|
||||||
// Two operations:
|
// Two operations:
|
||||||
|
@ -73,31 +68,35 @@ export function DexContextProvider(props: any) {
|
||||||
"Too many markets. Please file an issue to update this"
|
"Too many markets. Please file an issue to update this"
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
const marketAccounts = (
|
(
|
||||||
await anchor.utils.getMultipleAccounts(
|
await anchor.utils.getMultipleAccounts(
|
||||||
swapClient.program.provider.connection,
|
swapClient.program.provider.connection,
|
||||||
// @ts-ignore
|
// @ts-ignore
|
||||||
[...markets].map((m) => new PublicKey(m))
|
[...markets].map((m) => new PublicKey(m))
|
||||||
)
|
)
|
||||||
).map((programAccount) => {
|
)
|
||||||
|
.map((programAccount) => {
|
||||||
return {
|
return {
|
||||||
publicKey: programAccount?.publicKey,
|
publicKey: programAccount?.publicKey,
|
||||||
account: new Market(
|
account: new Promise<Market>((resolve) =>
|
||||||
Market.getLayout(DEX_PID).decode(programAccount?.account.data),
|
resolve(
|
||||||
|
new Market(
|
||||||
|
Market.getLayout(DEX_PID).decode(
|
||||||
|
programAccount?.account.data
|
||||||
|
),
|
||||||
-1, // Not used so don't bother fetching.
|
-1, // Not used so don't bother fetching.
|
||||||
-1, // Not used so don't bother fetching.
|
-1, // Not used so don't bother fetching.
|
||||||
swapClient.program.provider.opts,
|
swapClient.program.provider.opts,
|
||||||
DEX_PID
|
DEX_PID
|
||||||
|
)
|
||||||
|
)
|
||||||
),
|
),
|
||||||
};
|
};
|
||||||
|
})
|
||||||
|
.forEach((m) => {
|
||||||
|
_MARKET_CACHE.set(m.publicKey!.toString(), m.account);
|
||||||
});
|
});
|
||||||
setMarketCache((marketCache) => {
|
|
||||||
const newMarketCache = new Map(marketCache);
|
|
||||||
marketAccounts.forEach((m) => {
|
|
||||||
newMarketCache.set(m.publicKey!.toString(), m.account);
|
|
||||||
});
|
|
||||||
return newMarketCache;
|
|
||||||
});
|
|
||||||
setOoAccounts(newOoAccounts);
|
setOoAccounts(newOoAccounts);
|
||||||
});
|
});
|
||||||
}, [
|
}, [
|
||||||
|
@ -109,8 +108,6 @@ export function DexContextProvider(props: any) {
|
||||||
<_DexContext.Provider
|
<_DexContext.Provider
|
||||||
value={{
|
value={{
|
||||||
openOrders: ooAccounts,
|
openOrders: ooAccounts,
|
||||||
marketCache,
|
|
||||||
setMarketCache,
|
|
||||||
swapClient,
|
swapClient,
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
|
@ -134,28 +131,25 @@ export function useOpenOrders(): Map<string, Array<OpenOrders>> {
|
||||||
|
|
||||||
// Lazy load a given market.
|
// Lazy load a given market.
|
||||||
export function useMarket(market?: PublicKey): Market | undefined {
|
export function useMarket(market?: PublicKey): Market | undefined {
|
||||||
const ctx = useDexContext();
|
const { swapClient } = useDexContext();
|
||||||
|
|
||||||
const asyncMarket = useAsync(async () => {
|
const asyncMarket = useAsync(async () => {
|
||||||
if (!market) {
|
if (!market) {
|
||||||
return undefined;
|
return undefined;
|
||||||
}
|
}
|
||||||
if (ctx.marketCache.get(market.toString())) {
|
if (_MARKET_CACHE.get(market.toString())) {
|
||||||
return ctx.marketCache.get(market.toString());
|
return _MARKET_CACHE.get(market.toString());
|
||||||
}
|
}
|
||||||
const marketClient = await Market.load(
|
const marketClient = Market.load(
|
||||||
ctx.swapClient.program.provider.connection,
|
swapClient.program.provider.connection,
|
||||||
market,
|
market,
|
||||||
undefined,
|
undefined,
|
||||||
DEX_PID
|
DEX_PID
|
||||||
);
|
);
|
||||||
|
|
||||||
let cache = new Map(ctx.marketCache);
|
_MARKET_CACHE.set(market.toString(), marketClient);
|
||||||
cache.set(market.toString(), marketClient);
|
|
||||||
ctx.setMarketCache(cache);
|
|
||||||
|
|
||||||
return marketClient;
|
return marketClient;
|
||||||
}, [ctx.swapClient.program.provider.connection, market]);
|
}, [swapClient.program.provider.connection, market]);
|
||||||
|
|
||||||
if (asyncMarket.result) {
|
if (asyncMarket.result) {
|
||||||
return asyncMarket.result;
|
return asyncMarket.result;
|
||||||
|
@ -178,15 +172,17 @@ export function useOrderbook(market?: PublicKey): Orderbook | undefined {
|
||||||
return _ORDERBOOK_CACHE.get(market.toString());
|
return _ORDERBOOK_CACHE.get(market.toString());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const orderbook = new Promise<Orderbook>(async (resolve) => {
|
||||||
const [bids, asks] = await Promise.all([
|
const [bids, asks] = await Promise.all([
|
||||||
marketClient.loadBids(swapClient.program.provider.connection),
|
marketClient.loadBids(swapClient.program.provider.connection),
|
||||||
marketClient.loadAsks(swapClient.program.provider.connection),
|
marketClient.loadAsks(swapClient.program.provider.connection),
|
||||||
]);
|
]);
|
||||||
|
|
||||||
const orderbook = {
|
resolve({
|
||||||
bids,
|
bids,
|
||||||
asks,
|
asks,
|
||||||
};
|
});
|
||||||
|
});
|
||||||
|
|
||||||
_ORDERBOOK_CACHE.set(market.toString(), orderbook);
|
_ORDERBOOK_CACHE.set(market.toString(), orderbook);
|
||||||
|
|
||||||
|
@ -199,9 +195,9 @@ export function useOrderbook(market?: PublicKey): Orderbook | undefined {
|
||||||
if (marketClient?.bidsAddress) {
|
if (marketClient?.bidsAddress) {
|
||||||
listener = swapClient.program.provider.connection.onAccountChange(
|
listener = swapClient.program.provider.connection.onAccountChange(
|
||||||
marketClient?.bidsAddress,
|
marketClient?.bidsAddress,
|
||||||
(info) => {
|
async (info) => {
|
||||||
const bids = OrderbookSide.decode(marketClient, info.data);
|
const bids = OrderbookSide.decode(marketClient, info.data);
|
||||||
const orderbook = _ORDERBOOK_CACHE.get(
|
const orderbook = await _ORDERBOOK_CACHE.get(
|
||||||
marketClient.address.toString()
|
marketClient.address.toString()
|
||||||
);
|
);
|
||||||
const oldBestBid = orderbook?.bids.items(true).next().value;
|
const oldBestBid = orderbook?.bids.items(true).next().value;
|
||||||
|
@ -237,9 +233,9 @@ export function useOrderbook(market?: PublicKey): Orderbook | undefined {
|
||||||
if (marketClient?.asksAddress) {
|
if (marketClient?.asksAddress) {
|
||||||
listener = swapClient.program.provider.connection.onAccountChange(
|
listener = swapClient.program.provider.connection.onAccountChange(
|
||||||
marketClient?.asksAddress,
|
marketClient?.asksAddress,
|
||||||
(info) => {
|
async (info) => {
|
||||||
const asks = OrderbookSide.decode(marketClient, info.data);
|
const asks = OrderbookSide.decode(marketClient, info.data);
|
||||||
const orderbook = _ORDERBOOK_CACHE.get(
|
const orderbook = await _ORDERBOOK_CACHE.get(
|
||||||
marketClient.address.toString()
|
marketClient.address.toString()
|
||||||
);
|
);
|
||||||
const oldBestOffer = orderbook?.asks.items(false).next().value;
|
const oldBestOffer = orderbook?.asks.items(false).next().value;
|
||||||
|
@ -276,8 +272,6 @@ export function useOrderbook(market?: PublicKey): Orderbook | undefined {
|
||||||
return undefined;
|
return undefined;
|
||||||
}
|
}
|
||||||
|
|
||||||
const _ORDERBOOK_CACHE = new Map<string, Orderbook>();
|
|
||||||
|
|
||||||
export function useMarketName(market: PublicKey): string | null {
|
export function useMarketName(market: PublicKey): string | null {
|
||||||
const tokenMap = useTokenMap();
|
const tokenMap = useTokenMap();
|
||||||
const marketClient = useMarket(market);
|
const marketClient = useMarket(market);
|
||||||
|
@ -538,3 +532,6 @@ type Bbo = {
|
||||||
bestOffer?: number;
|
bestOffer?: number;
|
||||||
mid?: number;
|
mid?: number;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const _ORDERBOOK_CACHE = new Map<string, Promise<Orderbook>>();
|
||||||
|
const _MARKET_CACHE = new Map<string, Promise<Market>>();
|
||||||
|
|
|
@ -130,7 +130,7 @@ export function useMint(mint?: PublicKey): MintInfo | undefined | null {
|
||||||
TOKEN_PROGRAM_ID,
|
TOKEN_PROGRAM_ID,
|
||||||
new Account()
|
new Account()
|
||||||
);
|
);
|
||||||
const mintInfo = await mintClient.getMintInfo();
|
const mintInfo = mintClient.getMintInfo();
|
||||||
_MINT_CACHE.set(mint.toString(), mintInfo);
|
_MINT_CACHE.set(mint.toString(), mintInfo);
|
||||||
return mintInfo;
|
return mintInfo;
|
||||||
}, [provider.connection, mint]);
|
}, [provider.connection, mint]);
|
||||||
|
@ -148,4 +148,4 @@ const _OWNED_TOKEN_ACCOUNTS_CACHE: Array<{
|
||||||
}> = [];
|
}> = [];
|
||||||
|
|
||||||
// Cache storing all previously fetched mint infos.
|
// Cache storing all previously fetched mint infos.
|
||||||
const _MINT_CACHE = new Map<string, MintInfo>();
|
const _MINT_CACHE = new Map<string, Promise<MintInfo>>();
|
||||||
|
|
Loading…
Reference in New Issue