vega-frontend-monorepo/libs/fills/src/lib/fills-data-provider.ts
2022-10-19 10:14:18 +01:00

105 lines
3.0 KiB
TypeScript

import produce from 'immer';
import orderBy from 'lodash/orderBy';
import {
makeDataProvider,
makeDerivedDataProvider,
defaultAppend as append,
paginatedCombineDelta as combineDelta,
paginatedCombineInsertionData as combineInsertionData,
} from '@vegaprotocol/react-helpers';
import type { Market } from '@vegaprotocol/market-list';
import { marketsProvider } from '@vegaprotocol/market-list';
import type { PageInfo, Edge } from '@vegaprotocol/react-helpers';
import { FillsDocument, FillsEventDocument } from './__generated___/Fills';
import type {
FillsQuery,
FillFieldsFragment,
FillEdgeFragment,
FillsEventSubscription,
} from './__generated___/Fills';
const update = (
data: FillEdgeFragment[] | null,
delta: FillsEventSubscription['trades']
) => {
return produce(data, (draft) => {
orderBy(delta, 'createdAt').forEach((node) => {
if (draft === null) {
return;
}
const index = draft.findIndex((edge) => edge?.node.id === node.id);
if (index !== -1) {
if (draft[index]?.node) {
Object.assign(draft[index]?.node as FillFieldsFragment, node);
}
} else {
const firstNode = draft[0]?.node;
if (firstNode && node.createdAt >= firstNode.createdAt) {
const { buyerId, sellerId, marketId, ...trade } = node;
draft.unshift({
node: {
...trade,
__typename: 'Trade',
market: {
__typename: 'Market',
id: marketId,
},
buyer: { id: buyerId, __typename: 'Party' },
seller: { id: buyerId, __typename: 'Party' },
},
cursor: '',
__typename: 'TradeEdge',
});
}
}
});
});
};
export type Trade = Omit<FillFieldsFragment, 'market'> & { market?: Market };
export type TradeEdge = Edge<Trade>;
const getData = (responseData: FillsQuery): FillEdgeFragment[] =>
responseData.party?.tradesConnection?.edges || [];
const getPageInfo = (responseData: FillsQuery): PageInfo | null =>
responseData.party?.tradesConnection?.pageInfo || null;
const getDelta = (subscriptionData: FillsEventSubscription) =>
subscriptionData.trades || [];
export const fillsProvider = makeDataProvider({
query: FillsDocument,
subscriptionQuery: FillsEventDocument,
update,
getData,
getDelta,
pagination: {
getPageInfo,
append,
first: 100,
},
});
export const fillsWithMarketProvider = makeDerivedDataProvider<
(TradeEdge | null)[],
Trade[]
>(
[fillsProvider, marketsProvider],
(partsData): (TradeEdge | null)[] =>
(partsData[0] as ReturnType<typeof getData>)?.map(
(edge) =>
edge && {
cursor: edge.cursor,
node: {
...edge.node,
market: (partsData[1] as Market[]).find(
(market) => market.id === edge.node.market.id
),
},
}
) || null,
combineDelta<Trade, ReturnType<typeof getDelta>['0']>,
combineInsertionData<Trade>
);