Files
talk/client/coral-framework/services/client.js
T
2018-01-11 20:00:34 -07:00

109 lines
3.0 KiB
JavaScript

import ApolloClient, {
IntrospectionFragmentMatcher,
createNetworkInterface,
} from 'apollo-client';
import {
SubscriptionClient,
addGraphQLSubscriptions,
} from 'subscriptions-transport-ws';
import MessageTypes from 'subscriptions-transport-ws/dist/message-types';
// Redux middleware to report any errors to the console.
export const apolloErrorReporter = () => next => action => {
if (action.type === 'APOLLO_QUERY_ERROR') {
console.error(action.error);
}
return next(action);
};
function resolveToken(token) {
return typeof token === 'function' ? token() : token;
}
/**
* createClient setups and returns an Apollo GraphQL Client
* @param {Object} [options] configuration
* @param {string|function} [options.token] auth token
* @param {string} [options.uri] uri of the graphql server
* @param {string} [options.liveUri] uri of the graphql subscription server
* @param {Object} [options.introspectionData] introspection query result data
* @return {Object} apollo client
*/
export function createClient(options = {}) {
const { token, uri, liveUri, introspectionData } = options;
const wsClient = new SubscriptionClient(liveUri, {
reconnect: true,
lazy: true,
connectionParams: {
get token() {
return resolveToken(token);
},
},
});
const networkInterface = createNetworkInterface({
uri,
opts: {
credentials: 'same-origin',
},
});
networkInterface.use([
{
applyMiddleware(req, next) {
if (!req.options.headers) {
req.options.headers = {}; // Create the header object if needed.
}
let authToken = resolveToken(token);
if (authToken) {
req.options.headers['authorization'] = `Bearer ${authToken}`;
}
next();
},
},
]);
const networkInterfaceWithSubscriptions = addGraphQLSubscriptions(
networkInterface,
wsClient
);
const client = new ApolloClient({
connectToDevTools: true,
addTypename: true,
fragmentMatcher: new IntrospectionFragmentMatcher({
introspectionQueryResultData: introspectionData,
}),
dataIdFromObject: result => {
if (result.id && result.__typename) {
// eslint-disable-line no-underscore-dangle
return `${result.__typename}_${result.id}`; // eslint-disable-line no-underscore-dangle
}
return null;
},
networkInterface: networkInterfaceWithSubscriptions,
});
client.resetWebsocket = () => {
// Close socket connection which will also unregister subscriptions on the server-side.
wsClient.close();
// Reconnect to the server.
wsClient.connect();
// Reregister all subscriptions (uses non public api).
// See: https://github.com/apollographql/subscriptions-transport-ws/issues/171
Object.keys(wsClient.operations).forEach(id => {
wsClient.sendMessage(
id,
MessageTypes.GQL_START,
wsClient.operations[id].options
);
});
};
return client;
}