Skip to content

Commit

Permalink
feat: cache indexer requests when using indexer hooks
Browse files Browse the repository at this point in the history
  • Loading branch information
dib542 committed Nov 21, 2023
1 parent 4d5802a commit ff88ea1
Show file tree
Hide file tree
Showing 2 changed files with 24 additions and 30 deletions.
49 changes: 22 additions & 27 deletions src/lib/web3/hooks/useIndexer.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { useEffect, useState } from 'react';
import useSWRSubscription, { SWRSubscription } from 'swr/subscription';

const { REACT_APP__INDEXER_API = '' } = process.env;

Expand Down Expand Up @@ -265,9 +265,8 @@ export class IndexerStreamAccumulateDualDataSet<
}

interface StaleWhileRevalidateState<DataSetOrDataSets> {
data: DataSetOrDataSets | undefined;
isValidating: boolean;
error: Error | undefined;
data?: DataSetOrDataSets;
error?: Error;
}
// add higher-level hook to stream real-time DataSet or DataSets of Indexer URL
function useIndexerStream<
Expand All @@ -288,34 +287,30 @@ function useIndexerStream<
DataRow extends BaseDataRow,
DataSet = BaseDataSet<DataRow>
>(
url: URL | string | undefined,
url: URL | string = '',
IndexerClass:
| typeof IndexerStreamAccumulateSingleDataSet
| typeof IndexerStreamAccumulateDualDataSet
): StaleWhileRevalidateState<DataSet | DataSet[]> {
const [dataset, setDataSet] = useState<DataSet | DataSet[]>();
const [isValidating, setIsValidating] = useState<boolean>(false);
const [error, setError] = useState<Error>();

// todo: use deep-compare effect to not cause unneccessary updates from url or opts
useEffect(() => {
if (url) {
setIsValidating(true);
const stream = new IndexerClass<DataRow>(url, {
onAccumulated: (dataSet) => {
// note: the TypeScript here is a bit hacky but this should be ok
setDataSet(dataSet as unknown as DataSet | DataSet[]);
},
onCompleted: () => setIsValidating(false),
onError: (error) => setError(error),
});
return () => {
stream.unsubscribe();
};
}
}, [IndexerClass, url]);
// define subscription callback which may or may not be used in this component
// it is passed to useSWRSubscription to handle if the subscription should be
// created/held/destroyed as multiple components may listen for the same data
const subscribe: SWRSubscription<string, DataSet | DataSet[], Error> = (
url,
{ next }
) => {
const stream = new IndexerClass<DataRow>(url, {
onAccumulated: (dataSet) => {
// note: the TypeScript here is a bit hacky but this should be ok
next(null, dataSet as unknown as DataSet | DataSet[]);
},
onError: (error) => next(error),
});
return () => stream.unsubscribe();
};

return { data: dataset, isValidating, error };
// return cached subscription data
return useSWRSubscription<DataSet | DataSet[], Error>(`${url}`, subscribe);
}

// higher-level hook to stream real-time DataSet of Indexer URL
Expand Down
5 changes: 2 additions & 3 deletions src/lib/web3/hooks/useTokenPairs.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,12 +12,11 @@ type DataRow = [index: number, values: TokenPairReserves];

type TokenPairsState = {
data: TokenPairReserves[] | undefined;
isValidating: boolean;
error: Error | null;
};

export default function useTokenPairs(): TokenPairsState {
const { data, isValidating, error } =
const { data, error } =
useIndexerStreamOfSingleDataSet<DataRow>('/liquidity/pairs');

const values: TokenPairReserves[] | undefined = useMemo(() => {
Expand All @@ -30,7 +29,7 @@ export default function useTokenPairs(): TokenPairsState {
}, [data]);

// return state
return { data: values, isValidating, error: error || null };
return { data: values, error: error || null };
}

// add convenience method to fetch ticks in a pair
Expand Down

0 comments on commit ff88ea1

Please sign in to comment.