1 | "use strict";
|
2 | Object.defineProperty(exports, "__esModule", { value: true });
|
3 | var tslib_1 = require("tslib");
|
4 | var apollo_link_1 = require("apollo-link");
|
5 | var apollo_utilities_1 = require("apollo-utilities");
|
6 | var ts_invariant_1 = require("ts-invariant");
|
7 | var ApolloError_1 = require("../errors/ApolloError");
|
8 | var Observable_1 = require("../util/Observable");
|
9 | var mutations_1 = require("../data/mutations");
|
10 | var queries_1 = require("../data/queries");
|
11 | var ObservableQuery_1 = require("./ObservableQuery");
|
12 | var networkStatus_1 = require("./networkStatus");
|
13 | var types_1 = require("./types");
|
14 | var LocalState_1 = require("./LocalState");
|
15 | var observables_1 = require("../util/observables");
|
16 | var arrays_1 = require("../util/arrays");
|
17 | var hasOwnProperty = Object.prototype.hasOwnProperty;
|
18 | var QueryManager = (function () {
|
19 | function QueryManager(_a) {
|
20 | var link = _a.link, _b = _a.queryDeduplication, queryDeduplication = _b === void 0 ? false : _b, store = _a.store, _c = _a.onBroadcast, onBroadcast = _c === void 0 ? function () { return undefined; } : _c, _d = _a.ssrMode, ssrMode = _d === void 0 ? false : _d, _e = _a.clientAwareness, clientAwareness = _e === void 0 ? {} : _e, localState = _a.localState, assumeImmutableResults = _a.assumeImmutableResults;
|
21 | this.mutationStore = new mutations_1.MutationStore();
|
22 | this.queryStore = new queries_1.QueryStore();
|
23 | this.clientAwareness = {};
|
24 | this.idCounter = 1;
|
25 | this.queries = new Map();
|
26 | this.fetchQueryRejectFns = new Map();
|
27 | this.transformCache = new (apollo_utilities_1.canUseWeakMap ? WeakMap : Map)();
|
28 | this.inFlightLinkObservables = new Map();
|
29 | this.pollingInfoByQueryId = new Map();
|
30 | this.link = link;
|
31 | this.queryDeduplication = queryDeduplication;
|
32 | this.dataStore = store;
|
33 | this.onBroadcast = onBroadcast;
|
34 | this.clientAwareness = clientAwareness;
|
35 | this.localState = localState || new LocalState_1.LocalState({ cache: store.getCache() });
|
36 | this.ssrMode = ssrMode;
|
37 | this.assumeImmutableResults = !!assumeImmutableResults;
|
38 | }
|
39 | QueryManager.prototype.stop = function () {
|
40 | var _this = this;
|
41 | this.queries.forEach(function (_info, queryId) {
|
42 | _this.stopQueryNoBroadcast(queryId);
|
43 | });
|
44 | this.fetchQueryRejectFns.forEach(function (reject) {
|
45 | reject(new ts_invariant_1.InvariantError('QueryManager stopped while query was in flight'));
|
46 | });
|
47 | };
|
48 | QueryManager.prototype.mutate = function (_a) {
|
49 | var mutation = _a.mutation, variables = _a.variables, optimisticResponse = _a.optimisticResponse, updateQueriesByName = _a.updateQueries, _b = _a.refetchQueries, refetchQueries = _b === void 0 ? [] : _b, _c = _a.awaitRefetchQueries, awaitRefetchQueries = _c === void 0 ? false : _c, updateWithProxyFn = _a.update, _d = _a.errorPolicy, errorPolicy = _d === void 0 ? 'none' : _d, fetchPolicy = _a.fetchPolicy, _e = _a.context, context = _e === void 0 ? {} : _e;
|
50 | return tslib_1.__awaiter(this, void 0, void 0, function () {
|
51 | var mutationId, generateUpdateQueriesInfo, self;
|
52 | var _this = this;
|
53 | return tslib_1.__generator(this, function (_f) {
|
54 | switch (_f.label) {
|
55 | case 0:
|
56 | ts_invariant_1.invariant(mutation, 'mutation option is required. You must specify your GraphQL document in the mutation option.');
|
57 | ts_invariant_1.invariant(!fetchPolicy || fetchPolicy === 'no-cache', "Mutations only support a 'no-cache' fetchPolicy. If you don't want to disable the cache, remove your fetchPolicy setting to proceed with the default mutation behavior.");
|
58 | mutationId = this.generateQueryId();
|
59 | mutation = this.transform(mutation).document;
|
60 | this.setQuery(mutationId, function () { return ({ document: mutation }); });
|
61 | variables = this.getVariables(mutation, variables);
|
62 | if (!this.transform(mutation).hasClientExports) return [3, 2];
|
63 | return [4, this.localState.addExportedVariables(mutation, variables, context)];
|
64 | case 1:
|
65 | variables = _f.sent();
|
66 | _f.label = 2;
|
67 | case 2:
|
68 | generateUpdateQueriesInfo = function () {
|
69 | var ret = {};
|
70 | if (updateQueriesByName) {
|
71 | _this.queries.forEach(function (_a, queryId) {
|
72 | var observableQuery = _a.observableQuery;
|
73 | if (observableQuery) {
|
74 | var queryName = observableQuery.queryName;
|
75 | if (queryName &&
|
76 | hasOwnProperty.call(updateQueriesByName, queryName)) {
|
77 | ret[queryId] = {
|
78 | updater: updateQueriesByName[queryName],
|
79 | query: _this.queryStore.get(queryId),
|
80 | };
|
81 | }
|
82 | }
|
83 | });
|
84 | }
|
85 | return ret;
|
86 | };
|
87 | this.mutationStore.initMutation(mutationId, mutation, variables);
|
88 | this.dataStore.markMutationInit({
|
89 | mutationId: mutationId,
|
90 | document: mutation,
|
91 | variables: variables,
|
92 | updateQueries: generateUpdateQueriesInfo(),
|
93 | update: updateWithProxyFn,
|
94 | optimisticResponse: optimisticResponse,
|
95 | });
|
96 | this.broadcastQueries();
|
97 | self = this;
|
98 | return [2, new Promise(function (resolve, reject) {
|
99 | var storeResult;
|
100 | var error;
|
101 | self.getObservableFromLink(mutation, tslib_1.__assign(tslib_1.__assign({}, context), { optimisticResponse: optimisticResponse }), variables, false).subscribe({
|
102 | next: function (result) {
|
103 | if (apollo_utilities_1.graphQLResultHasError(result) && errorPolicy === 'none') {
|
104 | error = new ApolloError_1.ApolloError({
|
105 | graphQLErrors: result.errors,
|
106 | });
|
107 | return;
|
108 | }
|
109 | self.mutationStore.markMutationResult(mutationId);
|
110 | if (fetchPolicy !== 'no-cache') {
|
111 | self.dataStore.markMutationResult({
|
112 | mutationId: mutationId,
|
113 | result: result,
|
114 | document: mutation,
|
115 | variables: variables,
|
116 | updateQueries: generateUpdateQueriesInfo(),
|
117 | update: updateWithProxyFn,
|
118 | });
|
119 | }
|
120 | storeResult = result;
|
121 | },
|
122 | error: function (err) {
|
123 | self.mutationStore.markMutationError(mutationId, err);
|
124 | self.dataStore.markMutationComplete({
|
125 | mutationId: mutationId,
|
126 | optimisticResponse: optimisticResponse,
|
127 | });
|
128 | self.broadcastQueries();
|
129 | self.setQuery(mutationId, function () { return ({ document: null }); });
|
130 | reject(new ApolloError_1.ApolloError({
|
131 | networkError: err,
|
132 | }));
|
133 | },
|
134 | complete: function () {
|
135 | if (error) {
|
136 | self.mutationStore.markMutationError(mutationId, error);
|
137 | }
|
138 | self.dataStore.markMutationComplete({
|
139 | mutationId: mutationId,
|
140 | optimisticResponse: optimisticResponse,
|
141 | });
|
142 | self.broadcastQueries();
|
143 | if (error) {
|
144 | reject(error);
|
145 | return;
|
146 | }
|
147 | if (typeof refetchQueries === 'function') {
|
148 | refetchQueries = refetchQueries(storeResult);
|
149 | }
|
150 | var refetchQueryPromises = [];
|
151 | if (arrays_1.isNonEmptyArray(refetchQueries)) {
|
152 | refetchQueries.forEach(function (refetchQuery) {
|
153 | if (typeof refetchQuery === 'string') {
|
154 | self.queries.forEach(function (_a) {
|
155 | var observableQuery = _a.observableQuery;
|
156 | if (observableQuery &&
|
157 | observableQuery.queryName === refetchQuery) {
|
158 | refetchQueryPromises.push(observableQuery.refetch());
|
159 | }
|
160 | });
|
161 | }
|
162 | else {
|
163 | var queryOptions = {
|
164 | query: refetchQuery.query,
|
165 | variables: refetchQuery.variables,
|
166 | fetchPolicy: 'network-only',
|
167 | };
|
168 | if (refetchQuery.context) {
|
169 | queryOptions.context = refetchQuery.context;
|
170 | }
|
171 | refetchQueryPromises.push(self.query(queryOptions));
|
172 | }
|
173 | });
|
174 | }
|
175 | Promise.all(awaitRefetchQueries ? refetchQueryPromises : []).then(function () {
|
176 | self.setQuery(mutationId, function () { return ({ document: null }); });
|
177 | if (errorPolicy === 'ignore' &&
|
178 | storeResult &&
|
179 | apollo_utilities_1.graphQLResultHasError(storeResult)) {
|
180 | delete storeResult.errors;
|
181 | }
|
182 | resolve(storeResult);
|
183 | });
|
184 | },
|
185 | });
|
186 | })];
|
187 | }
|
188 | });
|
189 | });
|
190 | };
|
191 | QueryManager.prototype.fetchQuery = function (queryId, options, fetchType, fetchMoreForQueryId) {
|
192 | return tslib_1.__awaiter(this, void 0, void 0, function () {
|
193 | var _a, metadata, _b, fetchPolicy, _c, context, query, variables, storeResult, isNetworkOnly, needToFetch, _d, complete, result, shouldFetch, requestId, cancel, networkResult;
|
194 | var _this = this;
|
195 | return tslib_1.__generator(this, function (_e) {
|
196 | switch (_e.label) {
|
197 | case 0:
|
198 | _a = options.metadata, metadata = _a === void 0 ? null : _a, _b = options.fetchPolicy, fetchPolicy = _b === void 0 ? 'cache-first' : _b, _c = options.context, context = _c === void 0 ? {} : _c;
|
199 | query = this.transform(options.query).document;
|
200 | variables = this.getVariables(query, options.variables);
|
201 | if (!this.transform(query).hasClientExports) return [3, 2];
|
202 | return [4, this.localState.addExportedVariables(query, variables, context)];
|
203 | case 1:
|
204 | variables = _e.sent();
|
205 | _e.label = 2;
|
206 | case 2:
|
207 | options = tslib_1.__assign(tslib_1.__assign({}, options), { variables: variables });
|
208 | isNetworkOnly = fetchPolicy === 'network-only' || fetchPolicy === 'no-cache';
|
209 | needToFetch = isNetworkOnly;
|
210 | if (!isNetworkOnly) {
|
211 | _d = this.dataStore.getCache().diff({
|
212 | query: query,
|
213 | variables: variables,
|
214 | returnPartialData: true,
|
215 | optimistic: false,
|
216 | }), complete = _d.complete, result = _d.result;
|
217 | needToFetch = !complete || fetchPolicy === 'cache-and-network';
|
218 | storeResult = result;
|
219 | }
|
220 | shouldFetch = needToFetch && fetchPolicy !== 'cache-only' && fetchPolicy !== 'standby';
|
221 | if (apollo_utilities_1.hasDirectives(['live'], query))
|
222 | shouldFetch = true;
|
223 | requestId = this.idCounter++;
|
224 | cancel = fetchPolicy !== 'no-cache'
|
225 | ? this.updateQueryWatch(queryId, query, options)
|
226 | : undefined;
|
227 | this.setQuery(queryId, function () { return ({
|
228 | document: query,
|
229 | lastRequestId: requestId,
|
230 | invalidated: true,
|
231 | cancel: cancel,
|
232 | }); });
|
233 | this.invalidate(fetchMoreForQueryId);
|
234 | this.queryStore.initQuery({
|
235 | queryId: queryId,
|
236 | document: query,
|
237 | storePreviousVariables: shouldFetch,
|
238 | variables: variables,
|
239 | isPoll: fetchType === types_1.FetchType.poll,
|
240 | isRefetch: fetchType === types_1.FetchType.refetch,
|
241 | metadata: metadata,
|
242 | fetchMoreForQueryId: fetchMoreForQueryId,
|
243 | });
|
244 | this.broadcastQueries();
|
245 | if (shouldFetch) {
|
246 | networkResult = this.fetchRequest({
|
247 | requestId: requestId,
|
248 | queryId: queryId,
|
249 | document: query,
|
250 | options: options,
|
251 | fetchMoreForQueryId: fetchMoreForQueryId,
|
252 | }).catch(function (error) {
|
253 | if (ApolloError_1.isApolloError(error)) {
|
254 | throw error;
|
255 | }
|
256 | else {
|
257 | if (requestId >= _this.getQuery(queryId).lastRequestId) {
|
258 | _this.queryStore.markQueryError(queryId, error, fetchMoreForQueryId);
|
259 | _this.invalidate(queryId);
|
260 | _this.invalidate(fetchMoreForQueryId);
|
261 | _this.broadcastQueries();
|
262 | }
|
263 | throw new ApolloError_1.ApolloError({ networkError: error });
|
264 | }
|
265 | });
|
266 | if (fetchPolicy !== 'cache-and-network') {
|
267 | return [2, networkResult];
|
268 | }
|
269 | networkResult.catch(function () { });
|
270 | }
|
271 | this.queryStore.markQueryResultClient(queryId, !shouldFetch);
|
272 | this.invalidate(queryId);
|
273 | this.invalidate(fetchMoreForQueryId);
|
274 | if (this.transform(query).hasForcedResolvers) {
|
275 | return [2, this.localState.runResolvers({
|
276 | document: query,
|
277 | remoteResult: { data: storeResult },
|
278 | context: context,
|
279 | variables: variables,
|
280 | onlyRunForcedResolvers: true,
|
281 | }).then(function (result) {
|
282 | _this.markQueryResult(queryId, result, options, fetchMoreForQueryId);
|
283 | _this.broadcastQueries();
|
284 | return result;
|
285 | })];
|
286 | }
|
287 | this.broadcastQueries();
|
288 | return [2, { data: storeResult }];
|
289 | }
|
290 | });
|
291 | });
|
292 | };
|
293 | QueryManager.prototype.markQueryResult = function (queryId, result, _a, fetchMoreForQueryId) {
|
294 | var fetchPolicy = _a.fetchPolicy, variables = _a.variables, errorPolicy = _a.errorPolicy;
|
295 | if (fetchPolicy === 'no-cache') {
|
296 | this.setQuery(queryId, function () { return ({
|
297 | newData: { result: result.data, complete: true },
|
298 | }); });
|
299 | }
|
300 | else {
|
301 | this.dataStore.markQueryResult(result, this.getQuery(queryId).document, variables, fetchMoreForQueryId, errorPolicy === 'ignore' || errorPolicy === 'all');
|
302 | }
|
303 | };
|
304 | QueryManager.prototype.queryListenerForObserver = function (queryId, options, observer) {
|
305 | var _this = this;
|
306 | function invoke(method, argument) {
|
307 | if (observer[method]) {
|
308 | try {
|
309 | observer[method](argument);
|
310 | }
|
311 | catch (e) {
|
312 | ts_invariant_1.invariant.error(e);
|
313 | }
|
314 | }
|
315 | else if (method === 'error') {
|
316 | ts_invariant_1.invariant.error(argument);
|
317 | }
|
318 | }
|
319 | return function (queryStoreValue, newData) {
|
320 | _this.invalidate(queryId, false);
|
321 | if (!queryStoreValue)
|
322 | return;
|
323 | var _a = _this.getQuery(queryId), observableQuery = _a.observableQuery, document = _a.document;
|
324 | var fetchPolicy = observableQuery
|
325 | ? observableQuery.options.fetchPolicy
|
326 | : options.fetchPolicy;
|
327 | if (fetchPolicy === 'standby')
|
328 | return;
|
329 | var loading = networkStatus_1.isNetworkRequestInFlight(queryStoreValue.networkStatus);
|
330 | var lastResult = observableQuery && observableQuery.getLastResult();
|
331 | var networkStatusChanged = !!(lastResult &&
|
332 | lastResult.networkStatus !== queryStoreValue.networkStatus);
|
333 | var shouldNotifyIfLoading = options.returnPartialData ||
|
334 | (!newData && queryStoreValue.previousVariables) ||
|
335 | (networkStatusChanged && options.notifyOnNetworkStatusChange) ||
|
336 | fetchPolicy === 'cache-only' ||
|
337 | fetchPolicy === 'cache-and-network';
|
338 | if (loading && !shouldNotifyIfLoading) {
|
339 | return;
|
340 | }
|
341 | var hasGraphQLErrors = arrays_1.isNonEmptyArray(queryStoreValue.graphQLErrors);
|
342 | var errorPolicy = observableQuery
|
343 | && observableQuery.options.errorPolicy
|
344 | || options.errorPolicy
|
345 | || 'none';
|
346 | if (errorPolicy === 'none' && hasGraphQLErrors || queryStoreValue.networkError) {
|
347 | return invoke('error', new ApolloError_1.ApolloError({
|
348 | graphQLErrors: queryStoreValue.graphQLErrors,
|
349 | networkError: queryStoreValue.networkError,
|
350 | }));
|
351 | }
|
352 | try {
|
353 | var data = void 0;
|
354 | var isMissing = void 0;
|
355 | if (newData) {
|
356 | if (fetchPolicy !== 'no-cache' && fetchPolicy !== 'network-only') {
|
357 | _this.setQuery(queryId, function () { return ({ newData: null }); });
|
358 | }
|
359 | data = newData.result;
|
360 | isMissing = !newData.complete;
|
361 | }
|
362 | else {
|
363 | var lastError = observableQuery && observableQuery.getLastError();
|
364 | var errorStatusChanged = errorPolicy !== 'none' &&
|
365 | (lastError && lastError.graphQLErrors) !==
|
366 | queryStoreValue.graphQLErrors;
|
367 | if (lastResult && lastResult.data && !errorStatusChanged) {
|
368 | data = lastResult.data;
|
369 | isMissing = false;
|
370 | }
|
371 | else {
|
372 | var diffResult = _this.dataStore.getCache().diff({
|
373 | query: document,
|
374 | variables: queryStoreValue.previousVariables ||
|
375 | queryStoreValue.variables,
|
376 | returnPartialData: true,
|
377 | optimistic: true,
|
378 | });
|
379 | data = diffResult.result;
|
380 | isMissing = !diffResult.complete;
|
381 | }
|
382 | }
|
383 | var stale = isMissing && !(options.returnPartialData ||
|
384 | fetchPolicy === 'cache-only');
|
385 | var resultFromStore = {
|
386 | data: stale ? lastResult && lastResult.data : data,
|
387 | loading: loading,
|
388 | networkStatus: queryStoreValue.networkStatus,
|
389 | stale: stale,
|
390 | };
|
391 | if (errorPolicy === 'all' && hasGraphQLErrors) {
|
392 | resultFromStore.errors = queryStoreValue.graphQLErrors;
|
393 | }
|
394 | invoke('next', resultFromStore);
|
395 | }
|
396 | catch (networkError) {
|
397 | invoke('error', new ApolloError_1.ApolloError({ networkError: networkError }));
|
398 | }
|
399 | };
|
400 | };
|
401 | QueryManager.prototype.transform = function (document) {
|
402 | var transformCache = this.transformCache;
|
403 | if (!transformCache.has(document)) {
|
404 | var cache = this.dataStore.getCache();
|
405 | var transformed = cache.transformDocument(document);
|
406 | var forLink = apollo_utilities_1.removeConnectionDirectiveFromDocument(cache.transformForLink(transformed));
|
407 | var clientQuery = this.localState.clientQuery(transformed);
|
408 | var serverQuery = this.localState.serverQuery(forLink);
|
409 | var cacheEntry_1 = {
|
410 | document: transformed,
|
411 | hasClientExports: apollo_utilities_1.hasClientExports(transformed),
|
412 | hasForcedResolvers: this.localState.shouldForceResolvers(transformed),
|
413 | clientQuery: clientQuery,
|
414 | serverQuery: serverQuery,
|
415 | defaultVars: apollo_utilities_1.getDefaultValues(apollo_utilities_1.getOperationDefinition(transformed)),
|
416 | };
|
417 | var add = function (doc) {
|
418 | if (doc && !transformCache.has(doc)) {
|
419 | transformCache.set(doc, cacheEntry_1);
|
420 | }
|
421 | };
|
422 | add(document);
|
423 | add(transformed);
|
424 | add(clientQuery);
|
425 | add(serverQuery);
|
426 | }
|
427 | return transformCache.get(document);
|
428 | };
|
429 | QueryManager.prototype.getVariables = function (document, variables) {
|
430 | return tslib_1.__assign(tslib_1.__assign({}, this.transform(document).defaultVars), variables);
|
431 | };
|
432 | QueryManager.prototype.watchQuery = function (options, shouldSubscribe) {
|
433 | if (shouldSubscribe === void 0) { shouldSubscribe = true; }
|
434 | ts_invariant_1.invariant(options.fetchPolicy !== 'standby', 'client.watchQuery cannot be called with fetchPolicy set to "standby"');
|
435 | options.variables = this.getVariables(options.query, options.variables);
|
436 | if (typeof options.notifyOnNetworkStatusChange === 'undefined') {
|
437 | options.notifyOnNetworkStatusChange = false;
|
438 | }
|
439 | var transformedOptions = tslib_1.__assign({}, options);
|
440 | return new ObservableQuery_1.ObservableQuery({
|
441 | queryManager: this,
|
442 | options: transformedOptions,
|
443 | shouldSubscribe: shouldSubscribe,
|
444 | });
|
445 | };
|
446 | QueryManager.prototype.query = function (options) {
|
447 | var _this = this;
|
448 | ts_invariant_1.invariant(options.query, 'query option is required. You must specify your GraphQL document ' +
|
449 | 'in the query option.');
|
450 | ts_invariant_1.invariant(options.query.kind === 'Document', 'You must wrap the query string in a "gql" tag.');
|
451 | ts_invariant_1.invariant(!options.returnPartialData, 'returnPartialData option only supported on watchQuery.');
|
452 | ts_invariant_1.invariant(!options.pollInterval, 'pollInterval option only supported on watchQuery.');
|
453 | return new Promise(function (resolve, reject) {
|
454 | var watchedQuery = _this.watchQuery(options, false);
|
455 | _this.fetchQueryRejectFns.set("query:" + watchedQuery.queryId, reject);
|
456 | watchedQuery
|
457 | .result()
|
458 | .then(resolve, reject)
|
459 | .then(function () {
|
460 | return _this.fetchQueryRejectFns.delete("query:" + watchedQuery.queryId);
|
461 | });
|
462 | });
|
463 | };
|
464 | QueryManager.prototype.generateQueryId = function () {
|
465 | return String(this.idCounter++);
|
466 | };
|
467 | QueryManager.prototype.stopQueryInStore = function (queryId) {
|
468 | this.stopQueryInStoreNoBroadcast(queryId);
|
469 | this.broadcastQueries();
|
470 | };
|
471 | QueryManager.prototype.stopQueryInStoreNoBroadcast = function (queryId) {
|
472 | this.stopPollingQuery(queryId);
|
473 | this.queryStore.stopQuery(queryId);
|
474 | this.invalidate(queryId);
|
475 | };
|
476 | QueryManager.prototype.addQueryListener = function (queryId, listener) {
|
477 | this.setQuery(queryId, function (_a) {
|
478 | var listeners = _a.listeners;
|
479 | listeners.add(listener);
|
480 | return { invalidated: false };
|
481 | });
|
482 | };
|
483 | QueryManager.prototype.updateQueryWatch = function (queryId, document, options) {
|
484 | var _this = this;
|
485 | var cancel = this.getQuery(queryId).cancel;
|
486 | if (cancel)
|
487 | cancel();
|
488 | var previousResult = function () {
|
489 | var previousResult = null;
|
490 | var observableQuery = _this.getQuery(queryId).observableQuery;
|
491 | if (observableQuery) {
|
492 | var lastResult = observableQuery.getLastResult();
|
493 | if (lastResult) {
|
494 | previousResult = lastResult.data;
|
495 | }
|
496 | }
|
497 | return previousResult;
|
498 | };
|
499 | return this.dataStore.getCache().watch({
|
500 | query: document,
|
501 | variables: options.variables,
|
502 | optimistic: true,
|
503 | previousResult: previousResult,
|
504 | callback: function (newData) {
|
505 | _this.setQuery(queryId, function () { return ({ invalidated: true, newData: newData }); });
|
506 | },
|
507 | });
|
508 | };
|
509 | QueryManager.prototype.addObservableQuery = function (queryId, observableQuery) {
|
510 | this.setQuery(queryId, function () { return ({ observableQuery: observableQuery }); });
|
511 | };
|
512 | QueryManager.prototype.removeObservableQuery = function (queryId) {
|
513 | var cancel = this.getQuery(queryId).cancel;
|
514 | this.setQuery(queryId, function () { return ({ observableQuery: null }); });
|
515 | if (cancel)
|
516 | cancel();
|
517 | };
|
518 | QueryManager.prototype.clearStore = function () {
|
519 | this.fetchQueryRejectFns.forEach(function (reject) {
|
520 | reject(new ts_invariant_1.InvariantError('Store reset while query was in flight (not completed in link chain)'));
|
521 | });
|
522 | var resetIds = [];
|
523 | this.queries.forEach(function (_a, queryId) {
|
524 | var observableQuery = _a.observableQuery;
|
525 | if (observableQuery)
|
526 | resetIds.push(queryId);
|
527 | });
|
528 | this.queryStore.reset(resetIds);
|
529 | this.mutationStore.reset();
|
530 | return this.dataStore.reset();
|
531 | };
|
532 | QueryManager.prototype.resetStore = function () {
|
533 | var _this = this;
|
534 | return this.clearStore().then(function () {
|
535 | return _this.reFetchObservableQueries();
|
536 | });
|
537 | };
|
538 | QueryManager.prototype.reFetchObservableQueries = function (includeStandby) {
|
539 | var _this = this;
|
540 | if (includeStandby === void 0) { includeStandby = false; }
|
541 | var observableQueryPromises = [];
|
542 | this.queries.forEach(function (_a, queryId) {
|
543 | var observableQuery = _a.observableQuery;
|
544 | if (observableQuery) {
|
545 | var fetchPolicy = observableQuery.options.fetchPolicy;
|
546 | observableQuery.resetLastResults();
|
547 | if (fetchPolicy !== 'cache-only' &&
|
548 | (includeStandby || fetchPolicy !== 'standby')) {
|
549 | observableQueryPromises.push(observableQuery.refetch());
|
550 | }
|
551 | _this.setQuery(queryId, function () { return ({ newData: null }); });
|
552 | _this.invalidate(queryId);
|
553 | }
|
554 | });
|
555 | this.broadcastQueries();
|
556 | return Promise.all(observableQueryPromises);
|
557 | };
|
558 | QueryManager.prototype.observeQuery = function (queryId, options, observer) {
|
559 | this.addQueryListener(queryId, this.queryListenerForObserver(queryId, options, observer));
|
560 | return this.fetchQuery(queryId, options);
|
561 | };
|
562 | QueryManager.prototype.startQuery = function (queryId, options, listener) {
|
563 | ts_invariant_1.invariant.warn("The QueryManager.startQuery method has been deprecated");
|
564 | this.addQueryListener(queryId, listener);
|
565 | this.fetchQuery(queryId, options)
|
566 | .catch(function () { return undefined; });
|
567 | return queryId;
|
568 | };
|
569 | QueryManager.prototype.startGraphQLSubscription = function (_a) {
|
570 | var _this = this;
|
571 | var query = _a.query, fetchPolicy = _a.fetchPolicy, variables = _a.variables;
|
572 | query = this.transform(query).document;
|
573 | variables = this.getVariables(query, variables);
|
574 | var makeObservable = function (variables) {
|
575 | return _this.getObservableFromLink(query, {}, variables, false).map(function (result) {
|
576 | if (!fetchPolicy || fetchPolicy !== 'no-cache') {
|
577 | _this.dataStore.markSubscriptionResult(result, query, variables);
|
578 | _this.broadcastQueries();
|
579 | }
|
580 | if (apollo_utilities_1.graphQLResultHasError(result)) {
|
581 | throw new ApolloError_1.ApolloError({
|
582 | graphQLErrors: result.errors,
|
583 | });
|
584 | }
|
585 | return result;
|
586 | });
|
587 | };
|
588 | if (this.transform(query).hasClientExports) {
|
589 | var observablePromise_1 = this.localState.addExportedVariables(query, variables).then(makeObservable);
|
590 | return new Observable_1.Observable(function (observer) {
|
591 | var sub = null;
|
592 | observablePromise_1.then(function (observable) { return sub = observable.subscribe(observer); }, observer.error);
|
593 | return function () { return sub && sub.unsubscribe(); };
|
594 | });
|
595 | }
|
596 | return makeObservable(variables);
|
597 | };
|
598 | QueryManager.prototype.stopQuery = function (queryId) {
|
599 | this.stopQueryNoBroadcast(queryId);
|
600 | this.broadcastQueries();
|
601 | };
|
602 | QueryManager.prototype.stopQueryNoBroadcast = function (queryId) {
|
603 | this.stopQueryInStoreNoBroadcast(queryId);
|
604 | this.removeQuery(queryId);
|
605 | };
|
606 | QueryManager.prototype.removeQuery = function (queryId) {
|
607 | this.fetchQueryRejectFns.delete("query:" + queryId);
|
608 | this.fetchQueryRejectFns.delete("fetchRequest:" + queryId);
|
609 | this.getQuery(queryId).subscriptions.forEach(function (x) { return x.unsubscribe(); });
|
610 | this.queries.delete(queryId);
|
611 | };
|
612 | QueryManager.prototype.getCurrentQueryResult = function (observableQuery, optimistic) {
|
613 | if (optimistic === void 0) { optimistic = true; }
|
614 | var _a = observableQuery.options, variables = _a.variables, query = _a.query, fetchPolicy = _a.fetchPolicy, returnPartialData = _a.returnPartialData;
|
615 | var lastResult = observableQuery.getLastResult();
|
616 | var newData = this.getQuery(observableQuery.queryId).newData;
|
617 | if (newData && newData.complete) {
|
618 | return { data: newData.result, partial: false };
|
619 | }
|
620 | if (fetchPolicy === 'no-cache' || fetchPolicy === 'network-only') {
|
621 | return { data: undefined, partial: false };
|
622 | }
|
623 | var _b = this.dataStore.getCache().diff({
|
624 | query: query,
|
625 | variables: variables,
|
626 | previousResult: lastResult ? lastResult.data : undefined,
|
627 | returnPartialData: true,
|
628 | optimistic: optimistic,
|
629 | }), result = _b.result, complete = _b.complete;
|
630 | return {
|
631 | data: (complete || returnPartialData) ? result : void 0,
|
632 | partial: !complete,
|
633 | };
|
634 | };
|
635 | QueryManager.prototype.getQueryWithPreviousResult = function (queryIdOrObservable) {
|
636 | var observableQuery;
|
637 | if (typeof queryIdOrObservable === 'string') {
|
638 | var foundObserveableQuery = this.getQuery(queryIdOrObservable).observableQuery;
|
639 | ts_invariant_1.invariant(foundObserveableQuery, "ObservableQuery with this id doesn't exist: " + queryIdOrObservable);
|
640 | observableQuery = foundObserveableQuery;
|
641 | }
|
642 | else {
|
643 | observableQuery = queryIdOrObservable;
|
644 | }
|
645 | var _a = observableQuery.options, variables = _a.variables, query = _a.query;
|
646 | return {
|
647 | previousResult: this.getCurrentQueryResult(observableQuery, false).data,
|
648 | variables: variables,
|
649 | document: query,
|
650 | };
|
651 | };
|
652 | QueryManager.prototype.broadcastQueries = function () {
|
653 | var _this = this;
|
654 | this.onBroadcast();
|
655 | this.queries.forEach(function (info, id) {
|
656 | if (info.invalidated) {
|
657 | info.listeners.forEach(function (listener) {
|
658 | if (listener) {
|
659 | listener(_this.queryStore.get(id), info.newData);
|
660 | }
|
661 | });
|
662 | }
|
663 | });
|
664 | };
|
665 | QueryManager.prototype.getLocalState = function () {
|
666 | return this.localState;
|
667 | };
|
668 | QueryManager.prototype.getObservableFromLink = function (query, context, variables, deduplication) {
|
669 | var _this = this;
|
670 | if (deduplication === void 0) { deduplication = this.queryDeduplication; }
|
671 | var observable;
|
672 | var serverQuery = this.transform(query).serverQuery;
|
673 | if (serverQuery) {
|
674 | var _a = this, inFlightLinkObservables_1 = _a.inFlightLinkObservables, link = _a.link;
|
675 | var operation = {
|
676 | query: serverQuery,
|
677 | variables: variables,
|
678 | operationName: apollo_utilities_1.getOperationName(serverQuery) || void 0,
|
679 | context: this.prepareContext(tslib_1.__assign(tslib_1.__assign({}, context), { forceFetch: !deduplication })),
|
680 | };
|
681 | context = operation.context;
|
682 | if (deduplication) {
|
683 | var byVariables_1 = inFlightLinkObservables_1.get(serverQuery) || new Map();
|
684 | inFlightLinkObservables_1.set(serverQuery, byVariables_1);
|
685 | var varJson_1 = JSON.stringify(variables);
|
686 | observable = byVariables_1.get(varJson_1);
|
687 | if (!observable) {
|
688 | byVariables_1.set(varJson_1, observable = observables_1.multiplex(apollo_link_1.execute(link, operation)));
|
689 | var cleanup = function () {
|
690 | byVariables_1.delete(varJson_1);
|
691 | if (!byVariables_1.size)
|
692 | inFlightLinkObservables_1.delete(serverQuery);
|
693 | cleanupSub_1.unsubscribe();
|
694 | };
|
695 | var cleanupSub_1 = observable.subscribe({
|
696 | next: cleanup,
|
697 | error: cleanup,
|
698 | complete: cleanup,
|
699 | });
|
700 | }
|
701 | }
|
702 | else {
|
703 | observable = observables_1.multiplex(apollo_link_1.execute(link, operation));
|
704 | }
|
705 | }
|
706 | else {
|
707 | observable = Observable_1.Observable.of({ data: {} });
|
708 | context = this.prepareContext(context);
|
709 | }
|
710 | var clientQuery = this.transform(query).clientQuery;
|
711 | if (clientQuery) {
|
712 | observable = observables_1.asyncMap(observable, function (result) {
|
713 | return _this.localState.runResolvers({
|
714 | document: clientQuery,
|
715 | remoteResult: result,
|
716 | context: context,
|
717 | variables: variables,
|
718 | });
|
719 | });
|
720 | }
|
721 | return observable;
|
722 | };
|
723 | QueryManager.prototype.fetchRequest = function (_a) {
|
724 | var _this = this;
|
725 | var requestId = _a.requestId, queryId = _a.queryId, document = _a.document, options = _a.options, fetchMoreForQueryId = _a.fetchMoreForQueryId;
|
726 | var variables = options.variables, _b = options.errorPolicy, errorPolicy = _b === void 0 ? 'none' : _b, fetchPolicy = options.fetchPolicy;
|
727 | var resultFromStore;
|
728 | var errorsFromStore;
|
729 | return new Promise(function (resolve, reject) {
|
730 | var observable = _this.getObservableFromLink(document, options.context, variables);
|
731 | var fqrfId = "fetchRequest:" + queryId;
|
732 | _this.fetchQueryRejectFns.set(fqrfId, reject);
|
733 | var cleanup = function () {
|
734 | _this.fetchQueryRejectFns.delete(fqrfId);
|
735 | _this.setQuery(queryId, function (_a) {
|
736 | var subscriptions = _a.subscriptions;
|
737 | subscriptions.delete(subscription);
|
738 | });
|
739 | };
|
740 | var subscription = observable.map(function (result) {
|
741 | if (requestId >= _this.getQuery(queryId).lastRequestId) {
|
742 | _this.markQueryResult(queryId, result, options, fetchMoreForQueryId);
|
743 | _this.queryStore.markQueryResult(queryId, result, fetchMoreForQueryId);
|
744 | _this.invalidate(queryId);
|
745 | _this.invalidate(fetchMoreForQueryId);
|
746 | _this.broadcastQueries();
|
747 | }
|
748 | if (errorPolicy === 'none' && arrays_1.isNonEmptyArray(result.errors)) {
|
749 | return reject(new ApolloError_1.ApolloError({
|
750 | graphQLErrors: result.errors,
|
751 | }));
|
752 | }
|
753 | if (errorPolicy === 'all') {
|
754 | errorsFromStore = result.errors;
|
755 | }
|
756 | if (fetchMoreForQueryId || fetchPolicy === 'no-cache') {
|
757 | resultFromStore = result.data;
|
758 | }
|
759 | else {
|
760 | var _a = _this.dataStore.getCache().diff({
|
761 | variables: variables,
|
762 | query: document,
|
763 | optimistic: false,
|
764 | returnPartialData: true,
|
765 | }), result_1 = _a.result, complete = _a.complete;
|
766 | if (complete || options.returnPartialData) {
|
767 | resultFromStore = result_1;
|
768 | }
|
769 | }
|
770 | }).subscribe({
|
771 | error: function (error) {
|
772 | cleanup();
|
773 | reject(error);
|
774 | },
|
775 | complete: function () {
|
776 | cleanup();
|
777 | resolve({
|
778 | data: resultFromStore,
|
779 | errors: errorsFromStore,
|
780 | loading: false,
|
781 | networkStatus: networkStatus_1.NetworkStatus.ready,
|
782 | stale: false,
|
783 | });
|
784 | },
|
785 | });
|
786 | _this.setQuery(queryId, function (_a) {
|
787 | var subscriptions = _a.subscriptions;
|
788 | subscriptions.add(subscription);
|
789 | });
|
790 | });
|
791 | };
|
792 | QueryManager.prototype.getQuery = function (queryId) {
|
793 | return (this.queries.get(queryId) || {
|
794 | listeners: new Set(),
|
795 | invalidated: false,
|
796 | document: null,
|
797 | newData: null,
|
798 | lastRequestId: 1,
|
799 | observableQuery: null,
|
800 | subscriptions: new Set(),
|
801 | });
|
802 | };
|
803 | QueryManager.prototype.setQuery = function (queryId, updater) {
|
804 | var prev = this.getQuery(queryId);
|
805 | var newInfo = tslib_1.__assign(tslib_1.__assign({}, prev), updater(prev));
|
806 | this.queries.set(queryId, newInfo);
|
807 | };
|
808 | QueryManager.prototype.invalidate = function (queryId, invalidated) {
|
809 | if (invalidated === void 0) { invalidated = true; }
|
810 | if (queryId) {
|
811 | this.setQuery(queryId, function () { return ({ invalidated: invalidated }); });
|
812 | }
|
813 | };
|
814 | QueryManager.prototype.prepareContext = function (context) {
|
815 | if (context === void 0) { context = {}; }
|
816 | var newContext = this.localState.prepareContext(context);
|
817 | return tslib_1.__assign(tslib_1.__assign({}, newContext), { clientAwareness: this.clientAwareness });
|
818 | };
|
819 | QueryManager.prototype.checkInFlight = function (queryId) {
|
820 | var query = this.queryStore.get(queryId);
|
821 | return (query &&
|
822 | query.networkStatus !== networkStatus_1.NetworkStatus.ready &&
|
823 | query.networkStatus !== networkStatus_1.NetworkStatus.error);
|
824 | };
|
825 | QueryManager.prototype.startPollingQuery = function (options, queryId, listener) {
|
826 | var _this = this;
|
827 | var pollInterval = options.pollInterval;
|
828 | ts_invariant_1.invariant(pollInterval, 'Attempted to start a polling query without a polling interval.');
|
829 | if (!this.ssrMode) {
|
830 | var info = this.pollingInfoByQueryId.get(queryId);
|
831 | if (!info) {
|
832 | this.pollingInfoByQueryId.set(queryId, (info = {}));
|
833 | }
|
834 | info.interval = pollInterval;
|
835 | info.options = tslib_1.__assign(tslib_1.__assign({}, options), { fetchPolicy: 'network-only' });
|
836 | var maybeFetch_1 = function () {
|
837 | var info = _this.pollingInfoByQueryId.get(queryId);
|
838 | if (info) {
|
839 | if (_this.checkInFlight(queryId)) {
|
840 | poll_1();
|
841 | }
|
842 | else {
|
843 | _this.fetchQuery(queryId, info.options, types_1.FetchType.poll).then(poll_1, poll_1);
|
844 | }
|
845 | }
|
846 | };
|
847 | var poll_1 = function () {
|
848 | var info = _this.pollingInfoByQueryId.get(queryId);
|
849 | if (info) {
|
850 | clearTimeout(info.timeout);
|
851 | info.timeout = setTimeout(maybeFetch_1, info.interval);
|
852 | }
|
853 | };
|
854 | if (listener) {
|
855 | this.addQueryListener(queryId, listener);
|
856 | }
|
857 | poll_1();
|
858 | }
|
859 | return queryId;
|
860 | };
|
861 | QueryManager.prototype.stopPollingQuery = function (queryId) {
|
862 | this.pollingInfoByQueryId.delete(queryId);
|
863 | };
|
864 | return QueryManager;
|
865 | }());
|
866 | exports.QueryManager = QueryManager;
|
867 |
|
\ | No newline at end of file |