react-blips
Version:
Official React bindings for Blips
294 lines (223 loc) • 11.7 kB
JavaScript
var _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; };
function _asyncToGenerator(fn) { return function () { var gen = fn.apply(this, arguments); return new Promise(function (resolve, reject) { function step(key, arg) { try { var info = gen[key](arg); var value = info.value; } catch (error) { reject(error); return; } if (info.done) { resolve(value); } else { return Promise.resolve(value).then(function (value) { step("next", value); }, function (err) { step("throw", err); }); } } return step("next"); }); }; }
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }
import React, { Component } from 'react';
import PropTypes from 'prop-types';
import { parse } from 'graphql';
import hoistNonReactStatics from 'hoist-non-react-statics';
import invariant from 'invariant';
import { shallowEqual, getPropNameOr, computeNextState, mapObject, operationsMap, mergeOperations, convertSubscriptionToQuery } from '../utils';
export function createGraphQLHoc(sources, config) {
var dataKey = getPropNameOr('data')(config);
var mutationsKey = getPropNameOr('mutations')(config);
var queriesKey = getPropNameOr('queries')(config);
var promiseRegistry = [];
var registerPromise = promiseRegistry.push.bind(promiseRegistry);
var clearPromiseRegistry = function clearPromiseRegistry() {
return promiseRegistry.length = 0;
};
var subscriptionRegistry = [];
var registerSubscription = subscriptionRegistry.push.bind(subscriptionRegistry);
var clearSubscriptionRegistry = function clearSubscriptionRegistry() {
return subscriptionRegistry.length = 0;
};
var cancelSubscriptions = function cancelSubscriptions() {
for (var _iterator = subscriptionRegistry, _isArray = Array.isArray(_iterator), _i = 0, _iterator = _isArray ? _iterator : _iterator[Symbol.iterator]();;) {
var _ref;
if (_isArray) {
if (_i >= _iterator.length) break;
_ref = _iterator[_i++];
} else {
_i = _iterator.next();
if (_i.done) break;
_ref = _i.value;
}
var subscription = _ref;
subscription.unsubscribe();
}
};
var updateBatch = [];
var computeOptions = function computeOptions(props) {
return config.options && typeof config.options === 'function' ? config.options(props) : config.options || {};
};
return function createGraphQLHoc(BaseComponent) {
invariant(typeof BaseComponent === 'function', 'You must pass a component to the function returned by graphql. Instead received ' + JSON.stringify(BaseComponent));
var Blips = function (_Component) {
_inherits(Blips, _Component);
function Blips(props, context) {
var _this$state,
_this2 = this;
_classCallCheck(this, Blips);
var _this = _possibleConstructorReturn(this, _Component.call(this, props, context));
_this.state = (_this$state = {}, _this$state[dataKey] = {
loading: true
}, _this$state);
_this.cancelResolve = function () {};
_this.batchUpdateState = function () {
var list = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : updateBatch;
var state = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : _this.state;
var force = arguments[2];
if (list.length === 0 && !force) return;
_this.setState(computeNextState(list, {
dataKey: dataKey,
queriesKey: queriesKey,
mutationsKey: mutationsKey
}, state));
updateBatch.length = 0;
};
_this.parse = function (sources) {
var documents = sources.map(parse);
var operations = documents.map(operationsMap).reduce(mergeOperations, {});
return {
sources: sources,
documents: documents,
operations: operations
};
};
_this.resolve = function () {
var _Promise$resolve;
var cancel = false;
var _this$parsedData$oper = _this.parsedData.operations,
_this$parsedData$oper2 = _this$parsedData$oper.query,
queries = _this$parsedData$oper2 === undefined ? {} : _this$parsedData$oper2,
_this$parsedData$oper3 = _this$parsedData$oper.mutation,
mutations = _this$parsedData$oper3 === undefined ? {} : _this$parsedData$oper3,
_this$parsedData$oper4 = _this$parsedData$oper.subscription,
subscriptions = _this$parsedData$oper4 === undefined ? {} : _this$parsedData$oper4,
_this$parsedData$oper5 = _this$parsedData$oper.fetch,
fetches = _this$parsedData$oper5 === undefined ? {} : _this$parsedData$oper5;
for (var _iterator2 = Object.values(subscriptions), _isArray2 = Array.isArray(_iterator2), _i2 = 0, _iterator2 = _isArray2 ? _iterator2 : _iterator2[Symbol.iterator]();;) {
var _ref2;
if (_isArray2) {
if (_i2 >= _iterator2.length) break;
_ref2 = _iterator2[_i2++];
} else {
_i2 = _iterator2.next();
if (_i2.done) break;
_ref2 = _i2.value;
}
var subscription = _ref2;
_this.subscribe(subscription)(_this.options);
registerPromise(_this.query(convertSubscriptionToQuery(subscription))(_this.options));
}
for (var _iterator3 = Object.values(queries), _isArray3 = Array.isArray(_iterator3), _i3 = 0, _iterator3 = _isArray3 ? _iterator3 : _iterator3[Symbol.iterator]();;) {
var _ref3;
if (_isArray3) {
if (_i3 >= _iterator3.length) break;
_ref3 = _iterator3[_i3++];
} else {
_i3 = _iterator3.next();
if (_i3.done) break;
_ref3 = _i3.value;
}
var query = _ref3;
registerPromise(_this.query(query)(_this.options));
}
for (var _iterator4 = Object.values(fetches), _isArray4 = Array.isArray(_iterator4), _i4 = 0, _iterator4 = _isArray4 ? _iterator4 : _iterator4[Symbol.iterator]();;) {
var _ref4;
if (_isArray4) {
if (_i4 >= _iterator4.length) break;
_ref4 = _iterator4[_i4++];
} else {
_i4 = _iterator4.next();
if (_i4.done) break;
_ref4 = _i4.value;
}
var fetch = _ref4;
registerPromise(_this.fetch(fetch)(_this.options));
}
registerPromise(Promise.resolve((_Promise$resolve = {}, _Promise$resolve[queriesKey] = _extends({}, mapObject(_this.query)(queries), mapObject(_this.fetch)(fetches)), _Promise$resolve[mutationsKey] = mapObject(_this.mutate)(mutations), _Promise$resolve)));
Promise.all(promiseRegistry).then(function (res) {
var _this$batchUpdateStat;
!cancel && _this.batchUpdateState(res, (_this$batchUpdateStat = {}, _this$batchUpdateStat[dataKey] = { loading: false }, _this$batchUpdateStat), true);
});
_this.cancelResolve = function () {
return cancel = true;
};
};
_this.query = function (document) {
return function () {
var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : _this.options;
return _this.client.query(document, options);
};
};
_this.mutate = function (document) {
return function () {
var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : _this.options;
return _this.client.mutate(document, options);
};
};
_this.fetch = function (document) {
return function () {
var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : _this.options;
return _this.client.fetch(document, options);
};
};
_this.subscribe = function (document) {
return function () {
var _ref5 = _asyncToGenerator( /*#__PURE__*/regeneratorRuntime.mark(function _callee() {
var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : _this.options;
var observable;
return regeneratorRuntime.wrap(function _callee$(_context) {
while (1) {
switch (_context.prev = _context.next) {
case 0:
_context.next = 2;
return _this.client.subscribe(document, options);
case 2:
observable = _context.sent;
registerSubscription(observable.subscribe(function (res) {
updateBatch.push(res);
process.nextTick(_this.batchUpdateState);
}));
case 4:
case 'end':
return _context.stop();
}
}
}, _callee, _this2);
}));
return function () {
return _ref5.apply(this, arguments);
};
}();
};
_this.client = context.client;
_this.options = computeOptions(props);
_this.parsedData = _this.parse(sources);
return _this;
}
Blips.prototype.componentWillMount = function componentWillMount() {
this.resolve();
};
Blips.prototype.componentWillReceiveProps = function componentWillReceiveProps(nextProps) {
var nextOptions = computeOptions(nextProps);
if (shallowEqual(this.options, nextOptions)) return;
this.options = _extends({}, nextOptions);
cancelSubscriptions();
clearSubscriptionRegistry();
clearPromiseRegistry();
this.cancelResolve();
this.resolve();
};
Blips.prototype.render = function render() {
var props = Object.entries(this.state).reduce(function (acc, _ref6) {
var _extends2;
var key = _ref6[0],
value = _ref6[1];
return _extends({}, acc, (_extends2 = {}, _extends2[key] = _extends({}, acc[key] || {}, value), _extends2));
}, this.props);
return React.createElement(BaseComponent, props);
};
return Blips;
}(Component);
Blips.displayName = 'Blips(' + (BaseComponent.displayName || BaseComponent.name || 'Component') + ')';
Blips.WrappedComponent = BaseComponent;
Blips.contextTypes = {
client: PropTypes.object.isRequired
};
return hoistNonReactStatics(Blips, BaseComponent, {});
};
}