From e2b677d2e7dd1a1c245faf183df2058383d6cca0 Mon Sep 17 00:00:00 2001 From: guen Date: Sun, 12 Oct 2025 22:14:22 +0900 Subject: [PATCH] feat: document migration steps and enhance `useAsyncQuery` API in Nuxt - Add detailed **Migration Guide** to docs, including steps to switch from `@vue/apollo-composable` to `@vue3-apollo/core`. - Enhance `useAsyncQuery` with improved types, detailed JSDoc annotations, and examples for better developer experience. - Update the documentation navigation to include the new "Migration" section. --- packages/docs/.vitepress/config.ts | 4 + packages/docs/migration.md | 165 ++++++++++++++++++ .../src/runtime/composables/useAsyncQuery.ts | 52 ++++++ 3 files changed, 221 insertions(+) create mode 100644 packages/docs/migration.md diff --git a/packages/docs/.vitepress/config.ts b/packages/docs/.vitepress/config.ts index 9f3ad51..734da55 100644 --- a/packages/docs/.vitepress/config.ts +++ b/packages/docs/.vitepress/config.ts @@ -36,6 +36,10 @@ export default defineConfig({ { link: '/getting-started', text: 'Getting Started' + }, + { + link: '/migration', + text: 'Migration' } ], text: 'Guide' diff --git a/packages/docs/migration.md b/packages/docs/migration.md new file mode 100644 index 0000000..5c40c98 --- /dev/null +++ b/packages/docs/migration.md @@ -0,0 +1,165 @@ +# Migration Guide + +This plugin is designed to make migration from **@vue/apollo-composable** effortless. + + +## Quick Overview +1. Upgrade to **Apollo Client v4** +2. Update imports from `@vue/apollo-composable` → `@vue3-apollo/core` +3. Integrate new **loading tracking system** (optional but recommended) +4. Review **Breaking Changes** and update types or options accordingly + + +## 1. Migration Steps + +### 1.1 Update Apollo Client + +Vue3 Apollo requires **Apollo Client v4** or higher. + +```bash +npm install @apollo/client@^4 +``` + +```json +{ + "@apollo/client": "^4.x.x" +} +``` + +### 1.2 Update Imports + +Simply change imports from `@vue/apollo-composable` to `@vue3-apollo/core`. + +**Before:** +```ts +import { useQuery } from '@vue/apollo-composable' +``` + +**After:** +```ts +import { useQuery, useMutation, useSubscription } from '@vue3-apollo/core' +``` + +All composables maintain the same API, so migration typically only involves updating import paths. + + +## 2. Enhanced Loading Tracking + +Vue3 Apollo introduces an improved tracking system to monitor loading states globally or per component. + +### Example +```ts +import { useQueriesLoading } from '@vue3-apollo/core' + +// Track loading of queries in a specific component or scope +const isLoading = useQueriesLoading('dashboard') +``` + +You can pass an optional **`id`** parameter to share loading states across components. + +### Available Helpers +- `useQueryLoading(id?)` +- `useMutationLoading(id?)` +- `useSubscriptionLoading(id?)` +- Global variants: `useGlobalQueryLoading()`, `useGlobalMutationLoading()`, `useGlobalSubscriptionLoading()` + + +## 3. Breaking Changes + +The new `useAsyncQuery` for Nuxt is close to the old one but there are some **notable differences** you should adjust for: + +### 1) Positional overloads removed → object options only +**Before (positional):** +```ts +useAsyncQuery(query, variables?, clientId?, context?, options?) +``` +**After (object):** +```ts +useAsyncQuery({ + query, + variables, + clientId, // optional + context, // optional +}) +``` +> This simplifies typing and aligns with Apollo `QueryOptions`. + +### 2) `useLazyAsyncQuery` removed +Use `useAsyncQuery` with Nuxt `AsyncData` options instead of the dedicated "lazy" variant. + +**Before:** +```ts +useLazyAsyncQuery({ + query, + variables, +}) +``` +**After (Nuxt AsyncData):** +```ts +useAsyncQuery( + { + query, + variables, + }, + { + lazy: true, // do not block navigation; fetch after route resolves + }, +) +``` + +### 3) `cache` option removed +The old `cache?: boolean` flag is replaced by **Apollo fetch policies**. + +**Before:** +```ts +useAsyncQuery({ + query, + variables, + cache: true, +}) +``` +**After:** +```ts +useAsyncQuery({ + query, + variables, + fetchPolicy: 'cache-first', +}) +``` + +## 4. Summary +| Feature | Old | New | Notes | +|----------|-----|-----|-------| +| Async Query (SSR) | `useAsyncQuery` from old package | `useAsyncQuery` (object options) | Unified API for Nuxt 4 | +| Lazy Async Query | `useLazyAsyncQuery` | Removed → use `useAsyncQuery` with `{ lazy: true }` | Simplified lazy fetching | +| Query / Mutation / Subscription | `@vue/apollo-composable` | `@vue3-apollo/core` | Same API | +| Global Loading Tracking | ✅ | ✅ | via `useApolloTracker` | +| Component-scoped Loading | ❌ | ✅ | pass `id` to track across scopes | +| Apollo v4 Support | Manual | ✅ | Native | + + +## 5. Example Migration + +**Before:** +```ts +import { useQuery } from '@vue/apollo-composable' +import MY_QUERY from './myQuery.gql' + +const { result, loading, error } = useQuery(MY_QUERY) +``` + +**After:** +```ts +import { useQuery } from '@vue3-apollo/core' +import MY_QUERY from './myQuery.gql' + +const { result, loading, error } = useQuery(MY_QUERY) +``` + +Optionally track loading across components: +```ts +import { useQueriesLoading } from '@vue3-apollo/core' +const isLoading = useQueriesLoading('dashboard') +``` + +🎉 **Migration complete!** Replace imports, update Apollo Client to v4, and enjoy new global tracking. diff --git a/packages/nuxt/src/runtime/composables/useAsyncQuery.ts b/packages/nuxt/src/runtime/composables/useAsyncQuery.ts index 7e57e28..5012bf0 100644 --- a/packages/nuxt/src/runtime/composables/useAsyncQuery.ts +++ b/packages/nuxt/src/runtime/composables/useAsyncQuery.ts @@ -14,13 +14,65 @@ import { useAsyncData } from 'nuxt/app' import { hash } from 'ohash' import { unref } from 'vue' +/** + * Configuration options for useAsyncQuery composable + * + * @template TData - The data type returned from the GraphQL query + * @template TVariables - The type of variables passed to the query + * + * @property {MaybeRefOrGetter} [key] - Unique key for caching query results. If not provided, key will be auto-generated from query and variables + */ export type UseAsyncQueryOptions = { key?: MaybeRefOrGetter } & ApolloClient.QueryOptions, TVariables> & UseBaseOption + +/** + * Type helper to prevent type inference in specific cases + * @internal + */ type NoInfer = [T][T extends any ? 0 : never] +/** + * Type helper to make a type optional (undefined) + * @internal + */ type Optional = T | undefined +/** + * Composable for executing asynchronous GraphQL queries in Nuxt + * + * Combines Apollo Client with Nuxt's useAsyncData to provide: + * - Server-side rendering (SSR) support + * - Automatic caching with unique keys + * - Loading states and error handling + * - Type-safe with TypeScript + * + * @template DataT - The data type returned from the GraphQL query + * @template TVariables - The type of variables passed to the query + * @template PickKeys - Keys picked from the returned data + * @template DefaultT - Default data type when query is not completed + * + * @param {UseAsyncQueryOptions} options - Query configuration options including GraphQL query, variables, and Apollo Client options + * @param {AsyncDataOptions} [config] - Configuration options for Nuxt's useAsyncData + * + * @returns {AsyncData, ErrorLike | NuxtError | undefined>} Object containing reactive data, pending state, error, and utility functions + * + * @example + * ```typescript + * const { data, pending, error } = await useAsyncQuery({ + * query: gql` + * query GetUser($id: ID!) { + * user(id: $id) { + * id + * name + * email + * } + * } + * `, + * variables: { id: '123' } + * }) + * ``` + */ export function useAsyncQuery< DataT = unknown, TVariables extends OperationVariables = OperationVariables,