* feat(#1243): Market data providers * feat(#1243): Market data providers * feat(#1243): Market data providers * feat(#1243): refactor market lists * feat(#1243): refactor market lists * feat(#1243): refactor market lists * feat(#1243): refactor orderbook data providers * feat(#1243): refactor orderbook data providers * feat(#1243): refactor depth chart data layer * feat(#1243): fix market depth typing * fixed unit tests * feat(#1243): e2e test fixes * feat(#1243): code style fixes * feat(#1243): post merge fixes * feat(#1243): fix lint issues * feat(#1243): post merge fixes * feat(#1243): remove market name from market * feat(#1243): fix console lite e2e data depth mocks * feat(#1243): fix console lite e2e market trade test * feat(#1243): fix lint issues * feat(#1243): fix trading e2e home test Co-authored-by: asiaznik <artur@vegaprotocol.io>
121 lines
3.5 KiB
TypeScript
121 lines
3.5 KiB
TypeScript
import { useState, useEffect, useRef, useCallback } from 'react';
|
|
import { useApolloClient } from '@apollo/client';
|
|
import type { OperationVariables } from '@apollo/client';
|
|
import type {
|
|
Subscribe,
|
|
Load,
|
|
UpdateCallback,
|
|
} from '../lib/generic-data-provider';
|
|
|
|
/**
|
|
*
|
|
* @param dataProvider subscribe function created by makeDataProvider
|
|
* @param update optional function called on each delta received in subscription, if returns true updated data will be not passed from hook (component handles updates internally)
|
|
* @param variables optional
|
|
* @returns state: data, loading, error, methods: flush (pass updated data to update function without delta), restart: () => void}};
|
|
*/
|
|
export function useDataProvider<Data, Delta>({
|
|
dataProvider,
|
|
update,
|
|
insert,
|
|
variables,
|
|
noUpdate,
|
|
skip,
|
|
}: {
|
|
dataProvider: Subscribe<Data, Delta>;
|
|
update?: ({ delta, data }: { delta: Delta; data: Data }) => boolean;
|
|
insert?: ({
|
|
insertionData,
|
|
data,
|
|
totalCount,
|
|
}: {
|
|
insertionData: Data;
|
|
data: Data;
|
|
totalCount?: number;
|
|
}) => boolean;
|
|
variables?: OperationVariables;
|
|
noUpdate?: boolean;
|
|
skip?: boolean;
|
|
}) {
|
|
const client = useApolloClient();
|
|
const [data, setData] = useState<Data | null>(null);
|
|
const [totalCount, setTotalCount] = useState<number>();
|
|
const [loading, setLoading] = useState<boolean>(!skip);
|
|
const [error, setError] = useState<Error | undefined>(undefined);
|
|
const flushRef = useRef<(() => void) | undefined>(undefined);
|
|
const reloadRef = useRef<((force?: boolean) => void) | undefined>(undefined);
|
|
const loadRef = useRef<Load<Data> | undefined>(undefined);
|
|
const initialized = useRef<boolean>(false);
|
|
const flush = useCallback(() => {
|
|
if (flushRef.current) {
|
|
flushRef.current();
|
|
}
|
|
}, []);
|
|
const reload = useCallback((force = false) => {
|
|
if (reloadRef.current) {
|
|
reloadRef.current(force);
|
|
}
|
|
}, []);
|
|
const load = useCallback<Load<Data>>((...args) => {
|
|
if (loadRef.current) {
|
|
return loadRef.current(...args);
|
|
}
|
|
return Promise.reject();
|
|
}, []);
|
|
const callback = useCallback<UpdateCallback<Data, Delta>>(
|
|
({
|
|
data,
|
|
error,
|
|
loading,
|
|
delta,
|
|
insertionData,
|
|
totalCount,
|
|
isInsert,
|
|
isUpdate,
|
|
}) => {
|
|
setError(error);
|
|
setLoading(loading);
|
|
if (!error && !loading) {
|
|
// if update or insert function returns true it means that component handles updates
|
|
// component can use flush() which will call callback without delta and cause data state update
|
|
if (initialized.current && data) {
|
|
if (
|
|
isUpdate &&
|
|
!noUpdate &&
|
|
update &&
|
|
(!delta || update({ delta, data }))
|
|
) {
|
|
return;
|
|
}
|
|
if (
|
|
isInsert &&
|
|
insert &&
|
|
(!insertionData || insert({ insertionData, data, totalCount }))
|
|
) {
|
|
return;
|
|
}
|
|
}
|
|
initialized.current = true;
|
|
setTotalCount(totalCount);
|
|
setData(data);
|
|
}
|
|
},
|
|
[update, insert, noUpdate]
|
|
);
|
|
useEffect(() => {
|
|
if (skip) {
|
|
return;
|
|
}
|
|
const { unsubscribe, flush, reload, load } = dataProvider(
|
|
callback,
|
|
client,
|
|
variables
|
|
);
|
|
flushRef.current = flush;
|
|
reloadRef.current = reload;
|
|
loadRef.current = load;
|
|
return unsubscribe;
|
|
}, [client, initialized, dataProvider, callback, variables, skip]);
|
|
return { data, loading, error, flush, reload, load, totalCount };
|
|
}
|