-
-
Notifications
You must be signed in to change notification settings - Fork 628
/
Copy pathquery_options.dart
206 lines (183 loc) · 6.36 KB
/
query_options.dart
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
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
// ignore_for_file: deprecated_member_use_from_same_package
import 'package:graphql/src/core/_base_options.dart';
import 'package:graphql/src/utilities/helpers.dart';
import 'package:gql/ast.dart';
import 'package:gql_exec/gql_exec.dart';
import 'package:graphql/client.dart';
import 'package:graphql/src/core/policies.dart';
/// Query options.
class QueryOptions extends BaseOptions {
QueryOptions({
required DocumentNode document,
String? operationName,
Map<String, dynamic> variables = const {},
FetchPolicy? fetchPolicy,
ErrorPolicy? errorPolicy,
CacheRereadPolicy? cacheRereadPolicy,
Object? optimisticResult,
this.pollInterval,
Context? context,
}) : super(
fetchPolicy: fetchPolicy,
errorPolicy: errorPolicy,
cacheRereadPolicy: cacheRereadPolicy,
document: document,
operationName: operationName,
variables: variables,
context: context,
optimisticResult: optimisticResult,
);
/// The time interval on which this query should be re-fetched from the server.
Duration? pollInterval;
@override
List<Object?> get properties => [...super.properties, pollInterval];
WatchQueryOptions asWatchQueryOptions({bool fetchResults = true}) =>
WatchQueryOptions(
document: document,
operationName: operationName,
variables: variables,
fetchPolicy: fetchPolicy,
errorPolicy: errorPolicy,
cacheRereadPolicy: cacheRereadPolicy,
pollInterval: pollInterval,
fetchResults: fetchResults,
context: context,
optimisticResult: optimisticResult,
);
}
class SubscriptionOptions extends BaseOptions {
SubscriptionOptions({
required DocumentNode document,
String? operationName,
Map<String, dynamic> variables = const {},
FetchPolicy? fetchPolicy,
ErrorPolicy? errorPolicy,
CacheRereadPolicy? cacheRereadPolicy,
Object? optimisticResult,
Context? context,
}) : super(
fetchPolicy: fetchPolicy,
errorPolicy: errorPolicy,
cacheRereadPolicy: cacheRereadPolicy,
document: document,
operationName: operationName,
variables: variables,
context: context,
optimisticResult: optimisticResult,
);
/// An optimistic first result to eagerly add to the subscription stream
Object? optimisticResult;
}
class WatchQueryOptions extends QueryOptions {
WatchQueryOptions({
required DocumentNode document,
String? operationName,
Map<String, dynamic> variables = const {},
FetchPolicy? fetchPolicy,
ErrorPolicy? errorPolicy,
CacheRereadPolicy? cacheRereadPolicy,
Object? optimisticResult,
Duration? pollInterval,
this.fetchResults = false,
this.carryForwardDataOnException = true,
bool? eagerlyFetchResults,
Context? context,
}) : eagerlyFetchResults = eagerlyFetchResults ?? fetchResults,
super(
document: document,
operationName: operationName,
variables: variables,
fetchPolicy: fetchPolicy,
errorPolicy: errorPolicy,
cacheRereadPolicy: cacheRereadPolicy,
pollInterval: pollInterval,
context: context,
optimisticResult: optimisticResult,
);
/// Whether or not to fetch results
bool fetchResults;
/// Whether to [fetchResults] immediately on instantiation.
/// Defaults to [fetchResults].
bool eagerlyFetchResults;
/// carry forward previous data in the result of errors and no data.
/// defaults to `true`.
bool carryForwardDataOnException;
@override
List<Object?> get properties =>
[...super.properties, fetchResults, eagerlyFetchResults];
WatchQueryOptions copy() => WatchQueryOptions(
document: document,
operationName: operationName,
variables: variables,
fetchPolicy: fetchPolicy,
errorPolicy: errorPolicy,
cacheRereadPolicy: cacheRereadPolicy,
optimisticResult: optimisticResult,
pollInterval: pollInterval,
fetchResults: fetchResults,
eagerlyFetchResults: eagerlyFetchResults,
carryForwardDataOnException: carryForwardDataOnException,
context: context,
);
}
/// options for fetchMore operations
///
/// **NOTE**: with the addition of strict data structure checking in v4,
/// it is easy to make mistakes in writing [updateQuery].
///
/// To mitigate this, [FetchMoreOptions.partial] has been provided.
class FetchMoreOptions {
FetchMoreOptions({
this.document,
this.variables = const {},
required this.updateQuery,
});
/// Automatically merge the results of [updateQuery] into `previousResultData`.
///
/// This is useful if you only want to, say, extract some list data
/// from the newly fetched result, and don't want to worry about
/// structural inconsistencies while merging.
static FetchMoreOptions partial({
DocumentNode? document,
Map<String, dynamic> variables = const {},
required UpdateQuery updateQuery,
}) =>
FetchMoreOptions(
document: document,
variables: variables,
updateQuery: partialUpdater(updateQuery),
);
DocumentNode? document;
Map<String, dynamic> variables;
/// Strategy for merging the fetchMore result data
/// with the result data already in the cache
UpdateQuery updateQuery;
/// Wrap an [UpdateQuery] in a [deeplyMergeLeft] of the `previousResultData`.
static UpdateQuery partialUpdater(UpdateQuery update) =>
(previous, fetched) => deeplyMergeLeft(
[previous, update(previous, fetched)],
);
}
/// merge fetchMore result data with earlier result data
typedef Map<String, dynamic>? UpdateQuery(
Map<String, dynamic>? previousResultData,
Map<String, dynamic>? fetchMoreResultData,
);
extension WithType on Request {
OperationType get type {
final definitions = operation.document.definitions
.whereType<OperationDefinitionNode>()
.toList();
if (operation.operationName != null) {
definitions.removeWhere(
(node) => node.name!.value != operation.operationName,
);
}
// TODO differentiate error types, add exception
assert(definitions.length == 1);
return definitions.first.type;
}
bool get isQuery => type == OperationType.query;
bool get isMutation => type == OperationType.mutation;
bool get isSubscription => type == OperationType.subscription;
}