Skip to content

Releases: apollographql/apollo-client

v3.8.10

18 Jan 17:29
17dc73b
Compare
Choose a tag to compare

Patch Changes

  • #11489 abfd02a Thanks @gronxb! - Fix networkStatus with useSuspenseQuery not properly updating to ready state when using a cache-and-network fetch policy that returns data equal to what is already in the cache.

  • #11483 6394dda Thanks @pipopotamasu! - Fix cache override warning output

v3.9.0-rc.0

17 Jan 17:19
9f5f801
Compare
Choose a tag to compare
v3.9.0-rc.0 Pre-release
Pre-release

Minor Changes

  • #11495 1190aa5 Thanks @jerelmiller! - Increase the default memory limits for executeSelectionSet and executeSelectionSetArray.

v3.8.9

09 Jan 21:29
37d336e
Compare
Choose a tag to compare

Patch Changes

  • #11472 afc844d Thanks @alessbell! - Fix delay: Infinity when set on a MockResponse passed to Mocked Provider so it indefinitely enters loading state.

  • #11464 aac12b2 Thanks @jerelmiller! - Prevent useFragment from excessively unsubscribing and resubscribing the fragment with the cache on every render.

  • #11449 f40cda4 Thanks @phryneas! - Removes refences to the typescript "dom" lib.

  • #11470 e293bc9 Thanks @phryneas! - Remove an unnecessary check from parseAndCheckHttpResponse.

v3.9.0-beta.1

21 Dec 14:50
fe56f68
Compare
Choose a tag to compare
v3.9.0-beta.1 Pre-release
Pre-release

Minor Changes

  • #11424 62f3b6d Thanks @phryneas! - Simplify RetryLink, fix potential memory leak

    Historically, RetryLink would keep a values array of all previous values,
    in case the operation would get an additional subscriber at a later point in time.
    In practice, this could lead to a memory leak (#11393) and did not serve any
    further purpose, as the resulting observable would only be subscribed to by
    Apollo Client itself, and only once - it would be wrapped in a Concast before
    being exposed to the user, and that Concast would handle subscribers on its
    own.

  • #11442 4b6f2bc Thanks @jerelmiller! - Remove the need to call retain from useLoadableQuery since useReadQuery will now retain the query. This means that a queryRef that is not consumed by useReadQuery within the given autoDisposeTimeoutMs will now be auto diposed for you.

    Thanks to #11412, disposed query refs will be automatically resubscribed to the query when consumed by useReadQuery after it has been disposed.

  • #11438 6d46ab9 Thanks @jerelmiller! - Remove the need to call retain from useBackgroundQuery since useReadQuery will now retain the query. This means that a queryRef that is not consumed by useReadQuery within the given autoDisposeTimeoutMs will now be auto diposed for you.

    Thanks to #11412, disposed query refs will be automatically resubscribed to the query when consumed by useReadQuery after it has been disposed.

Patch Changes

  • #11443 ff5a332 Thanks @phryneas! - Adds a deprecation warning to the HOC and render prop APIs.

    The HOC and render prop APIs have already been deprecated since 2020,
    but we previously didn't have a @deprecated tag in the DocBlocks.

  • #11078 14edebe Thanks @phryneas! - ObservableQuery: prevent reporting results of previous queries if the variables changed since

  • #11439 33454f0 Thanks @jerelmiller! - Address bundling issue introduced in #11412 where the react/cache internals ended up duplicated in the bundle. This was due to the fact that we had a react/hooks entrypoint that imported these files along with the newly introduced createQueryPreloader function, which lived outside of the react/hooks folder.

v3.9.0-beta.0

18 Dec 19:42
3a2240f
Compare
Choose a tag to compare
v3.9.0-beta.0 Pre-release
Pre-release

Minor Changes

  • #11412 58db5c3 Thanks @jerelmiller! - Create a new useQueryRefHandlers hook that returns refetch and fetchMore functions for a given queryRef. This is useful to get access to handlers for a queryRef that was created by createQueryPreloader or when the handlers for a queryRef produced by a different component are inaccessible.

    const MyComponent({ queryRef }) {
      const { refetch, fetchMore } = useQueryRefHandlers(queryRef);
    
      // ...
    }
  • #11410 07fcf6a Thanks @sf-twingate! - Allow returning IGNORE sentinel object from optimisticResponse functions to bail-out from the optimistic update.

    Consider this example:

    const UPDATE_COMMENT = gql`
      mutation UpdateComment($commentId: ID!, $commentContent: String!) {
        updateComment(commentId: $commentId, content: $commentContent) {
          id
          __typename
          content
        }
      }
    `;
    
    function CommentPageWithData() {
      const [mutate] = useMutation(UPDATE_COMMENT);
      return (
        <Comment
          updateComment={({ commentId, commentContent }) =>
            mutate({
              variables: { commentId, commentContent },
              optimisticResponse: (vars, { IGNORE }) => {
                if (commentContent === "foo") {
                  // conditionally bail out of optimistic updates
                  return IGNORE;
                }
                return {
                  updateComment: {
                    id: commentId,
                    __typename: "Comment",
                    content: commentContent,
                  },
                };
              },
            })
          }
        />
      );
    }

    The IGNORE sentinel can be destructured from the second parameter in the callback function signature passed to optimisticResponse.

  • #11412 58db5c3 Thanks @jerelmiller! - Add the ability to start preloading a query outside React to begin fetching as early as possible. Call createQueryPreloader to create a preloadQuery function which can be called to start fetching a query. This returns a queryRef which is passed to useReadQuery and suspended until the query is done fetching.

    const preloadQuery = createQueryPreloader(client);
    const queryRef = preloadQuery(QUERY, { variables, ...otherOptions });
    
    function App() {
      return {
        <Suspense fallback={<div>Loading</div>}>
          <MyQuery />
        </Suspense>
      }
    }
    
    function MyQuery() {
      const { data } = useReadQuery(queryRef);
    
      // do something with data
    }
  • #11397 3f7eecb Thanks @aditya-kumawat! - Adds a new skipPollAttempt callback function that's called whenever a refetch attempt occurs while polling. If the function returns true, the refetch is skipped and not reattempted until the next poll interval. This will solve the frequent use-case of disabling polling when the window is inactive.

    useQuery(QUERY, {
      pollInterval: 1000,
      skipPollAttempt: () => document.hidden, // or !document.hasFocus()
    });
    // or define it globally
    new ApolloClient({
      defaultOptions: {
        watchQuery: {
          skipPollAttempt: () => document.hidden, // or !document.hasFocus()
        },
      },
    });
  • #11435 5cce53e Thanks @phryneas! - Deprecates canonizeResults.

    Using canonizeResults can result in memory leaks so we generally do not recommend using this option anymore.
    A future version of Apollo Client will contain a similar feature without the risk of memory leaks.

Patch Changes

  • #11369 2a47164 Thanks @phryneas! - Persisted Query Link: improve memory management

    • use LRU WeakCache instead of WeakMap to keep a limited number of hash results
    • hash cache is initiated lazily, only when needed
    • expose persistedLink.resetHashCache() method
    • reset hash cache if the upstream server reports it doesn't accept persisted queries
  • #10804 221dd99 Thanks @phryneas! - use WeakMap in React Native with Hermes

  • #11409 2e7203b Thanks @phryneas! - Adds an experimental ApolloClient.getMemoryInternals helper

v3.9.0-alpha.5

05 Dec 00:21
838095b
Compare
Choose a tag to compare
v3.9.0-alpha.5 Pre-release
Pre-release

Minor Changes

  • #11345 1759066a8 Thanks @phryneas! - QueryManager.inFlightLinkObservables now uses a strong Trie as an internal data structure.

    Warning: requires @apollo/experimental-nextjs-app-support update

    If you are using @apollo/experimental-nextjs-app-support, you will need to update that to at least 0.5.2, as it accesses this internal data structure.

  • #11300 a8158733c Thanks @jerelmiller! - Introduces a new useLoadableQuery hook. This hook works similarly to useBackgroundQuery in that it returns a queryRef that can be used to suspend a component via the useReadQuery hook. It provides a more ergonomic way to load the query during a user interaction (for example when wanting to preload some data) that would otherwise be clunky with useBackgroundQuery.

    function App() {
      const [loadQuery, queryRef, { refetch, fetchMore, reset }] =
        useLoadableQuery(query, options);
    
      return (
        <>
          <button onClick={() => loadQuery(variables)}>Load query</button>
          <Suspense fallback={<SuspenseFallback />}>
            {queryRef && <Child queryRef={queryRef} />}
          </Suspense>
        </>
      );
    }
    
    function Child({ queryRef }) {
      const { data } = useReadQuery(queryRef);
    
      // ...
    }

Patch Changes

  • #11356 cc4ac7e19 Thanks @phryneas! - Fix a potential memory leak in FragmentRegistry.transform and FragmentRegistry.findFragmentSpreads that would hold on to passed-in DocumentNodes for too long.

  • #11370 25e2cb431 Thanks @phryneas! - parse function: improve memory management

    • use LRU WeakCache instead of Map to keep a limited number of parsed results
    • cache is initiated lazily, only when needed
    • expose parse.resetCache() method
  • #11389 139acd115 Thanks @phryneas! - documentTransform: use optimism and WeakCache instead of directly storing data on the Trie

  • #11358 7d939f80f Thanks @phryneas! - Fixes a potential memory leak in Concast that might have been triggered when Concast was used outside of Apollo Client.

  • #11344 bd2667619 Thanks @phryneas! - Add a resetCache method to DocumentTransform and hook InMemoryCache.addTypenameTransform up to InMemoryCache.gc

  • #11367 30d17bfeb Thanks @phryneas! - print: use WeakCache instead of WeakMap

  • #11385 d9ca4f082 Thanks @phryneas! - ensure defaultContext is also used for mutations and subscriptions

  • #11387 4dce8673b Thanks @phryneas! - QueryManager.transformCache: use WeakCache instead of WeakMap

  • #11371 ebd8fe2c1 Thanks @phryneas! - Clarify types of EntityStore.makeCacheKey.

  • #11355 7d8e18493 Thanks @phryneas! - InMemoryCache.gc now also triggers FragmentRegistry.resetCaches (if there is a FragmentRegistry)

v3.8.8

29 Nov 18:32
89ec18e
Compare
Choose a tag to compare

Patch Changes

v3.9.0-alpha.4

08 Nov 15:41
950cae8
Compare
Choose a tag to compare
v3.9.0-alpha.4 Pre-release
Pre-release

Minor Changes

  • #11175 d6d14911c Thanks @phryneas! - To work around issues in React Server Components, especially with bundling for
    the Next.js "edge" runtime we now use an external package to wrap react imports
    instead of importing React directly.

Patch Changes

v3.9.0-alpha.3

02 Nov 14:04
be2029b
Compare
Choose a tag to compare
v3.9.0-alpha.3 Pre-release
Pre-release

Minor Changes

  • #11301 46ab032af Thanks @alessbell! - Add multipart subscription network adapters for Relay and urql

    Relay

    import { createFetchMultipartSubscription } from "@apollo/client/utilities/subscriptions/relay";
    import { Environment, Network, RecordSource, Store } from "relay-runtime";
    
    const fetchMultipartSubs = createFetchMultipartSubscription(
      "http://localhost:4000"
    );
    
    const network = Network.create(fetchQuery, fetchMultipartSubs);
    
    export const RelayEnvironment = new Environment({
      network,
      store: new Store(new RecordSource()),
    });

    Urql

    import { createFetchMultipartSubscription } from "@apollo/client/utilities/subscriptions/urql";
    import { Client, fetchExchange, subscriptionExchange } from "@urql/core";
    
    const url = "http://localhost:4000";
    
    const multipartSubscriptionForwarder = createFetchMultipartSubscription(url);
    
    const client = new Client({
      url,
      exchanges: [
        fetchExchange,
        subscriptionExchange({
          forwardSubscription: multipartSubscriptionForwarder,
        }),
      ],
    });

Patch Changes

  • #11275 3862f9ba9 Thanks @phryneas! - Add a defaultContext option and property on ApolloClient, e.g. for keeping track of changing auth tokens or dependency injection.

    This can be used e.g. in authentication scenarios, where a new token might be
    generated outside of the link chain and should passed into the link chain.

    import { ApolloClient, createHttpLink, InMemoryCache } from "@apollo/client";
    import { setContext } from "@apollo/client/link/context";
    
    const httpLink = createHttpLink({
      uri: "/graphql",
    });
    
    const authLink = setContext((_, { headers, token }) => {
      return {
        headers: {
          ...headers,
          authorization: token ? `Bearer ${token}` : "",
        },
      };
    });
    
    const client = new ApolloClient({
      link: authLink.concat(httpLink),
      cache: new InMemoryCache(),
    });
    
    // somewhere else in your application
    function onNewToken(newToken) {
      // token can now be changed for future requests without need for a global
      // variable, scoped ref or recreating the client
      client.defaultContext.token = newToken;
    }
  • #11297 c8c76a522 Thanks @jerelmiller! - Add an explicit return type for the useReadQuery hook called UseReadQueryResult. Previously the return type of this hook was inferred from the return value.

v3.8.7

02 Nov 15:54
8329f07
Compare
Choose a tag to compare

Patch Changes

  • #11297 c8c76a522 Thanks @jerelmiller! - Add an explicit return type for the useReadQuery hook called UseReadQueryResult. Previously the return type of this hook was inferred from the return value.

  • #11337 bb1da8349 Thanks @phryneas! - #11206 used the TypeScript syntax infer X extends Y that was introduced in TS 4.8.
    This caused some problems for some users, so we are rolling back to a more backwards-compatible (albeit slightly less performant) type.