overmind-graphql
Version:
Functional actions
165 lines • 6.57 kB
JavaScript
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