Skip to content

Commit 66f78ea

Browse files
author
Carlos Rufo Jimenez
committed
8.4-end-subscriptions-v2.1
1 parent 295218c commit 66f78ea

File tree

4 files changed

+204
-6
lines changed

4 files changed

+204
-6
lines changed

package.json

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,14 +4,16 @@
44
"private": true,
55
"dependencies": {
66
"apollo-client-preset": "^1.0.8",
7+
"apollo-link-ws": "^1.0.7",
78
"graphql": "^0.13.1",
89
"graphql-tag": "^2.8.0",
910
"react": "^16.2.0",
1011
"react-apollo": "^2.1.0-beta.3",
1112
"react-dom": "^16.2.0",
1213
"react-router": "^4.2.0",
1314
"react-router-dom": "^4.2.2",
14-
"react-scripts": "1.1.1"
15+
"react-scripts": "1.1.1",
16+
"subscriptions-transport-ws": "^0.9.7"
1517
},
1618
"scripts": {
1719
"start": "react-scripts start",

src/components/LinkList.js

Lines changed: 120 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,19 +28,109 @@ export const FEED_QUERY = gql`
2828
}
2929
`
3030

31+
const NEW_LINKS_SUBSCRIPTION = gql`
32+
subscription {
33+
newLink {
34+
node {
35+
id
36+
url
37+
description
38+
createdAt
39+
postedBy {
40+
id
41+
name
42+
}
43+
votes {
44+
id
45+
user {
46+
id
47+
}
48+
}
49+
}
50+
}
51+
}
52+
`
53+
54+
const NEW_VOTES_SUBSCRIPTION = gql`
55+
subscription {
56+
newVote {
57+
node {
58+
id
59+
link {
60+
id
61+
url
62+
description
63+
createdAt
64+
postedBy {
65+
id
66+
name
67+
}
68+
votes {
69+
id
70+
user {
71+
id
72+
}
73+
}
74+
}
75+
user {
76+
id
77+
}
78+
}
79+
}
80+
}
81+
`
82+
83+
class NewLinksSubscription extends Component {
84+
componentDidMount() {
85+
this.props.subscribeToNewLinks()
86+
}
87+
render() {
88+
return null
89+
}
90+
}
91+
92+
class NewVotesSubscription extends Component {
93+
componentDidMount() {
94+
this.props.subscribeToNewVotes()
95+
}
96+
render() {
97+
return null
98+
}
99+
}
100+
31101
class LinkList extends Component {
102+
// Test to see if item is already in the store
103+
idAlreadyExists = (previous, subscriptionData) => {
104+
const { data: { newLink: { node: { id } } } } = subscriptionData
105+
return (
106+
previous.feed.links.filter(item => {
107+
return item.id === id
108+
}).length > 0
109+
)
110+
}
111+
32112
render() {
33113
return (
34114
<Query query={FEED_QUERY}>
35115
{result => {
36116
if (result.loading) return <div>Loading</div>
37117
if (result.error) return <div>Error</div>
38118

39-
const { data } = result
119+
const { data, subscribeToMore } = result
40120
const linksToRender = data.feed.links
41121

42122
return (
43123
<div>
124+
<NewLinksSubscription
125+
subscribeToNewLinks={() =>
126+
this._subscribeToNewLinks(subscribeToMore)
127+
}
128+
/>
129+
<NewVotesSubscription
130+
subscribeToNewVotes={() =>
131+
this._subscribeToNewVotes(subscribeToMore)
132+
}
133+
/>
44134
{linksToRender.map((link, index) => (
45135
<Link
46136
key={link.id}
@@ -67,6 +157,35 @@ class LinkList extends Component {
67157
// 3
68158
store.writeQuery({ query: FEED_QUERY, data })
69159
}
160+
161+
_subscribeToNewLinks = subscribeToMore => {
162+
subscribeToMore({
163+
document: NEW_LINKS_SUBSCRIPTION,
164+
updateQuery: (previous, { subscriptionData }) => {
165+
if (!subscriptionData.data) return previous
166+
if (this.idAlreadyExists(previous, subscriptionData)) {
167+
return previous
168+
}
169+
170+
const newAllLinks = [
171+
subscriptionData.data.newLink.node,
172+
...previous.feed.links,
173+
]
174+
const result = {
175+
...previous,
176+
feed: {
177+
links: newAllLinks,
178+
},
179+
}
180+
return result
181+
},
182+
})
183+
}
184+
_subscribeToNewVotes = subscribeToMore => {
185+
subscribeToMore({
186+
document: NEW_VOTES_SUBSCRIPTION,
187+
})
188+
}
70189
}
71190

72191
export default LinkList

src/index.js

Lines changed: 24 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,9 @@ import { HttpLink } from 'apollo-link-http'
1010
import { InMemoryCache } from 'apollo-cache-inmemory'
1111
import { BrowserRouter } from 'react-router-dom'
1212
import { AUTH_TOKEN } from './constants'
13-
import { ApolloLink } from 'apollo-client-preset'
13+
import { ApolloLink, split } from 'apollo-client-preset'
14+
import { WebSocketLink } from 'apollo-link-ws'
15+
import { getMainDefinition } from 'apollo-utilities'
1416

1517
// 2
1618
const httpLink = new HttpLink({ uri: 'http://localhost:4000' })
@@ -27,9 +29,29 @@ const middlewareAuthLink = new ApolloLink((operation, forward) => {
2729
})
2830

2931
const httpLinkWithAuthToken = middlewareAuthLink.concat(httpLink)
32+
33+
const wsLink = new WebSocketLink({
34+
uri: `ws://localhost:4000`,
35+
options: {
36+
reconnect: true,
37+
connectionParams: {
38+
authToken: localStorage.getItem(AUTH_TOKEN),
39+
},
40+
},
41+
})
42+
43+
const link = split(
44+
({ query }) => {
45+
const { kind, operation } = getMainDefinition(query)
46+
return kind === 'OperationDefinition' && operation === 'subscription'
47+
},
48+
wsLink,
49+
httpLinkWithAuthToken
50+
)
51+
3052
// 3
3153
const client = new ApolloClient({
32-
link: httpLinkWithAuthToken,
54+
link,
3355
cache: new InMemoryCache(),
3456
})
3557

yarn.lock

Lines changed: 57 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -218,6 +218,12 @@ apollo-link-http@^1.3.1:
218218
apollo-link "^1.2.1"
219219
apollo-link-http-common "^0.2.2"
220220

221+
apollo-link-ws@^1.0.7:
222+
version "1.0.7"
223+
resolved "https://registry.yarnpkg.com/apollo-link-ws/-/apollo-link-ws-1.0.7.tgz#6cc3903cbfbbefe213ea9fc8121f5fed3cef1823"
224+
dependencies:
225+
apollo-link "^1.2.1"
226+
221227
apollo-link@^1.0.0, apollo-link@^1.0.6, apollo-link@^1.2.1:
222228
version "1.2.1"
223229
resolved "https://registry.yarnpkg.com/apollo-link/-/apollo-link-1.2.1.tgz#c120b16059f9bd93401b9f72b94d2f80f3f305d2"
@@ -377,6 +383,10 @@ async-each@^1.0.0:
377383
version "1.0.1"
378384
resolved "https://registry.yarnpkg.com/async-each/-/async-each-1.0.1.tgz#19d386a1d9edc6e7c1c85d388aedbcc56d33602d"
379385

386+
async-limiter@~1.0.0:
387+
version "1.0.0"
388+
resolved "https://registry.yarnpkg.com/async-limiter/-/async-limiter-1.0.0.tgz#78faed8c3d074ab81f22b4e985d79e8738f720f8"
389+
380390
async@^1.4.0, async@^1.5.2:
381391
version "1.5.2"
382392
resolved "https://registry.yarnpkg.com/async/-/async-1.5.2.tgz#ec6a61ae56480c0c3cb241c95618e20892f9672a"
@@ -1070,6 +1080,10 @@ babylon@^6.17.0, babylon@^6.18.0:
10701080
version "6.18.0"
10711081
resolved "https://registry.yarnpkg.com/babylon/-/babylon-6.18.0.tgz#af2f3b88fa6f5c1e4c634d1a0f8eac4f55b395e3"
10721082

1083+
backo2@^1.0.2:
1084+
version "1.0.2"
1085+
resolved "https://registry.yarnpkg.com/backo2/-/backo2-1.0.2.tgz#31ab1ac8b129363463e35b3ebb69f4dfcfba7947"
1086+
10731087
balanced-match@^0.4.2:
10741088
version "0.4.2"
10751089
resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-0.4.2.tgz#cb3f3e3c732dc0f01ee70b403f302e61d7709838"
@@ -2541,6 +2555,10 @@ [email protected]:
25412555
version "1.2.0"
25422556
resolved "https://registry.yarnpkg.com/eventemitter3/-/eventemitter3-1.2.0.tgz#1c86991d816ad1e504750e73874224ecf3bec508"
25432557

2558+
eventemitter3@^2.0.3:
2559+
version "2.0.3"
2560+
resolved "https://registry.yarnpkg.com/eventemitter3/-/eventemitter3-2.0.3.tgz#b5e1079b59fb5e1ba2771c0a993be060a58c99ba"
2561+
25442562
events@^1.0.0:
25452563
version "1.1.1"
25462564
resolved "https://registry.yarnpkg.com/events/-/events-1.1.1.tgz#9ebdb7635ad099c70dcc4c2a1f5004288e8bd924"
@@ -3898,7 +3916,7 @@ istanbul-reports@^1.1.4:
38983916
dependencies:
38993917
handlebars "^4.0.3"
39003918

3901-
iterall@^1.2.0:
3919+
iterall@^1.2.0, iterall@^1.2.1:
39023920
version "1.2.2"
39033921
resolved "https://registry.yarnpkg.com/iterall/-/iterall-1.2.2.tgz#92d70deb8028e0c39ff3164fdbf4d8b088130cd7"
39043922

@@ -4357,6 +4375,10 @@ lodash._reinterpolate@~3.0.0:
43574375
version "3.0.0"
43584376
resolved "https://registry.yarnpkg.com/lodash._reinterpolate/-/lodash._reinterpolate-3.0.0.tgz#0ccf2d89166af03b3663c796538b75ac6e114d9d"
43594377

4378+
lodash.assign@^4.2.0:
4379+
version "4.2.0"
4380+
resolved "https://registry.yarnpkg.com/lodash.assign/-/lodash.assign-4.2.0.tgz#0d99f3ccd7a6d261d19bdaeb9245005d285808e7"
4381+
43604382
lodash.camelcase@^4.3.0:
43614383
version "4.3.0"
43624384
resolved "https://registry.yarnpkg.com/lodash.camelcase/-/lodash.camelcase-4.3.0.tgz#b28aa6288a2b9fc651035c7711f65ab6190331a6"
@@ -4369,6 +4391,14 @@ lodash.defaults@^4.2.0:
43694391
version "4.2.0"
43704392
resolved "https://registry.yarnpkg.com/lodash.defaults/-/lodash.defaults-4.2.0.tgz#d09178716ffea4dde9e5fb7b37f6f0802274580c"
43714393

4394+
lodash.isobject@^3.0.2:
4395+
version "3.0.2"
4396+
resolved "https://registry.yarnpkg.com/lodash.isobject/-/lodash.isobject-3.0.2.tgz#3c8fb8d5b5bf4bf90ae06e14f2a530a4ed935e1d"
4397+
4398+
lodash.isstring@^4.0.1:
4399+
version "4.0.1"
4400+
resolved "https://registry.yarnpkg.com/lodash.isstring/-/lodash.isstring-4.0.1.tgz#d527dfb5456eca7cc9bb95d5daeaf88ba54a5451"
4401+
43724402
lodash.memoize@^4.1.2:
43734403
version "4.1.2"
43744404
resolved "https://registry.yarnpkg.com/lodash.memoize/-/lodash.memoize-4.1.2.tgz#bcc6c49a42a2840ed997f323eada5ecd182e0bfe"
@@ -6567,6 +6597,19 @@ [email protected]:
65676597
loader-utils "^1.0.2"
65686598
schema-utils "^0.3.0"
65696599

6600+
subscriptions-transport-ws@^0.9.7:
6601+
version "0.9.7"
6602+
resolved "https://registry.yarnpkg.com/subscriptions-transport-ws/-/subscriptions-transport-ws-0.9.7.tgz#9be456d6e188c96a53c91f570850e59bee5840ac"
6603+
dependencies:
6604+
backo2 "^1.0.2"
6605+
eventemitter3 "^2.0.3"
6606+
iterall "^1.2.1"
6607+
lodash.assign "^4.2.0"
6608+
lodash.isobject "^3.0.2"
6609+
lodash.isstring "^4.0.1"
6610+
symbol-observable "^1.0.4"
6611+
ws "^3.0.0"
6612+
65706613
supports-color@^2.0.0:
65716614
version "2.0.0"
65726615
resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-2.0.0.tgz#535d045ce6b6363fa40117084629995e9df324c7"
@@ -6631,7 +6674,7 @@ sw-toolbox@^3.4.0:
66316674
path-to-regexp "^1.0.1"
66326675
serviceworker-cache-polyfill "^4.0.0"
66336676

6634-
symbol-observable@^1.0.2:
6677+
symbol-observable@^1.0.2, symbol-observable@^1.0.4:
66356678
version "1.2.0"
66366679
resolved "https://registry.yarnpkg.com/symbol-observable/-/symbol-observable-1.2.0.tgz#c22688aed4eab3cdc2dfeacbb561660560a00804"
66376680

@@ -6850,6 +6893,10 @@ uid-number@^0.0.6:
68506893
version "0.0.6"
68516894
resolved "https://registry.yarnpkg.com/uid-number/-/uid-number-0.0.6.tgz#0ea10e8035e8eb5b8e4449f06da1c730663baa81"
68526895

6896+
ultron@~1.1.0:
6897+
version "1.1.1"
6898+
resolved "https://registry.yarnpkg.com/ultron/-/ultron-1.1.1.tgz#9fe1536a10a664a65266a1e3ccf85fd36302bc9c"
6899+
68536900
union-value@^1.0.0:
68546901
version "1.0.0"
68556902
resolved "https://registry.yarnpkg.com/union-value/-/union-value-1.0.0.tgz#5c71c34cb5bad5dcebe3ea0cd08207ba5aa1aea4"
@@ -7261,6 +7308,14 @@ write@^0.2.1:
72617308
dependencies:
72627309
mkdirp "^0.5.1"
72637310

7311+
ws@^3.0.0:
7312+
version "3.3.3"
7313+
resolved "https://registry.yarnpkg.com/ws/-/ws-3.3.3.tgz#f1cf84fe2d5e901ebce94efaece785f187a228f2"
7314+
dependencies:
7315+
async-limiter "~1.0.0"
7316+
safe-buffer "~5.1.0"
7317+
ultron "~1.1.0"
7318+
72647319
xdg-basedir@^3.0.0:
72657320
version "3.0.0"
72667321
resolved "https://registry.yarnpkg.com/xdg-basedir/-/xdg-basedir-3.0.0.tgz#496b2cc109eca8dbacfe2dc72b603c17c5870ad4"

0 commit comments

Comments
 (0)