forked from leebenson/reactql
-
Notifications
You must be signed in to change notification settings - Fork 0
/
apollo.ts
95 lines (86 loc) · 3.52 KB
/
apollo.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
// Apollo GraphQL client
// ----------------------------------------------------------------------------
// IMPORTS
/* NPM */
import { InMemoryCache, NormalizedCacheObject } from "apollo-cache-inmemory";
import { ApolloClient } from "apollo-client";
import { ApolloLink, split } from "apollo-link";
import { onError } from "apollo-link-error";
import { HttpLink } from "apollo-link-http";
import { WebSocketLink } from "apollo-link-ws";
import { getMainDefinition } from "apollo-utilities";
import { SubscriptionClient } from "subscriptions-transport-ws";
/* Local */
import { Store } from "@/data/store";
// ----------------------------------------------------------------------------
export function createClient(
// @ts-ignore - useful to pass in the store for `Authorization` headers, etc
store: Store
): ApolloClient<NormalizedCacheObject> {
// Create the cache first, which we'll share across Apollo tooling.
// This is an in-memory cache. Since we'll be calling `createClient` on
// universally, the cache will survive until the HTTP request is
// responded to (on the server) or for the whole of the user's visit (in
// the browser)
const cache = new InMemoryCache();
// Create a HTTP client (both server/client). It takes the GraphQL
// server from the `GRAPHQL` environment variable, which by default is
// set to an external playground at https://graphqlhub.com/graphql
const httpLink = new HttpLink({
credentials: "same-origin",
uri: GRAPHQL
});
// If we're in the browser, we'd have received initial state from the
// server. Restore it, so the client app can continue with the same data.
if (!SERVER) {
cache.restore((window as any).__APOLLO__);
}
// Return a new Apollo Client back, with the cache we've just created,
// and an array of 'links' (Apollo parlance for GraphQL middleware)
// to tell Apollo how to handle GraphQL requests
return new ApolloClient({
cache,
link: ApolloLink.from([
// General error handler, to log errors back to the console.
// Replace this in production with whatever makes sense in your
// environment. Remember you can use the global `SERVER` variable to
// determine whether you're running on the server, and record errors
// out to third-party services, etc
onError(({ graphQLErrors, networkError }) => {
if (graphQLErrors) {
graphQLErrors.map(({ message, locations, path }) =>
console.log(
`[GraphQL error]: Message: ${message}, Location: ${locations}, Path: ${path}`
)
);
}
if (networkError) {
console.log(`[Network error]: ${networkError}`);
}
}),
// Split on HTTP and WebSockets
WS_SUBSCRIPTIONS && !SERVER
? split(
({ query }) => {
const definition = getMainDefinition(query);
return (
definition.kind === "OperationDefinition" &&
definition.operation === "subscription"
);
},
// Use WebSockets for subscriptions
new WebSocketLink(
// Replace http(s) with `ws` for connecting via WebSockts
new SubscriptionClient(GRAPHQL.replace(/^https?/, "ws"), {
reconnect: true // <-- automatically redirect as needed
})
),
// ... fall-back to HTTP for everything else
httpLink
)
: httpLink // <-- just use HTTP on the server
]),
// On the server, enable SSR mode
ssrMode: SERVER
});
}