CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/npm-tanstack--vue-query

Hooks for managing, caching and syncing asynchronous and remote data in Vue

Pending
Overview
Eval results
Files

query-client.mddocs/

Query Client

Central management system for all query and mutation operations, providing cache control, data management, and global configuration for TanStack Vue Query.

Capabilities

QueryClient Class

Main client class for managing queries, mutations, and cache operations.

/**
 * Central client for managing all query and mutation operations
 * @param config - Optional configuration for cache and default options
 */
class QueryClient {
  constructor(config?: QueryClientConfig);
  
  // Query data management
  getQueryData<TData>(queryKey: QueryKey): TData | undefined;
  setQueryData<TData>(
    queryKey: QueryKey, 
    updater: Updater<TData | undefined, TData | undefined>,
    options?: SetDataOptions
  ): TData | undefined;
  getQueriesData<TData>(filters: QueryFilters): Array<[QueryKey, TData | undefined]>;
  setQueriesData<TData>(
    filters: QueryFilters,
    updater: Updater<TData | undefined, TData | undefined>,
    options?: SetDataOptions
  ): Array<[QueryKey, TData | undefined]>;
  
  // Query state management
  getQueryState<TData, TError>(queryKey: QueryKey): QueryState<TData, TError> | undefined;
  
  // Cache operations
  invalidateQueries(filters?: InvalidateQueryFilters, options?: InvalidateOptions): Promise<void>;
  refetchQueries(filters?: RefetchQueryFilters, options?: RefetchOptions): Promise<void>;
  cancelQueries(filters?: QueryFilters, options?: CancelOptions): Promise<void>;
  removeQueries(filters?: QueryFilters): void;
  resetQueries(filters?: QueryFilters, options?: ResetOptions): Promise<void>;
  
  // Query execution
  fetchQuery<TData>(options: FetchQueryOptions<TData>): Promise<TData>;
  prefetchQuery<TData>(options: FetchQueryOptions<TData>): Promise<void>;
  ensureQueryData<TData>(options: EnsureQueryDataOptions<TData>): Promise<TData>;
  
  // Infinite query execution
  fetchInfiniteQuery<TData, TPageParam>(
    options: FetchInfiniteQueryOptions<TData, TPageParam>
  ): Promise<InfiniteData<TData, TPageParam>>;
  prefetchInfiniteQuery<TData, TPageParam>(
    options: FetchInfiniteQueryOptions<TData, TPageParam>
  ): Promise<void>;
  
  // Status tracking
  isFetching(filters?: QueryFilters): number;
  isMutating(filters?: MutationFilters): number;
  
  // Default options
  setDefaultOptions(options: DefaultOptions): void;
  getDefaultOptions(): DefaultOptions | undefined;
  setQueryDefaults(queryKey: QueryKey, options: QueryObserverOptions): void;
  getQueryDefaults(queryKey: QueryKey): QueryObserverOptions | undefined;
  setMutationDefaults(mutationKey: MutationKey, options: MutationObserverOptions): void;
  getMutationDefaults(mutationKey: MutationKey): MutationObserverOptions | undefined;
  
  // Cache access
  getQueryCache(): QueryCache;
  getMutationCache(): MutationCache;
  
  // Lifecycle
  mount(): void;
  unmount(): void;
  clear(): void;
}

interface QueryClientConfig {
  queryCache?: QueryCache;
  mutationCache?: MutationCache;
  defaultOptions?: DefaultOptions;
}

interface DefaultOptions {
  queries?: QueryObserverOptions & ShallowOption;
  mutations?: MutationObserverOptions & ShallowOption;
  hydrate?: HydrateOptions['defaultOptions'];
  dehydrate?: DehydrateOptions;
}

Usage Examples:

import { QueryClient } from '@tanstack/vue-query';

// Basic client setup
const queryClient = new QueryClient();

// Client with custom configuration
const queryClient = new QueryClient({
  defaultOptions: {
    queries: {
      staleTime: 1000 * 60 * 5, // 5 minutes
      gcTime: 1000 * 60 * 30,   // 30 minutes
      retry: 3,
      refetchOnWindowFocus: false,
    },
    mutations: {
      retry: 1,
    },
  },
});

// Data management
const userData = queryClient.getQueryData(['user', userId]);
queryClient.setQueryData(['user', userId], (oldData) => ({
  ...oldData,
  lastSeen: new Date().toISOString()
}));

// Cache operations
await queryClient.invalidateQueries({ queryKey: ['posts'] });
await queryClient.refetchQueries({ queryKey: ['user'] });
queryClient.removeQueries({ queryKey: ['temp'] });

// Prefetching
await queryClient.prefetchQuery({
  queryKey: ['posts', 'popular'],
  queryFn: () => fetch('/api/posts/popular').then(res => res.json()),
  staleTime: 1000 * 60 * 10,
});

// Ensure data exists
const userData = await queryClient.ensureQueryData({
  queryKey: ['user', userId],
  queryFn: () => fetch(`/api/users/${userId}`).then(res => res.json()),
});

// Status checking
const fetchingCount = queryClient.isFetching();
const mutatingCount = queryClient.isMutating();

useQueryClient

Composable to access the QueryClient instance within Vue components.

/**
 * Access the QueryClient instance via Vue's injection system
 * @param id - Optional client ID for multi-client setups
 * @returns QueryClient instance
 * @throws Error if called outside setup() or no client found
 */
function useQueryClient(id?: string): QueryClient;

Usage Examples:

import { useQueryClient } from '@tanstack/vue-query';

export default {
  setup() {
    const queryClient = useQueryClient();
    
    const invalidateUserData = () => {
      queryClient.invalidateQueries({ queryKey: ['user'] });
    };
    
    const prefetchUserPosts = async (userId) => {
      await queryClient.prefetchQuery({
        queryKey: ['posts', 'user', userId],
        queryFn: () => fetch(`/api/users/${userId}/posts`).then(res => res.json())
      });
    };
    
    return {
      invalidateUserData,
      prefetchUserPosts
    };
  }
};

QueryCache & MutationCache

Cache classes for advanced cache management and event handling.

/**
 * Cache for storing and managing query data
 */
class QueryCache {
  constructor(config?: QueryCacheConfig);
  
  find<TData, TError>(filters: QueryFilters): Query<TData, TError> | undefined;
  findAll(filters?: QueryFilters): Array<Query>;
  subscribe(listener: QueryCacheNotifyEventListener): () => void;
  clear(): void;
}

/**
 * Cache for storing and managing mutation data
 */
class MutationCache {
  constructor(config?: MutationCacheConfig);
  
  find<TData, TError, TVariables, TContext>(
    filters: MutationFilters
  ): Mutation<TData, TError, TVariables, TContext> | undefined;
  findAll(filters?: MutationFilters): Array<Mutation>;
  subscribe(listener: MutationCacheNotifyEventListener): () => void;
  clear(): void;
}

interface QueryCacheConfig {
  onError?: (error: unknown, query: Query<unknown, unknown>) => void;
  onSuccess?: (data: unknown, query: Query<unknown, unknown>) => void;
  onSettled?: (data: unknown | undefined, error: unknown | null, query: Query<unknown, unknown>) => void;
}

interface MutationCacheConfig {
  onError?: (error: unknown, variables: unknown, context: unknown, mutation: Mutation<unknown, unknown, unknown, unknown>) => void;
  onSuccess?: (data: unknown, variables: unknown, context: unknown, mutation: Mutation<unknown, unknown, unknown, unknown>) => void;
  onSettled?: (data: unknown | undefined, error: unknown | null, variables: unknown, context: unknown, mutation: Mutation<unknown, unknown, unknown, unknown>) => void;
}

Usage Examples:

import { QueryCache, MutationCache } from '@tanstack/vue-query';

// Custom cache with global error handling
const queryCache = new QueryCache({
  onError: (error, query) => {
    console.error('Query error:', error, 'Query key:', query.queryKey);
    if (error.status === 401) {
      // Handle authentication errors globally
      router.push('/login');
    }
  }
});

const mutationCache = new MutationCache({
  onError: (error) => {
    console.error('Mutation error:', error);
    // Show global error notification
    showErrorToast(error.message);
  }
});

const queryClient = new QueryClient({
  queryCache,
  mutationCache
});

// Subscribe to cache events
const unsubscribe = queryCache.subscribe((event) => {
  if (event.type === 'added') {
    console.log('Query added:', event.query.queryKey);
  }
});

// Cleanup
onUnmounted(() => {
  unsubscribe();
});

Types

// Core data types
type QueryKey = ReadonlyArray<unknown>;
type MutationKey = ReadonlyArray<unknown>;

// Updater function type
type Updater<TInput, TOutput> = TOutput | ((input: TInput) => TOutput);

// Query state interface
interface QueryState<TData = unknown, TError = DefaultError> {
  data: TData | undefined;
  dataUpdateCount: number;
  dataUpdatedAt: number;
  error: TError | null;
  errorUpdateCount: number;
  errorUpdatedAt: number;
  fetchFailureCount: number;
  fetchFailureReason: TError | null;
  fetchMeta: FetchMeta | null;
  isInvalidated: boolean;
  status: QueryStatus;
  fetchStatus: FetchStatus;
}

// Filter types
interface QueryFilters<TQueryFnData = unknown, TError = DefaultError, TData = TQueryFnData, TQueryKey extends QueryKey = QueryKey> {
  exact?: boolean;
  fetchStatus?: FetchStatus;
  predicate?: (query: Query<TQueryFnData, TError, TData, TQueryKey>) => boolean;
  queryKey?: TQueryKey;
  stale?: boolean;
  status?: QueryStatus;
  type?: QueryTypeFilter;
}

interface MutationFilters {
  exact?: boolean;
  fetching?: boolean;
  mutationKey?: MutationKey;
  predicate?: (mutation: Mutation<any, any, any, any>) => boolean;
  status?: MutationStatus;
}

// Options interfaces
interface SetDataOptions {
  updatedAt?: number;
}

interface InvalidateOptions {
  cancelRefetch?: boolean;
}

interface RefetchOptions {
  cancelRefetch?: boolean;
}

interface CancelOptions {
  revert?: boolean;
  silent?: boolean;
}

interface ResetOptions {
  cancelRefetch?: boolean;
}

// Fetch options
interface FetchQueryOptions<TQueryFnData, TError = DefaultError, TData = TQueryFnData, TQueryKey extends QueryKey = QueryKey> {
  queryKey: TQueryKey;
  queryFn?: QueryFunction<TQueryFnData, TQueryKey>;
  staleTime?: number;
  gcTime?: number;
  retry?: boolean | number | ((failureCount: number, error: TError) => boolean);
  retryDelay?: number | ((retryAttempt: number, error: TError) => number);
  signal?: AbortSignal;
  meta?: QueryMeta;
}

interface EnsureQueryDataOptions<TQueryFnData, TError = DefaultError, TData = TQueryFnData, TQueryKey extends QueryKey = QueryKey>
  extends FetchQueryOptions<TQueryFnData, TError, TData, TQueryKey> {
  revalidateIfStale?: boolean;
}

// Event listener types
type QueryCacheNotifyEventListener = (event: QueryCacheNotifyEvent) => void;
type MutationCacheNotifyEventListener = (event: MutationCacheNotifyEvent) => void;

interface QueryCacheNotifyEvent {
  type: 'added' | 'removed' | 'updated';
  query: Query<any, any, any, any>;
}

interface MutationCacheNotifyEvent {
  type: 'added' | 'removed' | 'updated';
  mutation: Mutation<any, any, any, any>;
}

Install with Tessl CLI

npx tessl i tessl/npm-tanstack--vue-query

docs

helpers.md

index.md

mutations.md

plugin-setup.md

queries.md

query-client.md

status-utilities.md

tile.json