UNPKG

15.8 kBJavaScriptView Raw
1var __extends = (this && this.__extends) || (function () {
2 var extendStatics = function (d, b) {
3 extendStatics = Object.setPrototypeOf ||
4 ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
5 function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
6 return extendStatics(d, b);
7 }
8 return function (d, b) {
9 extendStatics(d, b);
10 function __() { this.constructor = d; }
11 d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
12 };
13})();
14var __assign = (this && this.__assign) || function () {
15 __assign = Object.assign || function(t) {
16 for (var s, i = 1, n = arguments.length; i < n; i++) {
17 s = arguments[i];
18 for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
19 t[p] = s[p];
20 }
21 return t;
22 };
23 return __assign.apply(this, arguments);
24};
25import { isEqual, tryFunctionOrLogError, cloneDeep } from 'apollo-utilities';
26import { NetworkStatus, isNetworkRequestInFlight } from './networkStatus';
27import { Observable } from '../util/Observable';
28import { ApolloError } from '../errors/ApolloError';
29import { FetchType } from './types';
30export var hasError = function (storeValue, policy) {
31 if (policy === void 0) { policy = 'none'; }
32 return storeValue &&
33 ((storeValue.graphQLErrors &&
34 storeValue.graphQLErrors.length > 0 &&
35 policy === 'none') ||
36 storeValue.networkError);
37};
38var ObservableQuery = (function (_super) {
39 __extends(ObservableQuery, _super);
40 function ObservableQuery(_a) {
41 var scheduler = _a.scheduler, options = _a.options, _b = _a.shouldSubscribe, shouldSubscribe = _b === void 0 ? true : _b;
42 var _this = _super.call(this, function (observer) {
43 return _this.onSubscribe(observer);
44 }) || this;
45 _this.isCurrentlyPolling = false;
46 _this.isTornDown = false;
47 _this.options = options;
48 _this.variables = options.variables || {};
49 _this.queryId = scheduler.queryManager.generateQueryId();
50 _this.shouldSubscribe = shouldSubscribe;
51 _this.scheduler = scheduler;
52 _this.queryManager = scheduler.queryManager;
53 _this.observers = [];
54 _this.subscriptionHandles = [];
55 return _this;
56 }
57 ObservableQuery.prototype.result = function () {
58 var that = this;
59 return new Promise(function (resolve, reject) {
60 var subscription;
61 var observer = {
62 next: function (result) {
63 resolve(result);
64 if (!that.observers.some(function (obs) { return obs !== observer; })) {
65 that.queryManager.removeQuery(that.queryId);
66 }
67 setTimeout(function () {
68 subscription.unsubscribe();
69 }, 0);
70 },
71 error: function (error) {
72 reject(error);
73 },
74 };
75 subscription = that.subscribe(observer);
76 });
77 };
78 ObservableQuery.prototype.currentResult = function () {
79 if (this.isTornDown) {
80 return {
81 data: this.lastError ? {} : this.lastResult ? this.lastResult.data : {},
82 error: this.lastError,
83 loading: false,
84 networkStatus: NetworkStatus.error,
85 };
86 }
87 var queryStoreValue = this.queryManager.queryStore.get(this.queryId);
88 if (hasError(queryStoreValue, this.options.errorPolicy)) {
89 return {
90 data: {},
91 loading: false,
92 networkStatus: queryStoreValue.networkStatus,
93 error: new ApolloError({
94 graphQLErrors: queryStoreValue.graphQLErrors,
95 networkError: queryStoreValue.networkError,
96 }),
97 };
98 }
99 var _a = this.queryManager.getCurrentQueryResult(this), data = _a.data, partial = _a.partial;
100 var queryLoading = !queryStoreValue ||
101 queryStoreValue.networkStatus === NetworkStatus.loading;
102 var loading = (this.options.fetchPolicy === 'network-only' && queryLoading) ||
103 (partial && this.options.fetchPolicy !== 'cache-only');
104 var networkStatus;
105 if (queryStoreValue) {
106 networkStatus = queryStoreValue.networkStatus;
107 }
108 else {
109 networkStatus = loading ? NetworkStatus.loading : NetworkStatus.ready;
110 }
111 var result = {
112 data: data,
113 loading: isNetworkRequestInFlight(networkStatus),
114 networkStatus: networkStatus,
115 };
116 if (queryStoreValue &&
117 queryStoreValue.graphQLErrors &&
118 this.options.errorPolicy === 'all') {
119 result.errors = queryStoreValue.graphQLErrors;
120 }
121 if (!partial) {
122 this.lastResult = __assign({}, result, { stale: false });
123 this.lastResultSnapshot = cloneDeep(this.lastResult);
124 }
125 return __assign({}, result, { partial: partial });
126 };
127 ObservableQuery.prototype.isDifferentFromLastResult = function (newResult) {
128 var snapshot = this.lastResultSnapshot;
129 return !(snapshot && newResult &&
130 snapshot.networkStatus === newResult.networkStatus &&
131 snapshot.stale === newResult.stale &&
132 isEqual(snapshot.data, newResult.data));
133 };
134 ObservableQuery.prototype.getLastResult = function () {
135 return this.lastResult;
136 };
137 ObservableQuery.prototype.getLastError = function () {
138 return this.lastError;
139 };
140 ObservableQuery.prototype.resetLastResults = function () {
141 delete this.lastResult;
142 delete this.lastResultSnapshot;
143 delete this.lastError;
144 this.isTornDown = false;
145 };
146 ObservableQuery.prototype.refetch = function (variables) {
147 var fetchPolicy = this.options.fetchPolicy;
148 if (fetchPolicy === 'cache-only') {
149 return Promise.reject(new Error('cache-only fetchPolicy option should not be used together with query refetch.'));
150 }
151 if (!isEqual(this.variables, variables)) {
152 this.variables = Object.assign({}, this.variables, variables);
153 }
154 if (!isEqual(this.options.variables, this.variables)) {
155 this.options.variables = Object.assign({}, this.options.variables, this.variables);
156 }
157 var isNetworkFetchPolicy = fetchPolicy === 'network-only' || fetchPolicy === 'no-cache';
158 var combinedOptions = __assign({}, this.options, { fetchPolicy: isNetworkFetchPolicy ? fetchPolicy : 'network-only' });
159 return this.queryManager
160 .fetchQuery(this.queryId, combinedOptions, FetchType.refetch)
161 .then(function (result) { return result; });
162 };
163 ObservableQuery.prototype.fetchMore = function (fetchMoreOptions) {
164 var _this = this;
165 if (!fetchMoreOptions.updateQuery) {
166 throw new Error('updateQuery option is required. This function defines how to update the query data with the new results.');
167 }
168 var combinedOptions;
169 return Promise.resolve()
170 .then(function () {
171 var qid = _this.queryManager.generateQueryId();
172 if (fetchMoreOptions.query) {
173 combinedOptions = fetchMoreOptions;
174 }
175 else {
176 combinedOptions = __assign({}, _this.options, fetchMoreOptions, { variables: Object.assign({}, _this.variables, fetchMoreOptions.variables) });
177 }
178 combinedOptions.fetchPolicy = 'network-only';
179 return _this.queryManager.fetchQuery(qid, combinedOptions, FetchType.normal, _this.queryId);
180 })
181 .then(function (fetchMoreResult) {
182 _this.updateQuery(function (previousResult) {
183 return fetchMoreOptions.updateQuery(previousResult, {
184 fetchMoreResult: fetchMoreResult.data,
185 variables: combinedOptions.variables,
186 });
187 });
188 return fetchMoreResult;
189 });
190 };
191 ObservableQuery.prototype.subscribeToMore = function (options) {
192 var _this = this;
193 var subscription = this.queryManager
194 .startGraphQLSubscription({
195 query: options.document,
196 variables: options.variables,
197 })
198 .subscribe({
199 next: function (subscriptionData) {
200 if (options.updateQuery) {
201 _this.updateQuery(function (previous, _a) {
202 var variables = _a.variables;
203 return options.updateQuery(previous, {
204 subscriptionData: subscriptionData,
205 variables: variables,
206 });
207 });
208 }
209 },
210 error: function (err) {
211 if (options.onError) {
212 options.onError(err);
213 return;
214 }
215 console.error('Unhandled GraphQL subscription error', err);
216 },
217 });
218 this.subscriptionHandles.push(subscription);
219 return function () {
220 var i = _this.subscriptionHandles.indexOf(subscription);
221 if (i >= 0) {
222 _this.subscriptionHandles.splice(i, 1);
223 subscription.unsubscribe();
224 }
225 };
226 };
227 ObservableQuery.prototype.setOptions = function (opts) {
228 var oldOptions = this.options;
229 this.options = Object.assign({}, this.options, opts);
230 if (opts.pollInterval) {
231 this.startPolling(opts.pollInterval);
232 }
233 else if (opts.pollInterval === 0) {
234 this.stopPolling();
235 }
236 var tryFetch = (oldOptions.fetchPolicy !== 'network-only' &&
237 opts.fetchPolicy === 'network-only') ||
238 (oldOptions.fetchPolicy === 'cache-only' &&
239 opts.fetchPolicy !== 'cache-only') ||
240 (oldOptions.fetchPolicy === 'standby' &&
241 opts.fetchPolicy !== 'standby') ||
242 false;
243 return this.setVariables(this.options.variables, tryFetch, opts.fetchResults);
244 };
245 ObservableQuery.prototype.setVariables = function (variables, tryFetch, fetchResults) {
246 if (tryFetch === void 0) { tryFetch = false; }
247 if (fetchResults === void 0) { fetchResults = true; }
248 this.isTornDown = false;
249 var newVariables = variables ? variables : this.variables;
250 if (isEqual(newVariables, this.variables) && !tryFetch) {
251 if (this.observers.length === 0 || !fetchResults) {
252 return new Promise(function (resolve) { return resolve(); });
253 }
254 return this.result();
255 }
256 else {
257 this.variables = newVariables;
258 this.options.variables = newVariables;
259 if (this.observers.length === 0) {
260 return new Promise(function (resolve) { return resolve(); });
261 }
262 return this.queryManager
263 .fetchQuery(this.queryId, __assign({}, this.options, { variables: this.variables }))
264 .then(function (result) { return result; });
265 }
266 };
267 ObservableQuery.prototype.updateQuery = function (mapFn) {
268 var _a = this.queryManager.getQueryWithPreviousResult(this.queryId), previousResult = _a.previousResult, variables = _a.variables, document = _a.document;
269 var newResult = tryFunctionOrLogError(function () {
270 return mapFn(previousResult, { variables: variables });
271 });
272 if (newResult) {
273 this.queryManager.dataStore.markUpdateQueryResult(document, variables, newResult);
274 this.queryManager.broadcastQueries();
275 }
276 };
277 ObservableQuery.prototype.stopPolling = function () {
278 if (this.isCurrentlyPolling) {
279 this.scheduler.stopPollingQuery(this.queryId);
280 this.options.pollInterval = undefined;
281 this.isCurrentlyPolling = false;
282 }
283 };
284 ObservableQuery.prototype.startPolling = function (pollInterval) {
285 if (this.options.fetchPolicy === 'cache-first' ||
286 this.options.fetchPolicy === 'cache-only') {
287 throw new Error('Queries that specify the cache-first and cache-only fetchPolicies cannot also be polling queries.');
288 }
289 if (this.isCurrentlyPolling) {
290 this.scheduler.stopPollingQuery(this.queryId);
291 this.isCurrentlyPolling = false;
292 }
293 this.options.pollInterval = pollInterval;
294 this.isCurrentlyPolling = true;
295 this.scheduler.startPollingQuery(this.options, this.queryId);
296 };
297 ObservableQuery.prototype.onSubscribe = function (observer) {
298 var _this = this;
299 if (observer._subscription &&
300 observer._subscription._observer &&
301 !observer._subscription._observer.error) {
302 observer._subscription._observer.error = function (error) {
303 console.error('Unhandled error', error.message, error.stack);
304 };
305 }
306 this.observers.push(observer);
307 if (observer.next && this.lastResult)
308 observer.next(this.lastResult);
309 if (observer.error && this.lastError)
310 observer.error(this.lastError);
311 if (this.observers.length === 1)
312 this.setUpQuery();
313 return function () {
314 _this.observers = _this.observers.filter(function (obs) { return obs !== observer; });
315 if (_this.observers.length === 0) {
316 _this.tearDownQuery();
317 }
318 };
319 };
320 ObservableQuery.prototype.setUpQuery = function () {
321 var _this = this;
322 if (this.shouldSubscribe) {
323 this.queryManager.addObservableQuery(this.queryId, this);
324 }
325 if (!!this.options.pollInterval) {
326 if (this.options.fetchPolicy === 'cache-first' ||
327 this.options.fetchPolicy === 'cache-only') {
328 throw new Error('Queries that specify the cache-first and cache-only fetchPolicies cannot also be polling queries.');
329 }
330 this.isCurrentlyPolling = true;
331 this.scheduler.startPollingQuery(this.options, this.queryId);
332 }
333 var observer = {
334 next: function (result) {
335 _this.lastResult = result;
336 _this.lastResultSnapshot = cloneDeep(result);
337 _this.observers.forEach(function (obs) { return obs.next && obs.next(result); });
338 },
339 error: function (error) {
340 _this.lastError = error;
341 _this.observers.forEach(function (obs) { return obs.error && obs.error(error); });
342 },
343 };
344 this.queryManager.startQuery(this.queryId, this.options, this.queryManager.queryListenerForObserver(this.queryId, this.options, observer));
345 };
346 ObservableQuery.prototype.tearDownQuery = function () {
347 this.isTornDown = true;
348 if (this.isCurrentlyPolling) {
349 this.scheduler.stopPollingQuery(this.queryId);
350 this.isCurrentlyPolling = false;
351 }
352 this.subscriptionHandles.forEach(function (sub) { return sub.unsubscribe(); });
353 this.subscriptionHandles = [];
354 this.queryManager.removeObservableQuery(this.queryId);
355 this.queryManager.stopQuery(this.queryId);
356 this.observers = [];
357 };
358 return ObservableQuery;
359}(Observable));
360export { ObservableQuery };
361//# sourceMappingURL=ObservableQuery.js.map
\No newline at end of file