react-apollo
Version:
React data container for Apollo Client
246 lines • 10.5 kB
JavaScript
var __extends = (this && this.__extends) || (function () {
var extendStatics = Object.setPrototypeOf ||
({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
return function (d, b) {
extendStatics(d, b);
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;
};
var __rest = (this && this.__rest) || function (s, e) {
var t = {};
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
t[p] = s[p];
if (s != null && typeof Object.getOwnPropertySymbols === "function")
for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) if (e.indexOf(p[i]) < 0)
t[p[i]] = s[p[i]];
return t;
};
import * as React from 'react';
import * as PropTypes from 'prop-types';
import { ApolloError, } from 'apollo-client';
import { parser, DocumentType } from './parser';
var shallowEqual = require('fbjs/lib/shallowEqual');
var invariant = require('invariant');
function compact(obj) {
return Object.keys(obj).reduce(function (acc, key) {
if (obj[key] !== undefined) {
acc[key] = obj[key];
}
return acc;
}, {});
}
function observableQueryFields(observable) {
var fields = {
variables: observable.variables,
refetch: observable.refetch.bind(observable),
fetchMore: observable.fetchMore.bind(observable),
updateQuery: observable.updateQuery.bind(observable),
startPolling: observable.startPolling.bind(observable),
stopPolling: observable.stopPolling.bind(observable),
subscribeToMore: observable.subscribeToMore.bind(observable),
};
return fields;
}
var Query = (function (_super) {
__extends(Query, _super);
function Query(props, context) {
var _this = _super.call(this, props, context) || this;
_this.previousData = {};
_this.startQuerySubscription = function () {
if (_this.querySubscription)
return;
var current = _this.getQueryResult();
_this.querySubscription = _this.queryObservable.subscribe({
next: function () {
if (current && current.networkStatus === 7) {
current = undefined;
return;
}
_this.updateCurrentData();
},
error: function (error) {
_this.resubscribeToQuery();
if (!error.hasOwnProperty('graphQLErrors'))
throw error;
_this.updateCurrentData();
},
});
};
_this.removeQuerySubscription = function () {
if (_this.querySubscription) {
_this.querySubscription.unsubscribe();
delete _this.querySubscription;
}
};
_this.updateCurrentData = function () {
if (_this.hasMounted)
_this.forceUpdate();
};
_this.getQueryResult = function () {
var data = { data: Object.create(null) };
Object.assign(data, observableQueryFields(_this.queryObservable));
var currentResult = _this.queryObservable.currentResult();
var loading = currentResult.loading, networkStatus = currentResult.networkStatus, errors = currentResult.errors;
var error = currentResult.error;
if (errors && errors.length > 0) {
error = new ApolloError({ graphQLErrors: errors });
}
Object.assign(data, { loading: loading, networkStatus: networkStatus, error: error });
if (loading) {
Object.assign(data.data, _this.previousData, currentResult.data);
}
else if (error) {
Object.assign(data, {
data: (_this.queryObservable.getLastResult() || {}).data,
});
}
else {
Object.assign(data.data, currentResult.data);
_this.previousData = currentResult.data;
}
if (!_this.querySubscription) {
data.refetch = function (args) {
return new Promise(function (r, f) {
_this.refetcherQueue = { resolve: r, reject: f, args: args };
});
};
}
data.client = _this.client;
return data;
};
_this.client = props.client || context.client;
invariant(!!_this.client, "Could not find \"client\" in the context of Query or as passed props. Wrap the root component in an <ApolloProvider>");
_this.initializeQueryObservable(props);
return _this;
}
Query.prototype.fetchData = function () {
if (this.props.skip)
return false;
var _a = this.props, children = _a.children, ssr = _a.ssr, displayName = _a.displayName, skip = _a.skip, client = _a.client, opts = __rest(_a, ["children", "ssr", "displayName", "skip", "client"]);
var fetchPolicy = opts.fetchPolicy;
if (ssr === false)
return false;
if (fetchPolicy === 'network-only' || fetchPolicy === 'cache-and-network') {
fetchPolicy = 'cache-first';
}
var observable = this.client.watchQuery(__assign({}, opts, { fetchPolicy: fetchPolicy }));
var result = this.queryObservable.currentResult();
return result.loading ? observable.result() : false;
};
Query.prototype.componentDidMount = function () {
this.hasMounted = true;
if (this.props.skip)
return;
this.startQuerySubscription();
if (this.refetcherQueue) {
var _a = this.refetcherQueue, args = _a.args, resolve = _a.resolve, reject = _a.reject;
this.queryObservable.refetch(args)
.then(resolve)
.catch(reject);
}
};
Query.prototype.componentWillReceiveProps = function (nextProps, nextContext) {
if (nextProps.skip && !this.props.skip) {
this.removeQuerySubscription();
return;
}
var client = nextProps.client;
if (shallowEqual(this.props, nextProps) &&
(this.client === client || this.client === nextContext.client)) {
return;
}
if (this.client !== client && this.client !== nextContext.client) {
if (client) {
this.client = client;
}
else {
this.client = nextContext.client;
}
this.removeQuerySubscription();
this.queryObservable = null;
this.previousData = {};
this.updateQuery(nextProps);
}
if (this.props.query !== nextProps.query) {
this.removeQuerySubscription();
}
this.updateQuery(nextProps);
if (nextProps.skip)
return;
this.startQuerySubscription();
};
Query.prototype.componentWillUnmount = function () {
this.removeQuerySubscription();
this.hasMounted = false;
};
Query.prototype.render = function () {
var children = this.props.children;
var queryResult = this.getQueryResult();
return children(queryResult);
};
Query.prototype.extractOptsFromProps = function (props) {
var variables = props.variables, pollInterval = props.pollInterval, fetchPolicy = props.fetchPolicy, errorPolicy = props.errorPolicy, notifyOnNetworkStatusChange = props.notifyOnNetworkStatusChange, query = props.query, _a = props.displayName, displayName = _a === void 0 ? 'Query' : _a, _b = props.context, context = _b === void 0 ? {} : _b;
this.operation = parser(query);
invariant(this.operation.type === DocumentType.Query, "The <Query /> component requires a graphql query, but got a " + (this.operation.type === DocumentType.Mutation ? 'mutation' : 'subscription') + ".");
return compact({
variables: variables,
pollInterval: pollInterval,
query: query,
fetchPolicy: fetchPolicy,
errorPolicy: errorPolicy,
notifyOnNetworkStatusChange: notifyOnNetworkStatusChange,
metadata: { reactComponent: { displayName: displayName } },
context: context,
});
};
Query.prototype.initializeQueryObservable = function (props) {
var opts = this.extractOptsFromProps(props);
if (this.context.operations) {
this.context.operations.set(this.operation.name, {
query: opts.query,
variables: opts.variables,
});
}
this.queryObservable = this.client.watchQuery(opts);
};
Query.prototype.updateQuery = function (props) {
if (!this.queryObservable)
this.initializeQueryObservable(props);
this.queryObservable.setOptions(this.extractOptsFromProps(props))
.catch(function () { return null; });
};
Query.prototype.resubscribeToQuery = function () {
this.removeQuerySubscription();
var lastError = this.queryObservable.getLastError();
var lastResult = this.queryObservable.getLastResult();
this.queryObservable.resetLastResults();
this.startQuerySubscription();
Object.assign(this.queryObservable, { lastError: lastError, lastResult: lastResult });
};
Query.contextTypes = {
client: PropTypes.object.isRequired,
operations: PropTypes.object,
};
Query.propTypes = {
children: PropTypes.func.isRequired,
fetchPolicy: PropTypes.string,
notifyOnNetworkStatusChange: PropTypes.bool,
pollInterval: PropTypes.number,
query: PropTypes.object.isRequired,
variables: PropTypes.object,
ssr: PropTypes.bool,
};
return Query;
}(React.Component));
export default Query;
//# sourceMappingURL=Query.js.map