test: useSubscription
This commit is contained in:
@@ -20,6 +20,7 @@
|
||||
"@vue/apollo-util": "workspace:*",
|
||||
"graphql": "^16.7.1",
|
||||
"graphql-tag": "^2.12.6",
|
||||
"graphql-ws": "^5.15.0",
|
||||
"pinia": "^2.1.6",
|
||||
"test-server": "workspace:*",
|
||||
"vue": "^3.3.4",
|
||||
|
||||
@@ -1,6 +1,9 @@
|
||||
import { ApolloClient, InMemoryCache, createHttpLink } from '@apollo/client/core'
|
||||
import { ApolloClient, InMemoryCache, createHttpLink, split } from '@apollo/client/core'
|
||||
import { onError } from '@apollo/client/link/error'
|
||||
import { getMainDefinition } from '@apollo/client/utilities'
|
||||
import { GraphQLWsLink } from '@apollo/client/link/subscriptions'
|
||||
import { logErrorMessages } from '@vue/apollo-util'
|
||||
import { createClient } from 'graphql-ws'
|
||||
|
||||
const cache = new InMemoryCache()
|
||||
|
||||
@@ -10,6 +13,26 @@ const httpLink = createHttpLink({
|
||||
uri: 'http://localhost:4042/graphql',
|
||||
})
|
||||
|
||||
const wsLink = new GraphQLWsLink(createClient({
|
||||
url: 'ws://localhost:4042/graphql',
|
||||
}))
|
||||
|
||||
const splitLink = split(
|
||||
({ query }) => {
|
||||
const definition = getMainDefinition(query)
|
||||
if (definition.kind === 'OperationDefinition' &&
|
||||
definition.operation === 'subscription') {
|
||||
console.log(`Subscribing to ${definition.name?.value ?? 'anonymous'}`)
|
||||
}
|
||||
return (
|
||||
definition.kind === 'OperationDefinition' &&
|
||||
definition.operation === 'subscription'
|
||||
)
|
||||
},
|
||||
wsLink,
|
||||
httpLink,
|
||||
)
|
||||
|
||||
// Handle errors
|
||||
const errorLink = onError(error => {
|
||||
logErrorMessages(error)
|
||||
@@ -17,5 +40,5 @@ const errorLink = onError(error => {
|
||||
|
||||
export const apolloClient = new ApolloClient({
|
||||
cache,
|
||||
link: errorLink.concat(httpLink),
|
||||
link: errorLink.concat(splitLink),
|
||||
})
|
||||
|
||||
@@ -0,0 +1,37 @@
|
||||
<script lang="ts" setup>
|
||||
import { useSubscription } from '@vue/apollo-composable'
|
||||
import gql from 'graphql-tag'
|
||||
import { ref } from 'vue'
|
||||
|
||||
const messages = ref<Array<{ id: string, text: string }>>([])
|
||||
|
||||
const { onResult } = useSubscription(gql`subscription OnMessageAdded {
|
||||
messageAdded(channelId: "general") {
|
||||
id
|
||||
text
|
||||
}
|
||||
}`)
|
||||
|
||||
onResult((result) => {
|
||||
console.log(result.data?.messageAdded)
|
||||
if (result.data?.messageAdded) {
|
||||
messages.value.push(result.data.messageAdded)
|
||||
}
|
||||
})
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="space-y-2 p-2 border border-gray-200 rounded-xl">
|
||||
<div
|
||||
v-for="message in messages"
|
||||
:key="message.id"
|
||||
class="message px-4 py-2 bg-white rounded-lg"
|
||||
>
|
||||
{{ message.text }}
|
||||
</div>
|
||||
|
||||
<div v-if="!messages.length">
|
||||
No messages yet
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
@@ -0,0 +1,20 @@
|
||||
<script lang="ts" setup>
|
||||
import MessageForm from './MessageForm.vue'
|
||||
import Subscription from './Subscription.vue'
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="m-12 space-y-4">
|
||||
<h1 class="text-2xl">
|
||||
Subscription
|
||||
</h1>
|
||||
<MessageForm channel-id="general" />
|
||||
<div class="flex gap-4">
|
||||
<Subscription
|
||||
v-for="n in 3"
|
||||
:key="n"
|
||||
class="flex-1"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
@@ -79,5 +79,12 @@ export const router = createRouter({
|
||||
layout: 'blank',
|
||||
},
|
||||
},
|
||||
{
|
||||
path: '/subscriptions',
|
||||
component: () => import('./components/Subscriptions.vue'),
|
||||
meta: {
|
||||
layout: 'blank',
|
||||
},
|
||||
},
|
||||
],
|
||||
})
|
||||
|
||||
@@ -0,0 +1,16 @@
|
||||
describe('Subscription', () => {
|
||||
beforeEach(() => {
|
||||
cy.task('db:reset')
|
||||
cy.visit('/')
|
||||
})
|
||||
|
||||
it('receive messages in real time', () => {
|
||||
cy.visit('/subscriptions')
|
||||
cy.get('input').type('Meow{enter}')
|
||||
cy.get('.message').should('have.length', 3)
|
||||
cy.get('.message').should('contain', 'Meow')
|
||||
cy.get('input').type('Waf{enter}')
|
||||
cy.get('.message').should('have.length', 6)
|
||||
cy.get('.message').should('contain', 'Waf')
|
||||
})
|
||||
})
|
||||
Generated
+53
-38
@@ -177,7 +177,7 @@ importers:
|
||||
dependencies:
|
||||
'@apollo/client':
|
||||
specifier: ^3.7.16
|
||||
version: 3.7.16(graphql@16.7.1)
|
||||
version: 3.7.16(graphql-ws@5.15.0)(graphql@16.7.1)
|
||||
'@vue/apollo-composable':
|
||||
specifier: workspace:*
|
||||
version: link:../vue-apollo-composable
|
||||
@@ -190,6 +190,9 @@ importers:
|
||||
graphql-tag:
|
||||
specifier: ^2.12.6
|
||||
version: 2.12.6(graphql@16.7.1)
|
||||
graphql-ws:
|
||||
specifier: ^5.15.0
|
||||
version: 5.15.0(graphql@16.7.1)
|
||||
pinia:
|
||||
specifier: ^2.1.6
|
||||
version: 2.1.6(typescript@5.0.2)(vue@3.3.4)
|
||||
@@ -241,7 +244,7 @@ importers:
|
||||
dependencies:
|
||||
'@apollo/client':
|
||||
specifier: ^3.7.16
|
||||
version: 3.7.16(graphql@16.7.1)
|
||||
version: 3.7.16(graphql-ws@5.15.0)(graphql@16.7.1)
|
||||
'@vue/apollo-composable':
|
||||
specifier: workspace:*
|
||||
version: link:../vue-apollo-composable
|
||||
@@ -455,7 +458,7 @@ importers:
|
||||
devDependencies:
|
||||
'@apollo/client':
|
||||
specifier: ^3.7.16
|
||||
version: 3.7.16(graphql@16.7.1)
|
||||
version: 3.7.16(graphql-ws@5.15.0)(graphql@16.7.1)
|
||||
'@types/throttle-debounce':
|
||||
specifier: ^5.0.0
|
||||
version: 5.0.0
|
||||
@@ -763,6 +766,42 @@ packages:
|
||||
graphql: 16.6.0
|
||||
dev: false
|
||||
|
||||
/@apollo/client@3.7.16(graphql-ws@5.15.0)(graphql@16.7.1):
|
||||
resolution: {integrity: sha512-rdhoc7baSD7ZzcjavEpYN8gZJle1KhjEKj4SJeMgBpcnO4as7oXUVU4LtFpotzZdFlo57qaLrNzfvppSTsKvZQ==}
|
||||
peerDependencies:
|
||||
graphql: ^14.0.0 || ^15.0.0 || ^16.0.0
|
||||
graphql-ws: ^5.5.5
|
||||
react: ^16.8.0 || ^17.0.0 || ^18.0.0
|
||||
react-dom: ^16.8.0 || ^17.0.0 || ^18.0.0
|
||||
subscriptions-transport-ws: ^0.9
|
||||
peerDependenciesMeta:
|
||||
graphql:
|
||||
optional: true
|
||||
graphql-ws:
|
||||
optional: true
|
||||
react:
|
||||
optional: true
|
||||
react-dom:
|
||||
optional: true
|
||||
subscriptions-transport-ws:
|
||||
optional: true
|
||||
dependencies:
|
||||
'@graphql-typed-document-node/core': 3.1.1(graphql@16.7.1)
|
||||
'@wry/context': 0.7.0
|
||||
'@wry/equality': 0.5.3
|
||||
'@wry/trie': 0.4.3
|
||||
graphql: 16.7.1
|
||||
graphql-tag: 2.12.6(graphql@16.7.1)
|
||||
graphql-ws: 5.15.0(graphql@16.7.1)
|
||||
hoist-non-react-statics: 3.3.2
|
||||
optimism: 0.16.2
|
||||
prop-types: 15.8.1
|
||||
response-iterator: 0.2.6
|
||||
symbol-observable: 4.0.0
|
||||
ts-invariant: 0.10.3
|
||||
tslib: 2.5.0
|
||||
zen-observable-ts: 1.2.5
|
||||
|
||||
/@apollo/client@3.7.16(graphql@15.8.0)(subscriptions-transport-ws@0.9.19):
|
||||
resolution: {integrity: sha512-rdhoc7baSD7ZzcjavEpYN8gZJle1KhjEKj4SJeMgBpcnO4as7oXUVU4LtFpotzZdFlo57qaLrNzfvppSTsKvZQ==}
|
||||
peerDependencies:
|
||||
@@ -799,41 +838,6 @@ packages:
|
||||
tslib: 2.5.0
|
||||
zen-observable-ts: 1.2.5
|
||||
|
||||
/@apollo/client@3.7.16(graphql@16.7.1):
|
||||
resolution: {integrity: sha512-rdhoc7baSD7ZzcjavEpYN8gZJle1KhjEKj4SJeMgBpcnO4as7oXUVU4LtFpotzZdFlo57qaLrNzfvppSTsKvZQ==}
|
||||
peerDependencies:
|
||||
graphql: ^14.0.0 || ^15.0.0 || ^16.0.0
|
||||
graphql-ws: ^5.5.5
|
||||
react: ^16.8.0 || ^17.0.0 || ^18.0.0
|
||||
react-dom: ^16.8.0 || ^17.0.0 || ^18.0.0
|
||||
subscriptions-transport-ws: ^0.9
|
||||
peerDependenciesMeta:
|
||||
graphql:
|
||||
optional: true
|
||||
graphql-ws:
|
||||
optional: true
|
||||
react:
|
||||
optional: true
|
||||
react-dom:
|
||||
optional: true
|
||||
subscriptions-transport-ws:
|
||||
optional: true
|
||||
dependencies:
|
||||
'@graphql-typed-document-node/core': 3.1.1(graphql@16.7.1)
|
||||
'@wry/context': 0.7.0
|
||||
'@wry/equality': 0.5.3
|
||||
'@wry/trie': 0.4.3
|
||||
graphql: 16.7.1
|
||||
graphql-tag: 2.12.6(graphql@16.7.1)
|
||||
hoist-non-react-statics: 3.3.2
|
||||
optimism: 0.16.2
|
||||
prop-types: 15.8.1
|
||||
response-iterator: 0.2.6
|
||||
symbol-observable: 4.0.0
|
||||
ts-invariant: 0.10.3
|
||||
tslib: 2.5.0
|
||||
zen-observable-ts: 1.2.5
|
||||
|
||||
/@apollo/client@3.7.9(graphql@15.8.0):
|
||||
resolution: {integrity: sha512-YnJvrJOVWrp4y/zdNvUaM8q4GuSHCEIecsRDTJhK/veT33P/B7lfqGJ24NeLdKMj8tDEuXYF7V0t+th4+rgC+Q==}
|
||||
peerDependencies:
|
||||
@@ -10414,6 +10418,17 @@ packages:
|
||||
graphql: 16.6.0
|
||||
dev: false
|
||||
|
||||
/graphql-ws@5.15.0(graphql@16.7.1):
|
||||
resolution: {integrity: sha512-xWGAtm3fig9TIhSaNsg0FaDZ8Pyn/3re3RFlP4rhQcmjRDIPpk1EhRuNB+YSJtLzttyuToaDiNhwT1OMoGnJnw==}
|
||||
engines: {node: '>=10'}
|
||||
peerDependencies:
|
||||
graphql: '>=0.11 <=16'
|
||||
peerDependenciesMeta:
|
||||
graphql:
|
||||
optional: true
|
||||
dependencies:
|
||||
graphql: 16.7.1
|
||||
|
||||
/graphql@15.8.0:
|
||||
resolution: {integrity: sha512-5gghUc24tP9HRznNpV2+FIoq3xKkj5dTQqf4v0CpdPbFVwFkWoxOM+o+2OC9ZSvjEMTjfmG9QT+gcvggTwW1zw==}
|
||||
engines: {node: '>= 10.x'}
|
||||
|
||||
Reference in New Issue
Block a user