This repository was archived by the owner on Oct 9, 2025. It is now read-only.
forked from jcoreio/apollo-magic-refetch
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathindex.js.flow
More file actions
98 lines (87 loc) · 2.57 KB
/
Copy pathindex.js.flow
File metadata and controls
98 lines (87 loc) · 2.57 KB
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
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
// @flow
import { ApolloClient } from '@apollo/client'
import getSchemaTypes from './getSchemaTypes'
import type { Types } from './getSchemaTypes'
import doesQueryContain from './doesQueryContain'
import typesQuery, { type TypeMetadata } from './typesQuery'
export { typesQuery }
export type { TypeMetadata }
function normalizePredicate(
predicate: any,
idField: string
): (data: any) => boolean {
if (typeof predicate === 'function') return predicate
let ids = predicate
if (Array.isArray(ids)) ids = new Set(ids)
else if (!(ids instanceof Set)) ids = new Set([ids])
return data => ids.has(data[idField])
}
type Term = [string, any, ?string] | [string, any] | [string]
function every<T>(
array: $ReadOnlyArray<T>,
predicate: (elem: T) => boolean
): boolean {
for (let elem of array) {
if (!predicate(elem)) return false
}
return true
}
let typesPromise: ?Promise<Types> = null
export default async function refetch(
client: mixed,
typenameOrTerms: string | $ReadOnlyArray<Term>,
predicate?: ?any,
idField?: string
): Promise<any> {
const types: Types = await refetch.fetchTypeMetadata(client)
let terms
if (typeof typenameOrTerms === 'string') {
terms = [[typenameOrTerms, predicate, idField]]
} else if (Array.isArray(typenameOrTerms)) {
terms = typenameOrTerms
} else {
throw new Error(`invalid typename or terms: ${typenameOrTerms}`)
}
const {
queryManager: { queries },
} = client
let promises = []
for (let query of queries.values()) {
const { document, observableQuery } = query
if (!observableQuery) continue
let data
const currentResult = observableQuery.currentResult
? observableQuery.currentResult()
: observableQuery.getCurrentResult()
if (currentResult) data = currentResult.data
if (
every(terms, ([typename, predicate, idField]: any) =>
doesQueryContain(
document,
types,
typename,
data,
predicate != null
? normalizePredicate(predicate, idField || 'id')
: null
)
)
) {
promises.push(observableQuery.refetch())
}
}
await promises
}
refetch.fetchTypeMetadata = async function(
client: ApolloClient<any>
): Promise<Types> {
if (!typesPromise) {
refetch.setTypeMetadata(client.query({ query: typesQuery }))
}
// istanbul ignore next
if (!typesPromise) throw new Error('this should never happen')
return await typesPromise
}
refetch.setTypeMetadata = (metadata: Promise<TypeMetadata> | TypeMetadata) => {
typesPromise = getSchemaTypes(async () => await metadata)
}