-
Notifications
You must be signed in to change notification settings - Fork 20
/
fetch-lists.ts
74 lines (66 loc) · 2.01 KB
/
fetch-lists.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
61
62
63
64
65
66
67
68
69
70
71
72
73
74
import { ISourcingContext, IRemoteNode } from "../../types"
import {
collectListOperationNames,
getGatsbyNodeDefinition,
} from "../utils/node-definition-helpers"
import { paginate, planPagination } from "./paginate"
import { addPaginatedFields } from "./fetch-node-fields"
/**
* Fetches and paginates remote nodes by type while reporting progress
*/
export async function* fetchAllNodes(
context: ISourcingContext,
remoteTypeName: string,
variables?: object
): AsyncIterable<IRemoteNode> {
const { gatsbyApi, formatLogMessage } = context
const { reporter } = gatsbyApi
const nodeDefinition = getGatsbyNodeDefinition(context, remoteTypeName)
const activity = reporter.activityTimer(
formatLogMessage(`fetching ${nodeDefinition.remoteTypeName}`)
)
activity.start()
try {
const listOperations = collectListOperationNames(nodeDefinition.document)
for (const nodeListQuery of listOperations) {
const nodes = fetchNodeList(
context,
remoteTypeName,
nodeListQuery,
variables
)
for await (const node of nodes) {
yield node
}
}
} finally {
activity.end()
}
}
export async function* fetchNodeList(
context: ISourcingContext,
remoteTypeName: string,
listOperationName: string,
variables?: object
): AsyncIterable<IRemoteNode> {
const typeNameField = context.gatsbyFieldAliases["__typename"]
const nodeDefinition = getGatsbyNodeDefinition(context, remoteTypeName)
const plan = planPagination(
context,
nodeDefinition.document,
listOperationName,
variables
)
for await (const page of paginate(context, plan)) {
const partialNodes = plan.adapter.getItems(page.fieldValue)
for (const node of partialNodes) {
if (!node || node[typeNameField] !== remoteTypeName) {
// Possible when fetching complex interface or union type fields
// or when some node is `null`
continue
}
// TODO: run in parallel?
yield addPaginatedFields(context, nodeDefinition, node)
}
}
}