Apollo Client Pagination

Say, we have gql response like this and we wan't to have pagination with it. Let's merge it as it specified in official documentation

query listItems(  filter: Filter,   sort: String,  limit: Number,  offset: Number,): ItemList!input Filter {  name: String!  type: String!}type ItemList {  items: [Item!]!  totalCount: Int!}

We will setup ApolloClient with typePolicies to merge incoming data in cache:

import { ApolloClient, InMemoryCache } from '@apollo/client';const client = new ApolloClient({  // ...  cache: new InMemoryCache({ typePolicies }),  // ...});export const typePolicies: TypePolicies = {  Query: {    fields: {      // query name      listItems: {        // apollo will serialize and use keyArgs as unique        // identifier in cache for every query        // consider choosing the right fields,         // i.e. limit and offset won't work here        keyArgs: [          'sort', // primitive type          'filter', ['name', 'type'] // nested fields of `filter`        ],        merge: mergeItemsWithTotalCount,      },  }}

We will need merge function mergeItemsWithTotalCount, which will join results of query and cached data for specific key:

/** merges all sources with { items: unknown[], totalCount: number } */const mergeItemsWithTotalCount = (existing, incoming, { args }) => {    // no existing data    if (!existing || !args?.offset || args.offset < existing      return incoming || [];    }    // If hook was called multiple times    if (existing?.items?.      return existing || [];    }    // merge cache and incoming data    const items = [...(existing?.items ||     // apply latest result for totalCount    const totalCount = incoming?.totalCount || existing?.totalCount;    return {      ...(incoming ||       items,      totalCount,    };  };