or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

docs

caching.mdcore-client.mderror-handling.mdindex.mdlink-system.mdmasking.mdreact-hooks.mdtesting.mdutilities.md
tile.json

core-client.mddocs/

Core Client Operations

Central client functionality for executing GraphQL operations with caching and link management. The ApolloClient class provides the foundation for all GraphQL operations with intelligent caching, observable queries, and comprehensive lifecycle management.

Capabilities

ApolloClient Class

The main client class that coordinates GraphQL operations, caching, and link execution.

/**
 * Main Apollo GraphQL client class
 * Manages GraphQL operations, cache coordination, and link chain execution
 */
class ApolloClient<TCacheShape = NormalizedCacheObject> {
  constructor(options: ApolloClientOptions<TCacheShape>);
  
  /** The cache instance used by this client */
  cache: ApolloCache<TCacheShape>;
  
  /** The link chain used for network operations */
  link: ApolloLink;
  
  /** Default options for queries, mutations, and watchQuery */
  defaultOptions: DefaultOptions;
  
  /** Version information */
  version: string;
}

interface ApolloClientOptions<TCacheShape> {
  /** GraphQL endpoint URI or Link instance */
  uri?: string | UriFunction;
  link?: ApolloLink;
  /** Cache implementation */
  cache: ApolloCache<TCacheShape>;
  /** Default options for operations */
  defaultOptions?: DefaultOptions;
  /** Type definitions for local resolvers */
  typeDefs?: string | string[] | DocumentNode | DocumentNode[];
  /** Local state resolvers */
  resolvers?: Resolvers | Resolvers[];
  /** Enable Apollo DevTools */
  devtools?: DevtoolsOptions;
}

Usage Example:

import { ApolloClient, InMemoryCache, createHttpLink } from "@apollo/client";

const httpLink = createHttpLink({
  uri: 'https://api.example.com/graphql',
});

const client = new ApolloClient({
  link: httpLink,
  cache: new InMemoryCache(),
  defaultOptions: {
    watchQuery: {
      errorPolicy: 'ignore',
    },
    query: {
      errorPolicy: 'all',
    },
  },
});

Query Operations

Execute one-time GraphQL queries with caching support.

/**
 * Execute a GraphQL query
 * @param options - Query options including query, variables, and fetch policy
 * @returns Promise resolving to query result with data and metadata
 */
query<T = any, TVariables = OperationVariables>(
  options: QueryOptions<TVariables, T>
): Promise<ApolloQueryResult<T>>;

interface QueryOptions<TVariables = OperationVariables, TData = any> {
  /** GraphQL query document */
  query: DocumentNode | TypedDocumentNode<TData, TVariables>;
  /** Variables for the query */
  variables?: TVariables;
  /** How to interact with the cache */
  fetchPolicy?: FetchPolicy;
  /** Error handling policy */
  errorPolicy?: ErrorPolicy;
  /** Context passed to links */
  context?: DefaultContext;
  /** Notification of network events */
  notifyOnNetworkStatusChange?: boolean;
  /** Return partial data from cache */
  returnPartialData?: boolean;
  /** Polling interval in milliseconds */
  pollInterval?: number;
}

interface ApolloQueryResult<T> {
  /** Query result data */
  data: T;
  /** Whether query is loading */
  loading: boolean;
  /** Current network status */
  networkStatus: NetworkStatus;
  /** Any errors that occurred */
  error?: ApolloError;
  /** Partial data indicator */
  partial?: boolean;
}

Usage Example:

const GET_USER = gql`
  query GetUser($id: ID!) {
    user(id: $id) {
      id
      name
      email
    }
  }
`;

const result = await client.query({
  query: GET_USER,
  variables: { id: '123' },
  fetchPolicy: 'cache-first'
});

console.log(result.data.user);

Mutation Operations

Execute GraphQL mutations with optimistic updates and cache management.

/**
 * Execute a GraphQL mutation
 * @param options - Mutation options including mutation, variables, and update functions
 * @returns Promise resolving to mutation result
 */
mutate<TData = any, TVariables = OperationVariables>(
  options: MutationOptions<TData, TVariables>
): Promise<FetchResult<TData>>;

interface MutationOptions<TData = any, TVariables = OperationVariables> {
  /** GraphQL mutation document */
  mutation: DocumentNode | TypedDocumentNode<TData, TVariables>;
  /** Variables for the mutation */
  variables?: TVariables;
  /** Optimistic response for immediate UI updates */
  optimisticResponse?: TData | ((vars: TVariables) => TData);
  /** Function to update cache after mutation */
  update?: MutationUpdaterFunction<TData, TVariables>;
  /** Queries to refetch after mutation */
  refetchQueries?: RefetchQueriesInclude;
  /** How to write mutation result to cache */
  fetchPolicy?: MutationFetchPolicy;
  /** Error handling policy */
  errorPolicy?: ErrorPolicy;
  /** Context passed to links */
  context?: DefaultContext;
}

Usage Example:

const CREATE_USER = gql`
  mutation CreateUser($input: CreateUserInput!) {
    createUser(input: $input) {
      id
      name
      email
    }
  }
`;

const result = await client.mutate({
  mutation: CREATE_USER,
  variables: {
    input: {
      name: 'John Doe',
      email: 'john@example.com'
    }
  },
  update: (cache, { data }) => {
    if (data?.createUser) {
      cache.modify({
        fields: {
          users(existingUsers = []) {
            const newUserRef = cache.writeFragment({
              data: data.createUser,
              fragment: gql`
                fragment NewUser on User {
                  id
                  name
                  email
                }
              `
            });
            return [...existingUsers, newUserRef];
          }
        }
      });
    }
  }
});

Subscription Operations

Execute GraphQL subscriptions for real-time data updates.

/**
 * Execute a GraphQL subscription
 * @param options - Subscription options including subscription and variables
 * @returns Observable that emits subscription updates
 */
subscribe<T = any, TVariables = OperationVariables>(
  options: SubscriptionOptions<TVariables, T>
): Observable<FetchResult<T>>;

interface SubscriptionOptions<TVariables = OperationVariables, TData = any> {
  /** GraphQL subscription document */
  query: DocumentNode | TypedDocumentNode<TData, TVariables>;
  /** Variables for the subscription */
  variables?: TVariables;
  /** How to interact with the cache */
  fetchPolicy?: FetchPolicy;
  /** Error handling policy */
  errorPolicy?: ErrorPolicy;
  /** Context passed to links */
  context?: DefaultContext;
}

Usage Example:

const MESSAGE_SUBSCRIPTION = gql`
  subscription MessageAdded($channel: String!) {
    messageAdded(channel: $channel) {
      id
      content
      user {
        name
      }
      createdAt
    }
  }
`;

const subscription = client.subscribe({
  query: MESSAGE_SUBSCRIPTION,
  variables: { channel: 'general' }
});

subscription.subscribe({
  next: (result) => {
    console.log('New message:', result.data?.messageAdded);
  },
  error: (error) => {
    console.error('Subscription error:', error);
  }
});

Watch Query Operations

Create observable queries that reactively update when underlying data changes.

/**
 * Create an observable query that updates reactively
 * @param options - Watch query options
 * @returns ObservableQuery instance for reactive updates
 */
watchQuery<T = any, TVariables = OperationVariables>(
  options: WatchQueryOptions<TVariables, T>
): ObservableQuery<T, TVariables>;

class ObservableQuery<TData = any, TVariables = OperationVariables> {
  /** Current query options */
  options: WatchQueryOptions<TVariables, TData>;
  
  /** Query variables */
  variables: TVariables | undefined;
  
  /** Get current result synchronously */
  getCurrentResult(): ApolloQueryResult<TData>;
  
  /** Refetch the query */
  refetch(variables?: Partial<TVariables>): Promise<ApolloQueryResult<TData>>;
  
  /** Fetch more data for pagination */
  fetchMore<TFetchData = TData, TFetchVars = TVariables>(
    options: FetchMoreQueryOptions<TFetchVars, TFetchData>
  ): Promise<ApolloQueryResult<TData>>;
  
  /** Subscribe for more data */
  subscribeToMore<TSubscriptionData = TData, TSubscriptionVariables = TVariables>(
    options: SubscribeToMoreOptions<TData, TSubscriptionVariables, TSubscriptionData>
  ): () => void;
  
  /** Update query data optimistically */
  updateQuery<TVars = TVariables>(
    mapFn: (previousQueryResult: TData, options: UpdateQueryOptions<TVars>) => TData
  ): void;
  
  /** Start polling for updates */
  startPolling(pollInterval: number): void;
  
  /** Stop polling */
  stopPolling(): void;
}

Usage Example:

const observableQuery = client.watchQuery({
  query: GET_USERS,
  variables: { limit: 10 },
  pollInterval: 5000
});

const subscription = observableQuery.subscribe({
  next: (result) => {
    console.log('Users updated:', result.data.users);
  },
  error: (error) => {
    console.error('Query error:', error);
  }
});

// Later: fetch more users
observableQuery.fetchMore({
  variables: { offset: 10, limit: 10 },
  updateQuery: (prev, { fetchMoreResult }) => {
    if (!fetchMoreResult) return prev;
    return {
      ...fetchMoreResult,
      users: [...prev.users, ...fetchMoreResult.users]
    };
  }
});

Cache Operations

Direct cache read and write operations for managing local state.

/**
 * Read data from cache using a query
 * @param options - Read options with query and variables
 * @returns Query data from cache or null if not found
 */
readQuery<QueryType, TVariables = any>(
  options: DataProxy.ReadQueryOptions<QueryType, TVariables>
): QueryType | null;

/**
 * Write data to cache using a query structure
 * @param options - Write options with query, variables, and data
 */
writeQuery<TData = any, TVariables = any>(
  options: DataProxy.WriteQueryOptions<TData, TVariables>
): void;

/**
 * Read a fragment from the cache
 * @param options - Fragment read options
 * @returns Fragment data or null if not found
 */
readFragment<FragmentType, TVariables = any>(
  options: DataProxy.ReadFragmentOptions<FragmentType, TVariables>
): FragmentType | null;

/**
 * Write a fragment to the cache
 * @param options - Fragment write options
 */
writeFragment<TData = any, TVariables = any>(
  options: DataProxy.WriteFragmentOptions<TData, TVariables>
): void;

Usage Example:

// Read from cache
const userData = client.readQuery({
  query: GET_USER,
  variables: { id: '123' }
});

// Write to cache
client.writeQuery({
  query: GET_USER,
  variables: { id: '123' },
  data: {
    user: {
      id: '123',
      name: 'John Doe',
      email: 'john@example.com',
      __typename: 'User'
    }
  }
});

// Read fragment
const userFragment = client.readFragment({
  id: 'User:123',
  fragment: gql`
    fragment UserInfo on User {
      name
      email
    }
  `
});

Client Management

Store management and client lifecycle operations.

/**
 * Reset the entire store, clearing all data
 * @returns Promise that resolves when reset is complete
 */
resetStore(): Promise<ApolloQueryResult<any>[]>;

/**
 * Clear the store without refetching active queries
 * @returns Promise that resolves when clear is complete
 */
clearStore(): Promise<any[]>;

/**
 * Refetch all active queries
 * @param options - Refetch options
 * @returns Promise with refetch results
 */
refetchQueries(options: RefetchQueriesOptions): Promise<RefetchQueriesResult>;

/**
 * Stop all active queries and subscriptions
 */
stop(): void;

Usage Example:

// Reset store and refetch all queries
await client.resetStore();

// Clear store without refetching
await client.clearStore();

// Refetch specific queries
await client.refetchQueries({
  include: [GET_USERS, GET_POSTS]
});

// Stop all operations
client.stop();

Types

type UriFunction = (operation: Operation) => string;

interface DefaultOptions {
  query?: Partial<QueryOptions>;
  mutate?: Partial<MutationOptions>;
  watchQuery?: Partial<WatchQueryOptions>;
}

interface DevtoolsOptions {
  enabled?: boolean;
  name?: string;
}

type RefetchQueriesInclude = 
  | string 
  | DocumentNode 
  | (string | DocumentNode)[]
  | 'all'
  | 'active';

interface RefetchQueriesOptions {
  include?: RefetchQueriesInclude;
  onQueryUpdated?: OnQueryUpdated;
  optimistic?: boolean;
}

interface RefetchQueriesResult {
  results: RefetchQueryDescriptor[];
  errors: any[];
}