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