UNPKG

blips

Version:

State management for the GraphQL heads

304 lines (239 loc) 11.1 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"); }); }; } import { GraphQLError, execute, subscribe, validate } from 'graphql'; import { makeExecutableSchema } from 'graphql-tools/dist/schemaGenerator'; import { PubSub, withFilter } from 'graphql-subscriptions'; import { createApolloFetch } from 'apollo-fetch'; import Clerk from 'state-clerk'; import { when, isEmpty, isType, toObservable, extendContext, getDocument, promiseBatch, validateWithoutSchema } from './utils'; export var CLIENTGRAPHQL_DEPRECATION_WARNING = ' The "graphql" method is deprecated and will be removed in the 1.0 release. Use the "fetch" method instead.'; export var CREATESTORE_DEPRECATION_WARNING = 'The "createStore" method is deprecated and will be removed in the 1.0 release. Use "new BlipsClient(...)" instead'; export var FETCH_NOT_CONFIGURED_ERROR = 'You are trying to use "BlipsClient.fetch" without it being configured.'; export var NO_SUBSCRIPTION_ERROR = 'No subscription operation defined in query'; export var LONE_SUBSCRIPTION_OPERATION_ERROR = 'Only one subscription operation is allowed per query'; export var incorrectMiddlewareOrAfterwareType = function incorrectMiddlewareOrAfterwareType() { var name = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 'middleware/afterware'; return 'The fetch ' + name + ' must be a function or an array of functions'; }; var loggedWarnings = {}; export function BlipsClient() { var _ref = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}, typeDefs = _ref.typeDefs, resolvers = _ref.resolvers; var _this = this; var initialState = arguments[1]; var _ref2 = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {}, _ref2$variables = _ref2.variables, variables = _ref2$variables === undefined ? {} : _ref2$variables, _ref2$context = _ref2.context, context = _ref2$context === undefined ? {} : _ref2$context, _ref2$fetch = _ref2.fetch, fetch = _ref2$fetch === undefined ? {} : _ref2$fetch; var _pubsub = new PubSub(); var _state = void 0; var _schema = void 0; var _resolvers = void 0; var _clerk = void 0; var _context = void 0; var _variables = void 0; var _apolloFetch = void 0; function _validateDocument(sourceOrDocument) { var document = sourceOrDocument; try { document = getDocument(sourceOrDocument); } catch (syntaxError) { return { document: document, errors: [syntaxError] }; } var errors = _schema ? validate(_schema, document) : validateWithoutSchema(document); return _extends({ document: document }, !isEmpty(errors) && { errors: errors }); } function _runner(fn) { return function (document) { var _ref3 = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}, _ref3$variables = _ref3.variables, variables = _ref3$variables === undefined ? {} : _ref3$variables, _ref3$context = _ref3.context, context = _ref3$context === undefined ? {} : _ref3$context; var operationName = arguments[2]; var resolveFn = arguments[3]; return (0, fn)(_schema, document, {}, extendContext(_context, context), _extends({}, _variables, variables), operationName, resolveFn); }; } function _setUpMiddlewareOrAfterware(listOrFn, name) { if (!listOrFn) return; if (isType('function', listOrFn)) { _apolloFetch.use(listOrFn); } else if (isType('array', listOrFn)) { for (var _iterator = listOrFn, _isArray = Array.isArray(_iterator), _i = 0, _iterator = _isArray ? _iterator : _iterator[Symbol.iterator]();;) { var _ref4; if (_isArray) { if (_i >= _iterator.length) break; _ref4 = _iterator[_i++]; } else { _i = _iterator.next(); if (_i.done) break; _ref4 = _i.value; } var middleware = _ref4; _apolloFetch.use(middleware); } } else { throw new TypeError(incorrectMiddlewareOrAfterwareType(name)); } } var _executor = _runner(execute); var _subscriber = _runner(subscribe); function _execute(operationType) { return function (sourceOrDocument, options, operationName, resolveFn) { var _validateDocument2 = _validateDocument(sourceOrDocument), document = _validateDocument2.document, errors = _validateDocument2.errors; if (errors) return Promise.resolve({ errors: errors }); // If an operationName is provided, go ahead and execute that if (operationName) { return _executor(document, options, operationName, resolveFn); } var executableOperations = document.definitions.filter(function (definition) { return definition.operation === operationType; }); // If there's just one operation definition of the correct type execute it if (executableOperations.length === 1) { return _executor(document, options, operationName, resolveFn); } // otherwise: return promiseBatch(executableOperations.map(function (operation) { return _executor(document, options, operation.name.value, resolveFn); })); }; } ;(function constructor() { // store the initial state _state = _extends({}, initialState) || {}; // create and store the clerk instance _clerk = new Clerk(_state); // compute and store the resolvers _resolvers = when(typeof resolvers === 'function', resolvers({ pubsub: _pubsub, withFilter: withFilter }), resolvers); _schema = makeExecutableSchema({ typeDefs: typeDefs, resolvers: _resolvers }); // store the default variables _variables = variables; // compute and store the default context _context = extendContext({ // add store to the context. // it will not be replaced by any `store` props passed through the default options store: _extends({}, _clerk) }, context); // create apolloFetch if (fetch.uri) { _apolloFetch = createApolloFetch({ uri: fetch.uri }); // set up middleware and afterware _setUpMiddlewareOrAfterware(fetch.middleware, 'middleware'); _setUpMiddlewareOrAfterware(fetch.afterware, 'afterware'); } })(); return { /** * returns the state object * @return {Object} */ get state() { return _state; }, /** * returns the schema * @return {GraphQLSchema} */ get schema() { return _schema; }, query: _execute('query'), mutate: _execute('mutation'), subscribe: function () { var _ref5 = _asyncToGenerator( /*#__PURE__*/regeneratorRuntime.mark(function _callee(sourceOrDocument, options, operationName, resolveFn) { var _validateDocument3, document, errors, operations, iterator; return regeneratorRuntime.wrap(function _callee$(_context2) { while (1) { switch (_context2.prev = _context2.next) { case 0: _validateDocument3 = _validateDocument(sourceOrDocument), document = _validateDocument3.document, errors = _validateDocument3.errors; if (!errors) { _context2.next = 3; break; } return _context2.abrupt('return', Promise.resolve({ errors: errors })); case 3: operations = document.definitions.filter(function (definition) { return definition.operation === 'subscription'; }); if (!(operations.length < 1)) { _context2.next = 8; break; } return _context2.abrupt('return', Promise.resolve({ errors: [new GraphQLError(NO_SUBSCRIPTION_ERROR)] })); case 8: if (!(operations.length > 1)) { _context2.next = 10; break; } return _context2.abrupt('return', Promise.resolve({ errors: [new GraphQLError(LONE_SUBSCRIPTION_OPERATION_ERROR)] })); case 10: _context2.next = 12; return _subscriber(document, options, operationName, resolveFn); case 12: iterator = _context2.sent; return _context2.abrupt('return', toObservable(iterator)); case 14: case 'end': return _context2.stop(); } } }, _callee, _this); })); return function subscribe(_x5, _x6, _x7, _x8) { return _ref5.apply(this, arguments); }; }(), fetch: function fetch(query) { var _ref6 = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}, _ref6$variables = _ref6.variables, variables = _ref6$variables === undefined ? {} : _ref6$variables; var operationName = arguments[2]; if (!_apolloFetch || !isType('function', _apolloFetch)) { throw new Error(FETCH_NOT_CONFIGURED_ERROR); } return _apolloFetch({ query: query, variables: variables, operationName: operationName }); }, graphql: function graphql(query) { var _ref7 = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}, _ref7$variables = _ref7.variables, variables = _ref7$variables === undefined ? {} : _ref7$variables; var operationName = arguments[2]; if (!loggedWarnings[CLIENTGRAPHQL_DEPRECATION_WARNING]) { // eslint-disable-next-line console.warn(CLIENTGRAPHQL_DEPRECATION_WARNING); loggedWarnings[CLIENTGRAPHQL_DEPRECATION_WARNING] = true; } if (!_apolloFetch || !isType('function', _apolloFetch)) { throw new Error(FETCH_NOT_CONFIGURED_ERROR); } return _apolloFetch({ query: query, variables: variables, operationName: operationName }); } }; } export function createStore() { if (!loggedWarnings[CREATESTORE_DEPRECATION_WARNING]) { // eslint-disable-next-line console.warn(CREATESTORE_DEPRECATION_WARNING); loggedWarnings[CREATESTORE_DEPRECATION_WARNING] = true; } for (var _len = arguments.length, args = Array(_len), _key = 0; _key < _len; _key++) { args[_key] = arguments[_key]; } return new (Function.prototype.bind.apply(BlipsClient, [null].concat(args)))(); }