UNPKG

overmind-graphql

Version:
165 lines 6.57 kB
import * as withAbsintheSocket from '@absinthe/socket'; import { GraphQLClient } from 'graphql-request'; import { print } from 'graphql/language/printer'; import { Socket as PhoenixSocket } from 'phoenix'; import gqlTag from 'graphql-tag'; function createError(message) { throw new Error(`OVERMIND-GRAPHQL: ${message}`); } export const gql = (literals, ...placeholders) => gqlTag(literals, ...placeholders); const _clients = {}; const _subscriptions = {}; export const graphql = (queries) => { let _http; let _ws; function getClient() { if (_http) { const headers = // eslint-disable-next-line typeof _http.headers === 'function' ? _http.headers() : _http.options && _http.options.headers ? _http.options.headers : {}; if (_clients[_http.endpoint]) { _clients[_http.endpoint].setHeaders(headers); } else { _clients[_http.endpoint] = new GraphQLClient(_http.endpoint, { ..._http.options, headers, }); } return _clients[_http.endpoint]; } return null; } let wsClient = null; function getWsClient() { if (_ws && !wsClient) { const socket = typeof _ws === 'function' ? _ws() : new PhoenixSocket(_ws.endpoint, { params: _ws.params ? _ws.params() : undefined, }); if (!socket) { throw createError('You are trying to create a Socket for subscriptions, but there is no socket or socket information provided'); } wsClient = withAbsintheSocket.create(socket); return wsClient; } return wsClient; } const evaluatedQueries = { rawQueries: Object.keys(queries.rawQueries || {}).reduce((aggr, key) => { aggr[key] = (variables) => { const query = queries.rawQueries[key]; const client = getClient(); if (client) { return client.rawRequest(print(query), variables); } throw createError('You are running a query, though there is no HTTP endpoint configured'); }; return aggr; }, {}), queries: Object.keys(queries.queries || {}).reduce((aggr, key) => { aggr[key] = (variables) => { const query = queries.queries[key]; const client = getClient(); if (client) { return client.request(print(query), variables); } throw createError('You are running a query, though there is no HTTP endpoint configured'); }; return aggr; }, {}), rawMutations: Object.keys(queries.rawMutations || {}).reduce((aggr, key) => { aggr[key] = (variables) => { const query = queries.rawMutations[key]; const client = getClient(); if (client) { return client.rawRequest(print(query), variables); } throw createError('You are running a query, though there is no HTTP endpoint configured'); }; return aggr; }, {}), mutations: Object.keys(queries.mutations || {}).reduce((aggr, key) => { aggr[key] = (variables) => { const query = queries.mutations[key]; const client = getClient(); if (client) { return client.request(print(query), variables); } throw createError('You are running a query, though there is no HTTP endpoint configured'); }; return aggr; }, {}), subscriptions: Object.keys(queries.subscriptions || {}).reduce((aggr, key) => { const query = queries.subscriptions[key]; const queryString = print(query); if (!_subscriptions[queryString]) { _subscriptions[queryString] = []; } function subscription(arg1, arg2) { const client = getWsClient(); if (client) { const variables = arg2 ? arg1 : {}; const action = arg2 || arg1; const notifier = withAbsintheSocket.send(client, { operation: queryString, variables, }); const observer = withAbsintheSocket.observe(client, notifier, { onResult: ({ data }) => { action(data); }, }); _subscriptions[queryString].push({ variables, dispose: () => withAbsintheSocket.unobserve(client, notifier, observer), }); } else { throw createError('There is no ws client available for this query'); } } subscription.dispose = () => { _subscriptions[queryString].forEach((sub) => { try { sub.dispose(); } catch (e) { // Ignore, it probably throws an error because we weren't subscribed in the first place } }); _subscriptions[queryString].length = 0; }; subscription.disposeWhere = (cb) => { _subscriptions[queryString] = _subscriptions[queryString].reduce((subAggr, sub) => { if (cb(sub.variables)) { try { sub.dispose(); } catch (e) { // Ignore, it probably throws an error because we weren't subscribed in the first place } return subAggr; } return subAggr.concat(sub); }, []); }; aggr[key] = subscription; return aggr; }, {}), }; return { initialize(http, ws) { _http = http; if (ws) { _ws = ws; } }, ...evaluatedQueries, }; }; //# sourceMappingURL=index.js.map