apollo-client
Version:
A simple yet functional GraphQL client.
144 lines • 6.56 kB
JavaScript
var __assign = (this && this.__assign) || Object.assign || function(t) {
for (var s, i = 1, n = arguments.length; i < n; i++) {
s = arguments[i];
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
t[p] = s[p];
}
return t;
};
import { print } from 'graphql/language/printer';
import { isEqual } from 'apollo-utilities';
import { NetworkStatus } from '../core/networkStatus';
var QueryStore = /** @class */ (function () {
function QueryStore() {
this.store = {};
}
QueryStore.prototype.getStore = function () {
return this.store;
};
QueryStore.prototype.get = function (queryId) {
return this.store[queryId];
};
QueryStore.prototype.initQuery = function (query) {
var previousQuery = this.store[query.queryId];
if (previousQuery &&
previousQuery.document !== query.document &&
print(previousQuery.document) !== print(query.document)) {
// XXX we're throwing an error here to catch bugs where a query gets overwritten by a new one.
// we should implement a separate action for refetching so that QUERY_INIT may never overwrite
// an existing query (see also: https://github.com/apollostack/apollo-client/issues/732)
throw new Error('Internal Error: may not update existing query string in store');
}
var isSetVariables = false;
var previousVariables = null;
if (query.storePreviousVariables &&
previousQuery &&
previousQuery.networkStatus !== NetworkStatus.loading
// if the previous query was still loading, we don't want to remember it at all.
) {
if (!isEqual(previousQuery.variables, query.variables)) {
isSetVariables = true;
previousVariables = previousQuery.variables;
}
}
// TODO break this out into a separate function
var networkStatus;
if (isSetVariables) {
networkStatus = NetworkStatus.setVariables;
}
else if (query.isPoll) {
networkStatus = NetworkStatus.poll;
}
else if (query.isRefetch) {
networkStatus = NetworkStatus.refetch;
// TODO: can we determine setVariables here if it's a refetch and the variables have changed?
}
else {
networkStatus = NetworkStatus.loading;
}
var graphQLErrors = [];
if (previousQuery && previousQuery.graphQLErrors) {
graphQLErrors = previousQuery.graphQLErrors;
}
// XXX right now if QUERY_INIT is fired twice, like in a refetch situation, we just overwrite
// the store. We probably want a refetch action instead, because I suspect that if you refetch
// before the initial fetch is done, you'll get an error.
this.store[query.queryId] = {
document: query.document,
variables: query.variables,
previousVariables: previousVariables,
networkError: null,
graphQLErrors: graphQLErrors,
networkStatus: networkStatus,
metadata: query.metadata,
};
// If the action had a `moreForQueryId` property then we need to set the
// network status on that query as well to `fetchMore`.
//
// We have a complement to this if statement in the query result and query
// error action branch, but importantly *not* in the client result branch.
// This is because the implementation of `fetchMore` *always* sets
// `fetchPolicy` to `network-only` so we would never have a client result.
if (typeof query.fetchMoreForQueryId === 'string' &&
this.store[query.fetchMoreForQueryId]) {
this.store[query.fetchMoreForQueryId].networkStatus =
NetworkStatus.fetchMore;
}
};
QueryStore.prototype.markQueryResult = function (queryId, result, fetchMoreForQueryId) {
if (!this.store[queryId])
return;
this.store[queryId].networkError = null;
this.store[queryId].graphQLErrors =
result.errors && result.errors.length ? result.errors : [];
this.store[queryId].previousVariables = null;
this.store[queryId].networkStatus = NetworkStatus.ready;
// If we have a `fetchMoreForQueryId` then we need to update the network
// status for that query. See the branch for query initialization for more
// explanation about this process.
if (typeof fetchMoreForQueryId === 'string' &&
this.store[fetchMoreForQueryId]) {
this.store[fetchMoreForQueryId].networkStatus = NetworkStatus.ready;
}
};
QueryStore.prototype.markQueryError = function (queryId, error, fetchMoreForQueryId) {
if (!this.store[queryId])
return;
this.store[queryId].networkError = error;
this.store[queryId].networkStatus = NetworkStatus.error;
// If we have a `fetchMoreForQueryId` then we need to update the network
// status for that query. See the branch for query initialization for more
// explanation about this process.
if (typeof fetchMoreForQueryId === 'string') {
this.markQueryResultClient(fetchMoreForQueryId, true);
}
};
QueryStore.prototype.markQueryResultClient = function (queryId, complete) {
if (!this.store[queryId])
return;
this.store[queryId].networkError = null;
this.store[queryId].previousVariables = null;
this.store[queryId].networkStatus = complete
? NetworkStatus.ready
: NetworkStatus.loading;
};
QueryStore.prototype.stopQuery = function (queryId) {
delete this.store[queryId];
};
QueryStore.prototype.reset = function (observableQueryIds) {
var _this = this;
// keep only the queries with query ids that are associated with observables
this.store = Object.keys(this.store)
.filter(function (queryId) {
return observableQueryIds.indexOf(queryId) > -1;
})
.reduce(function (res, key) {
// XXX set loading to true so listeners don't trigger unless they want results with partial data
res[key] = __assign({}, _this.store[key], { networkStatus: NetworkStatus.loading });
return res;
}, {});
};
return QueryStore;
}());
export { QueryStore };
//# sourceMappingURL=queries.js.map