|
1 | 1 | import omit from 'lodash.omit'; |
| 2 | +import { print } from 'graphql-tag/printer'; |
2 | 3 |
|
3 | 4 | let apolloClient = null; |
4 | 5 |
|
5 | 6 | let defineReactive = function() {}; |
6 | 7 |
|
| 8 | +// quick way to add the subscribe and unsubscribe functions to the network interface |
| 9 | +function addGraphQLSubscriptions(networkInterface, wsClient) { |
| 10 | + return Object.assign(networkInterface, { |
| 11 | + subscribe(request, handler) { |
| 12 | + return wsClient.subscribe({ |
| 13 | + query: print(request.query), |
| 14 | + variables: request.variables, |
| 15 | + }, handler); |
| 16 | + }, |
| 17 | + unsubscribe(id) { |
| 18 | + wsClient.unsubscribe(id); |
| 19 | + }, |
| 20 | + }); |
| 21 | +} |
| 22 | + |
7 | 23 | class DollarApollo { |
8 | 24 | constructor(vm) { |
9 | 25 | this.vm = vm; |
@@ -34,6 +50,18 @@ class DollarApollo { |
34 | 50 | return this.client.mutate; |
35 | 51 | } |
36 | 52 |
|
| 53 | + subscribe(options) { |
| 54 | + const vm = this.vm; |
| 55 | + const observable = this.client.subscribe(options); |
| 56 | + const _subscribe = observable.subscribe.bind(observable); |
| 57 | + observable.subscribe = (function(options) { |
| 58 | + let sub = _subscribe(options); |
| 59 | + vm._apolloSubscriptions.push(sub); |
| 60 | + return sub; |
| 61 | + }).bind(observable); |
| 62 | + return observable; |
| 63 | + } |
| 64 | + |
37 | 65 | option(key, options) { |
38 | 66 | const vm = this.vm; |
39 | 67 | const $apollo = this; |
@@ -162,6 +190,73 @@ class DollarApollo { |
162 | 190 | } |
163 | 191 | } |
164 | 192 | } |
| 193 | + |
| 194 | + subscribeOption(key, options) { |
| 195 | + const vm = this.vm; |
| 196 | + const $apollo = this; |
| 197 | + |
| 198 | + let observer, sub; |
| 199 | + |
| 200 | + function generateApolloOptions(variables) { |
| 201 | + const apolloOptions = omit(options, [ |
| 202 | + 'variables', |
| 203 | + 'result', |
| 204 | + 'error', |
| 205 | + ]); |
| 206 | + apolloOptions.variables = variables; |
| 207 | + return apolloOptions; |
| 208 | + } |
| 209 | + |
| 210 | + function q(variables) { |
| 211 | + console.log(variables); |
| 212 | + |
| 213 | + if (sub) { |
| 214 | + sub.unsubscribe(); |
| 215 | + } |
| 216 | + |
| 217 | + // Create observer |
| 218 | + observer = $apollo.subscribe(generateApolloOptions(variables)); |
| 219 | + |
| 220 | + // Create subscription |
| 221 | + sub = observer.subscribe({ |
| 222 | + next: nextResult, |
| 223 | + error: catchError |
| 224 | + }); |
| 225 | + } |
| 226 | + |
| 227 | + if (typeof options.variables === 'function') { |
| 228 | + vm.$watch(options.variables.bind(vm), q, { |
| 229 | + immediate: true |
| 230 | + }); |
| 231 | + } else { |
| 232 | + q(options.variables); |
| 233 | + } |
| 234 | + |
| 235 | + function nextResult(data) { |
| 236 | + if (typeof options.result === 'function') { |
| 237 | + options.result.call(vm, data); |
| 238 | + } |
| 239 | + } |
| 240 | + |
| 241 | + function catchError(error) { |
| 242 | + loadingDone(); |
| 243 | + |
| 244 | + if (error.graphQLErrors && error.graphQLErrors.length !== 0) { |
| 245 | + console.error(`GraphQL execution errors for subscription ${query}`); |
| 246 | + for (let e of error.graphQLErrors) { |
| 247 | + console.error(e); |
| 248 | + } |
| 249 | + } else if (error.networkError) { |
| 250 | + console.error(`Error sending the subscription ${query}`, error.networkError); |
| 251 | + } else { |
| 252 | + console.error(error); |
| 253 | + } |
| 254 | + |
| 255 | + if (typeof options.error === 'function') { |
| 256 | + options.error(error); |
| 257 | + } |
| 258 | + } |
| 259 | + } |
165 | 260 | } |
166 | 261 |
|
167 | 262 | const prepare = function prepare() { |
@@ -199,9 +294,18 @@ const launch = function launch() { |
199 | 294 | this.$apollo.option(key, this._apolloQueries[key]); |
200 | 295 | } |
201 | 296 | } |
| 297 | + |
| 298 | + let apollo = this.$options.apollo; |
| 299 | + if(apollo && apollo.subscribe) { |
| 300 | + for (let key in apollo.subscribe) { |
| 301 | + this.$apollo.subscribeOption(key, apollo.subscribe[key]); |
| 302 | + } |
| 303 | + } |
202 | 304 | } |
203 | 305 |
|
204 | 306 | module.exports = { |
| 307 | + addGraphQLSubscriptions, |
| 308 | + |
205 | 309 | install(Vue, options) { |
206 | 310 |
|
207 | 311 | defineReactive = Vue.util.defineReactive; |
|
0 commit comments