|
1 | | -import type { |
2 | | - BorrowActivity, |
3 | | - Chain, |
4 | | - Erc20Token, |
5 | | - Hub, |
6 | | - HubAsset, |
7 | | - LiquidatedActivity, |
8 | | - NativeToken, |
9 | | - RepayActivity, |
10 | | - Reserve, |
11 | | - ReserveInfo, |
12 | | - Spoke, |
13 | | - SupplyActivity, |
14 | | - SwapActivity, |
15 | | - SwapByIntent, |
16 | | - SwapByIntentWithApprovalRequired, |
17 | | - SwapByTransaction, |
18 | | - UserPosition, |
19 | | - WithdrawActivity, |
| 1 | +import { |
| 2 | + type BorrowActivity, |
| 3 | + type Chain, |
| 4 | + type Erc20Token, |
| 5 | + type Hub, |
| 6 | + type HubAsset, |
| 7 | + type HubQuery, |
| 8 | + isTxHashInputVariant, |
| 9 | + type LiquidatedActivity, |
| 10 | + type NativeToken, |
| 11 | + type RepayActivity, |
| 12 | + type Reserve, |
| 13 | + type ReserveInfo, |
| 14 | + type Spoke, |
| 15 | + type SupplyActivity, |
| 16 | + type SwapActivity, |
| 17 | + type SwapByIntent, |
| 18 | + type SwapByIntentWithApprovalRequired, |
| 19 | + type SwapByTransaction, |
| 20 | + type UserHistoryQuery, |
| 21 | + type UserPosition, |
| 22 | + type VariablesOf, |
| 23 | + type WithdrawActivity, |
20 | 24 | } from '@aave/graphql-next'; |
21 | 25 | import introspectedSchema from '@aave/graphql-next/schema'; |
| 26 | +import type { DateTime, TxHash } from '@aave/types-next'; |
22 | 27 | import { |
23 | 28 | cacheExchange, |
24 | 29 | type Resolver, |
@@ -46,17 +51,101 @@ export const exchange = cacheExchange({ |
46 | 51 | // value: transformToBigInt, |
47 | 52 | // nonce: transformToBigInt, |
48 | 53 | // }, |
| 54 | + |
| 55 | + Query: { |
| 56 | + hub: (_, { request }: VariablesOf<typeof HubQuery>) => { |
| 57 | + return { |
| 58 | + __typename: 'Hub', |
| 59 | + address: request.hub, |
| 60 | + chain: { |
| 61 | + __typename: 'Chain', |
| 62 | + chainId: request.chainId, |
| 63 | + }, |
| 64 | + assets: [], |
| 65 | + }; |
| 66 | + }, |
| 67 | + |
| 68 | + userHistory: ( |
| 69 | + _parent, |
| 70 | + args: VariablesOf<typeof UserHistoryQuery>, |
| 71 | + cache, |
| 72 | + ) => { |
| 73 | + console.log('jerjere', args.request.filter); |
| 74 | + // Only optimize for txHash filter lookups |
| 75 | + if (!isTxHashInputVariant(args.request.filter)) { |
| 76 | + return cache.resolve('Query', 'userHistory', args); |
| 77 | + } |
| 78 | + |
| 79 | + const { txHash, chainId } = args.request.filter.txHash; |
| 80 | + |
| 81 | + // Collect all cached pages for Query.userHistory |
| 82 | + const matches = cache |
| 83 | + .inspectFields('Query') |
| 84 | + .filter((f) => f.fieldName === 'userHistory') |
| 85 | + .reduce((set, f) => { |
| 86 | + const pageRef = cache.resolve('Query', f.fieldKey) as string | null; |
| 87 | + if (!pageRef) return set; |
| 88 | + |
| 89 | + const itemRefs = cache.resolve(pageRef, 'items') as string[] | null; |
| 90 | + if (!itemRefs) return set; |
| 91 | + |
| 92 | + for (const ref of itemRefs) { |
| 93 | + set.add(ref); |
| 94 | + } |
| 95 | + return set; |
| 96 | + }, new Set<string>()) |
| 97 | + .values() |
| 98 | + .toArray() |
| 99 | + .filter((ref) => { |
| 100 | + const itemTxHash = cache.resolve(ref, 'txHash') as TxHash; |
| 101 | + if (itemTxHash !== txHash) return false; |
| 102 | + |
| 103 | + // Verify chainId if spoke.chain.chainId exists |
| 104 | + const spokeRef = cache.resolve(ref, 'spoke') as string | null; |
| 105 | + if (spokeRef) { |
| 106 | + const chainRef = cache.resolve(spokeRef, 'chain') as |
| 107 | + | string |
| 108 | + | null; |
| 109 | + const itemChainId = chainRef |
| 110 | + ? (cache.resolve(chainRef, 'chainId') as number | undefined) |
| 111 | + : undefined; |
| 112 | + if (typeof itemChainId === 'number') { |
| 113 | + return itemChainId === chainId; |
| 114 | + } |
| 115 | + } |
| 116 | + return true; |
| 117 | + }) |
| 118 | + .sort((a, b) => { |
| 119 | + const ta = cache.resolve(a, 'timestamp') as DateTime; |
| 120 | + const tb = cache.resolve(b, 'timestamp') as DateTime; |
| 121 | + return tb.localeCompare(ta); // desc |
| 122 | + }); |
| 123 | + |
| 124 | + if (matches.length === 0) return undefined; |
| 125 | + |
| 126 | + return { |
| 127 | + __typename: 'PaginatedUserHistoryResult', |
| 128 | + items: matches, |
| 129 | + pageInfo: { |
| 130 | + __typename: 'PaginatedResultInfo', |
| 131 | + prev: null, |
| 132 | + next: null, |
| 133 | + }, |
| 134 | + }; |
| 135 | + }, |
| 136 | + }, |
49 | 137 | }, |
50 | 138 | keys: { |
51 | 139 | // Entitied with composite key |
52 | | - Hub: (data: Hub) => `Hub:${data.address}/chain:${data.chain.chainId}`, |
| 140 | + Hub: (data: Hub) => `address=${data.address},chain=${data.chain.chainId}`, |
53 | 141 | HubAsset: (data: HubAsset) => |
54 | | - `HubAsset:${data.assetId}/hub:${data.hub.address}/chain:${data.hub.chain.chainId}`, |
| 142 | + `assetId=${data.assetId},hub=${data.hub.address},chain=${data.hub.chain.chainId}`, |
55 | 143 | Reserve: (data: Reserve) => |
56 | | - `Reserve:${data.id}/spoke:${data.spoke.address}/chain:${data.chain.chainId}`, |
| 144 | + `reserveId=${data.id},spoke=${data.spoke.address},chain=${data.chain.chainId}`, |
57 | 145 | ReserveInfo: (data: ReserveInfo) => |
58 | | - `ReserveInfo:${data.id}/spoke:${data.spoke.address}/chain:${data.chain.chainId}`, |
59 | | - Spoke: (data: Spoke) => `Spoke:${data.address}/chain:${data.chain.chainId}`, |
| 146 | + `reserveId=${data.id},spoke=${data.spoke.address},chain=${data.chain.chainId}`, |
| 147 | + Spoke: (data: Spoke) => |
| 148 | + `address=${data.address},chain=${data.chain.chainId}`, |
60 | 149 |
|
61 | 150 | // Entities with id field as key |
62 | 151 | BorrowActivity: (data: BorrowActivity) => data.id, |
|
0 commit comments