-
Notifications
You must be signed in to change notification settings - Fork 24
/
Copy pathpagination.ts
60 lines (54 loc) · 1.46 KB
/
pagination.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
import {
PageRequest,
PageResponse,
} from '@dao-dao/types/protobuf/codegen/cosmos/base/query/v1beta1/pagination'
export const getAllRpcResponse = async <
P extends { pagination?: PageRequest; [key: string]: any },
R extends { pagination?: PageResponse; [key: string]: any },
K extends keyof R,
V = R[K] extends any[] ? R[K] : R[K][],
>(
queryFn: (params: P, useInterfaces?: boolean) => Promise<R>,
params: P,
key: K,
reverse = false,
useInterfaces = false
): Promise<V> => {
let pagination: Partial<PageRequest> | undefined
const data = [] as any[]
do {
const response = await queryFn(
{
...params,
pagination: {
key: new Uint8Array(),
...pagination,
reverse,
// Get all.
offset: 0n,
limit: BigInt(Number.MAX_SAFE_INTEGER),
},
},
useInterfaces
)
pagination = response.pagination?.nextKey?.length
? {
key: response.pagination.nextKey,
}
: undefined
const results = response[key] as any
// If `key` accesses an array, flatten into result data. Otherwise, just
// concatenate all the responses (in case the paginated array is nested
// inside `key`).
if (Array.isArray(results)) {
// If no results retrieved, stop.
if (!results?.length) {
break
}
data.push(...results)
} else {
data.push(results)
}
} while (pagination !== undefined)
return data as V
}