/
as-iterator.ts
46 lines (39 loc) · 1.24 KB
/
as-iterator.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
import copy from 'fast-copy'
import { CollectionProp, QueryParams } from '../common-types'
type IterableFn<P = any, T = any> = (params: P) => Promise<CollectionProp<T>>
type ParamsType<T extends IterableFn> = T extends (params: infer P) => any ? P : never
export const asIterator = <P extends QueryParams, T, F extends IterableFn<P, T>>(
fn: F,
params: ParamsType<F>
): AsyncIterable<T> => {
return {
[Symbol.asyncIterator]() {
let options = copy(params)
const get = () => fn(copy(options))
let currentResult = get()
return {
current: 0,
async next() {
const { total, items, skip, limit } = await currentResult
if (total === this.current) {
return { done: true, value: null }
}
const value = items[this.current++ - skip]
const endOfPage = this.current % limit === 0
const endOfList = this.current === total
if (endOfPage && !endOfList) {
options = {
...options,
query: {
...options.query,
skip: skip + limit,
},
}
currentResult = get()
}
return { done: false, value }
},
}
},
}
}