Skip to content

Releases: apollographql/apollo-client

v3.9.2

01 Feb 14:38
064cf54
Compare
Choose a tag to compare

Patch Changes

v3.9.1

31 Jan 16:52
10f7b48
Compare
Choose a tag to compare

Patch Changes

v3.9.0

30 Jan 21:18
9f2ccdb
Compare
Choose a tag to compare

Minor Changes

Memory optimizations

  • #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.

  • #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.

  • #11254 d08970d Thanks @benjamn! - Decouple canonicalStringify from ObjectCanon for better time and memory performance.

  • #11356 cc4ac7e 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 25e2cb4 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 139acd1 Thanks @phryneas! - documentTransform: use optimism and WeakCache instead of directly storing data on the Trie

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

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

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

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

  • #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

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

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

  • #11343 776631d Thanks @phryneas! - Add reset method to print, hook up to InMemoryCache.gc

Suspense-enabled data fetching on user interaction with useLoadableQuery

  • #11300 a815873 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);
    
      // ...
    }

Begin preloading outside of React with createQueryPreloader

  • #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.

Testing utility improvements

  • #11178 4d64a6f Thanks @sebakerckhof! - Support re-using of mocks in the MockedProvider

  • #6701 8d2b4e1 Thanks @prowe! - Ability to dynamically match mocks

    Adds support for a new property MockedResponse.variableMatcher: a predicate function that accepts a variables param. If true, the variables will be passed into the ResultFunction to help dynamically build a response.

New useQueryRefHandlers hook

  • #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);
    
      // ...
    }

Bail out of optimisticResponse updates with the IGNORE sentinel object

  • #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
        }
      ...
Read more

v3.9.0-rc.1

18 Jan 18:40
cfe6b78
Compare
Choose a tag to compare
v3.9.0-rc.1 Pre-release
Pre-release

Patch Changes

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)