diff --git a/packages/docs/src/guide-composable/setup.md b/packages/docs/src/guide-composable/setup.md index 87bc376..11bd892 100644 --- a/packages/docs/src/guide-composable/setup.md +++ b/packages/docs/src/guide-composable/setup.md @@ -82,3 +82,27 @@ provide(ApolloClients, { ``` You can then select which one to use in functions we will cover next (such as `useQuery`, `useMutation` and `useSubscription`) with the `clientId` option. + +## Usage outside of setup + +When using e.g. `useQuery` outside of vue contexts, the clients cannot be injected using vue's provide/inject mechanism. `@vue/apollo-composable` can manage their own apollo clients + +Use `provideApolloClient` for a single default client: + +```js +import { provideApolloClient } from "@vue/apollo-composable"; + +provideApolloClient(apolloClient) +``` + +Use `provideApolloClients` for multiple clients: + +```js +import { provideApolloClients } from "@vue/apollo-composable"; + +provideApolloClients({ + default: apolloClient, + clientA: apolloClientA, + clientB: apolloClientB, +}) +``` diff --git a/packages/test-e2e-composable-vue3/src/components/NoSetupQueryMultiClient.vue b/packages/test-e2e-composable-vue3/src/components/NoSetupQueryMultiClient.vue new file mode 100644 index 0000000..68af2ed --- /dev/null +++ b/packages/test-e2e-composable-vue3/src/components/NoSetupQueryMultiClient.vue @@ -0,0 +1,35 @@ + + + diff --git a/packages/test-e2e-composable-vue3/src/router.ts b/packages/test-e2e-composable-vue3/src/router.ts index bd0b82c..4468883 100644 --- a/packages/test-e2e-composable-vue3/src/router.ts +++ b/packages/test-e2e-composable-vue3/src/router.ts @@ -18,6 +18,10 @@ export const router = createRouter({ path: '/no-setup-query', component: () => import('./components/NoSetupQuery.vue'), }, + { + path: '/no-setup-query-multi-client', + component: () => import('./components/NoSetupQueryMultiClient.vue'), + }, { path: '/lazy-query', component: () => import('./components/LazyQuery.vue'), diff --git a/packages/test-e2e-composable-vue3/tests/e2e/specs/test.js b/packages/test-e2e-composable-vue3/tests/e2e/specs/test.js index ad6bb9b..c909856 100644 --- a/packages/test-e2e-composable-vue3/tests/e2e/specs/test.js +++ b/packages/test-e2e-composable-vue3/tests/e2e/specs/test.js @@ -81,6 +81,11 @@ describe('Vue 3 + Apollo Composable', () => { cy.contains('.no-setup-query', 'Hello world!') }) + it('supports queries outside of setup with multiple clients', () => { + cy.visit('/no-setup-query-multi-client') + cy.contains('.no-setup-query', 'Hello world!') + }) + it('useLazyQuery', () => { cy.visit('/lazy-query') cy.get('.list-disc').should('have.length', 0) diff --git a/packages/vue-apollo-composable/src/index.ts b/packages/vue-apollo-composable/src/index.ts index e0302ea..a391745 100644 --- a/packages/vue-apollo-composable/src/index.ts +++ b/packages/vue-apollo-composable/src/index.ts @@ -43,4 +43,5 @@ export { useApolloClient, UseApolloClientReturn, provideApolloClient, + provideApolloClients, } from './useApolloClient' diff --git a/packages/vue-apollo-composable/src/useApolloClient.ts b/packages/vue-apollo-composable/src/useApolloClient.ts index 76163ac..781e840 100644 --- a/packages/vue-apollo-composable/src/useApolloClient.ts +++ b/packages/vue-apollo-composable/src/useApolloClient.ts @@ -33,28 +33,43 @@ export function useApolloClient (clientId?: ClientId): UseApo let resolveImpl: ResolveClient> // Save current client in current closure scope - const savedCurrentClient = currentApolloClient + const savedCurrentClients = currentApolloClients if (!getCurrentInstance()) { - resolveImpl = () => savedCurrentClient + resolveImpl = (id?: ClientId) => { + if (id) { + return resolveClientWithId(savedCurrentClients, id) + } + return resolveDefaultClient(savedCurrentClients, savedCurrentClients.default) + } } else { const providedApolloClients: ClientDict | null = inject(ApolloClients, null) const providedApolloClient: ApolloClient | null = inject(DefaultApolloClient, null) resolveImpl = (id?: ClientId) => { - if (savedCurrentClient) { - return savedCurrentClient - } else if (id) { - return resolveClientWithId(providedApolloClients, id) + if (id) { + const client = resolveClientWithId(providedApolloClients, id) + if (client) { + return client + } + return resolveClientWithId(savedCurrentClients, id) } - return resolveDefaultClient(providedApolloClients, providedApolloClient) + const client = resolveDefaultClient(providedApolloClients, providedApolloClient) + if (client) { + return client + } + return resolveDefaultClient(savedCurrentClients, savedCurrentClients.default) } } function resolveClient (id: ClientId | undefined = clientId) { const client = resolveImpl(id) if (!client) { - throw new Error(`Apollo client with id ${id ?? 'default'} not found. Use provideApolloClient() if you are outside of a component setup.`) + throw new Error( + `Apollo client with id ${ + id ?? 'default' + } not found. Use provideApolloClient() if you are outside of a component setup.`, + ) } return client } @@ -67,13 +82,24 @@ export function useApolloClient (clientId?: ClientId): UseApo } } -let currentApolloClient: NullableApolloClient +let currentApolloClients: ClientDict = {} export function provideApolloClient (client: ApolloClient) { - currentApolloClient = client + currentApolloClients = { + default: client, + } return function (fn: () => TFnResult) { const result = fn() - currentApolloClient = undefined + currentApolloClients = {} + return result + } +} + +export function provideApolloClients (clients: ClientDict) { + currentApolloClients = clients + return function (fn: () => TFnResult) { + const result = fn() + currentApolloClients = {} return result } }