apollo-client
Version:
A simple yet functional GraphQL client.
305 lines • 12.9 kB
JavaScript
var __extends = (this && this.__extends) || function (d, b) {
for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p];
function __() { this.constructor = d; }
d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
};
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 { Observable } from '../util/Observable';
import { ApolloError, } from '../errors/ApolloError';
import { FetchType, } from './types';
import { tryFunctionOrLogError } from '../util/errorHandling';
import { isEqual } from '../util/isEqual';
import { NetworkStatus, isNetworkRequestInFlight, } from '../queries/networkStatus';
var ObservableQuery = (function (_super) {
__extends(ObservableQuery, _super);
function ObservableQuery(_a) {
var scheduler = _a.scheduler, options = _a.options, _b = _a.shouldSubscribe, shouldSubscribe = _b === void 0 ? true : _b;
var _this = this;
var queryManager = scheduler.queryManager;
var queryId = queryManager.generateQueryId();
var subscriberFunction = function (observer) {
return _this.onSubscribe(observer);
};
_this = _super.call(this, subscriberFunction) || this;
_this.isCurrentlyPolling = false;
_this.options = options;
_this.variables = _this.options.variables || {};
_this.scheduler = scheduler;
_this.queryManager = queryManager;
_this.queryId = queryId;
_this.shouldSubscribe = shouldSubscribe;
_this.observers = [];
_this.subscriptionHandles = [];
return _this;
}
ObservableQuery.prototype.result = function () {
var _this = this;
return new Promise(function (resolve, reject) {
var subscription = _this.subscribe({
next: function (result) {
resolve(result);
setTimeout(function () {
subscription.unsubscribe();
}, 0);
},
error: function (error) {
reject(error);
},
});
});
};
ObservableQuery.prototype.currentResult = function () {
var _a = this.queryManager.getCurrentQueryResult(this, true), data = _a.data, partial = _a.partial;
var queryStoreValue = this.queryManager.getApolloState().queries[this.queryId];
if (queryStoreValue && ((queryStoreValue.graphQLErrors && queryStoreValue.graphQLErrors.length > 0) ||
queryStoreValue.networkError)) {
var error = new ApolloError({
graphQLErrors: queryStoreValue.graphQLErrors,
networkError: queryStoreValue.networkError,
});
return { data: {}, loading: false, networkStatus: queryStoreValue.networkStatus, error: error };
}
var queryLoading = !queryStoreValue || queryStoreValue.networkStatus === NetworkStatus.loading;
var loading = (this.options.forceFetch && queryLoading)
|| (partial && !this.options.noFetch);
var networkStatus;
if (queryStoreValue) {
networkStatus = queryStoreValue.networkStatus;
}
else {
networkStatus = loading ? NetworkStatus.loading : NetworkStatus.ready;
}
return {
data: data,
loading: isNetworkRequestInFlight(networkStatus),
networkStatus: networkStatus,
partial: partial,
};
};
ObservableQuery.prototype.getLastResult = function () {
return this.lastResult;
};
ObservableQuery.prototype.refetch = function (variables) {
var _this = this;
this.variables = __assign({}, this.variables, variables);
if (this.options.noFetch) {
throw new Error('noFetch option should not use query refetch.');
}
this.options.variables = __assign({}, this.options.variables, this.variables);
var combinedOptions = __assign({}, this.options, { forceFetch: true });
return this.queryManager.fetchQuery(this.queryId, combinedOptions, FetchType.refetch)
.then(function (result) { return _this.queryManager.transformResult(result); });
};
ObservableQuery.prototype.fetchMore = function (fetchMoreOptions) {
var _this = this;
return Promise.resolve()
.then(function () {
var qid = _this.queryManager.generateQueryId();
var combinedOptions = null;
if (fetchMoreOptions.query) {
combinedOptions = fetchMoreOptions;
}
else {
var variables = __assign({}, _this.variables, fetchMoreOptions.variables);
combinedOptions = __assign({}, _this.options, fetchMoreOptions, { variables: variables });
}
combinedOptions = __assign({}, combinedOptions, { query: combinedOptions.query, forceFetch: true });
return _this.queryManager.fetchQuery(qid, combinedOptions);
})
.then(function (fetchMoreResult) {
var reducer = fetchMoreOptions.updateQuery;
var mapFn = function (previousResult, _a) {
var variables = _a.variables;
var queryVariables = variables;
return reducer(previousResult, {
fetchMoreResult: fetchMoreResult,
queryVariables: queryVariables,
});
};
_this.updateQuery(mapFn);
return fetchMoreResult;
});
};
ObservableQuery.prototype.subscribeToMore = function (options) {
var _this = this;
var observable = this.queryManager.startGraphQLSubscription({
document: options.document,
variables: options.variables,
});
var reducer = options.updateQuery;
var subscription = observable.subscribe({
next: function (data) {
var mapFn = function (previousResult, _a) {
var variables = _a.variables;
return reducer(previousResult, {
subscriptionData: { data: data },
variables: variables,
});
};
_this.updateQuery(mapFn);
},
error: function (err) {
if (options.onError) {
options.onError(err);
}
else {
console.error('Unhandled GraphQL subscription errror', err);
}
},
});
this.subscriptionHandles.push(subscription);
return function () {
var i = _this.subscriptionHandles.indexOf(subscription);
if (i >= 0) {
_this.subscriptionHandles.splice(i, 1);
subscription.unsubscribe();
}
};
};
ObservableQuery.prototype.setOptions = function (opts) {
var oldOptions = this.options;
this.options = __assign({}, this.options, opts);
if (opts.pollInterval) {
this.startPolling(opts.pollInterval);
}
else if (opts.pollInterval === 0) {
this.stopPolling();
}
var tryFetch = (!oldOptions.forceFetch && opts.forceFetch)
|| (oldOptions.noFetch && !opts.noFetch) || false;
return this.setVariables(this.options.variables, tryFetch);
};
ObservableQuery.prototype.setVariables = function (variables, tryFetch) {
var _this = this;
if (tryFetch === void 0) { tryFetch = false; }
var newVariables = __assign({}, this.variables, variables);
var nullPromise = new Promise(function (resolve) { return resolve(); });
if (isEqual(newVariables, this.variables) && !tryFetch) {
if (this.observers.length === 0) {
return nullPromise;
}
return this.result();
}
else {
this.variables = newVariables;
if (this.observers.length === 0) {
return nullPromise;
}
return this.queryManager.fetchQuery(this.queryId, __assign({}, this.options, { variables: this.variables }))
.then(function (result) { return _this.queryManager.transformResult(result); });
}
};
ObservableQuery.prototype.updateQuery = function (mapFn) {
var _a = this.queryManager.getQueryWithPreviousResult(this.queryId), previousResult = _a.previousResult, variables = _a.variables, document = _a.document;
var newResult = tryFunctionOrLogError(function () { return mapFn(previousResult, { variables: variables }); });
if (newResult) {
this.queryManager.store.dispatch({
type: 'APOLLO_UPDATE_QUERY_RESULT',
newResult: newResult,
variables: variables,
document: document,
});
}
};
ObservableQuery.prototype.stopPolling = function () {
if (this.isCurrentlyPolling) {
this.scheduler.stopPollingQuery(this.queryId);
this.isCurrentlyPolling = false;
}
};
ObservableQuery.prototype.startPolling = function (pollInterval) {
if (this.options.noFetch) {
throw new Error('noFetch option should not use query polling.');
}
if (this.isCurrentlyPolling) {
this.scheduler.stopPollingQuery(this.queryId);
this.isCurrentlyPolling = false;
}
this.options.pollInterval = pollInterval;
this.isCurrentlyPolling = true;
this.scheduler.startPollingQuery(this.options, this.queryId);
};
ObservableQuery.prototype.onSubscribe = function (observer) {
var _this = this;
this.observers.push(observer);
if (observer.next && this.lastResult) {
observer.next(this.lastResult);
}
if (observer.error && this.lastError) {
observer.error(this.lastError);
}
if (this.observers.length === 1) {
this.setUpQuery();
}
var retQuerySubscription = {
unsubscribe: function () {
if (_this.observers.findIndex(function (el) { return el === observer; }) < 0) {
return;
}
_this.observers = _this.observers.filter(function (obs) { return obs !== observer; });
if (_this.observers.length === 0) {
_this.tearDownQuery();
}
},
};
return retQuerySubscription;
};
ObservableQuery.prototype.setUpQuery = function () {
var _this = this;
if (this.shouldSubscribe) {
this.queryManager.addObservableQuery(this.queryId, this);
}
if (!!this.options.pollInterval) {
if (this.options.noFetch) {
throw new Error('noFetch option should not use query polling.');
}
this.isCurrentlyPolling = true;
this.scheduler.startPollingQuery(this.options, this.queryId);
}
var observer = {
next: function (result) {
_this.lastResult = result;
_this.observers.forEach(function (obs) {
if (obs.next) {
obs.next(result);
}
});
},
error: function (error) {
_this.observers.forEach(function (obs) {
if (obs.error) {
obs.error(error);
}
else {
console.error('Unhandled error', error.message, error.stack);
}
});
_this.lastError = error;
},
};
this.queryManager.startQuery(this.queryId, this.options, this.queryManager.queryListenerForObserver(this.queryId, this.options, observer));
};
ObservableQuery.prototype.tearDownQuery = function () {
if (this.isCurrentlyPolling) {
this.scheduler.stopPollingQuery(this.queryId);
this.isCurrentlyPolling = false;
}
this.subscriptionHandles.forEach(function (sub) { return sub.unsubscribe(); });
this.subscriptionHandles = [];
this.queryManager.stopQuery(this.queryId);
if (this.shouldSubscribe) {
this.queryManager.removeObservableQuery(this.queryId);
}
this.observers = [];
};
return ObservableQuery;
}(Observable));
export { ObservableQuery };
//# sourceMappingURL=ObservableQuery.js.map