UNPKG

react-blips

Version:
294 lines (223 loc) 11.7 kB
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, {}); }; }