diff --git a/packages/test-e2e-composable-vue3/package.json b/packages/test-e2e-composable-vue3/package.json index 8b27e90..812fbda 100644 --- a/packages/test-e2e-composable-vue3/package.json +++ b/packages/test-e2e-composable-vue3/package.json @@ -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", diff --git a/packages/test-e2e-composable-vue3/src/apollo.ts b/packages/test-e2e-composable-vue3/src/apollo.ts index c21680b..f867600 100644 --- a/packages/test-e2e-composable-vue3/src/apollo.ts +++ b/packages/test-e2e-composable-vue3/src/apollo.ts @@ -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), }) diff --git a/packages/test-e2e-composable-vue3/src/components/Subscription.vue b/packages/test-e2e-composable-vue3/src/components/Subscription.vue new file mode 100644 index 0000000..652f267 --- /dev/null +++ b/packages/test-e2e-composable-vue3/src/components/Subscription.vue @@ -0,0 +1,37 @@ + + + diff --git a/packages/test-e2e-composable-vue3/src/components/Subscriptions.vue b/packages/test-e2e-composable-vue3/src/components/Subscriptions.vue new file mode 100644 index 0000000..6a39c50 --- /dev/null +++ b/packages/test-e2e-composable-vue3/src/components/Subscriptions.vue @@ -0,0 +1,20 @@ + + + diff --git a/packages/test-e2e-composable-vue3/src/router.ts b/packages/test-e2e-composable-vue3/src/router.ts index 03615be..6cc4027 100644 --- a/packages/test-e2e-composable-vue3/src/router.ts +++ b/packages/test-e2e-composable-vue3/src/router.ts @@ -79,5 +79,12 @@ export const router = createRouter({ layout: 'blank', }, }, + { + path: '/subscriptions', + component: () => import('./components/Subscriptions.vue'), + meta: { + layout: 'blank', + }, + }, ], }) diff --git a/packages/test-e2e-composable-vue3/tests/e2e/specs/subscription.cy.ts b/packages/test-e2e-composable-vue3/tests/e2e/specs/subscription.cy.ts new file mode 100644 index 0000000..f1026e0 --- /dev/null +++ b/packages/test-e2e-composable-vue3/tests/e2e/specs/subscription.cy.ts @@ -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') + }) +}) diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 9312c32..4f1374f 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -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'}