Skip to content

Releases: apollographql/apollo-client

@apollo/client-graphql-codegen@1.0.0-rc.0

19 Jun 15:42
449c3ea
Compare
Choose a tag to compare

Major Changes

@apollo/client@4.0.0-rc.0

18 Jun 21:53
f1eba94
Compare
Choose a tag to compare
Pre-release

Major Changes

@apollo/client@4.0.0-alpha.23

18 Jun 21:22
44645d2
Compare
Choose a tag to compare
Pre-release

Major Changes

  • #12712 bbb2b61 Thanks @jerelmiller! - An error is now thrown when trying to call fetchMore on a cache-only query.

  • #12712 bbb2b61 Thanks @jerelmiller! - cache-only queries are no longer refetched when calling client.reFetchObservableQueries when includeStandby is true.

  • #12705 a60f411 Thanks @jerelmiller! - cache-only queries will now initialize with loading: false and networkStatus: NetworkStatus.ready when there is no data in the cache.

    This means useQuery will no longer render a short initial loading state before rendering loading: false and ObservableQuery.getCurrentResult() will now return loading: false immediately.

  • #12712 bbb2b61 Thanks @jerelmiller! - cache-only queries are now excluded from client.refetchQueries in all situations. cache-only queries affected by updateCache are also excluded from refetchQueries when onQueryUpdated is not provided.

  • #12681 b181f98 Thanks @jerelmiller! - Changing most options when rerendering useQuery will no longer trigger a reobserve which may cause network fetches. Instead, the changed options will be applied to the next cache update or fetch.

    Options that now trigger a reobserve when changed between renders are:

    • query
    • variables
    • skip
    • Changing fetchPolicy to or from standby
  • #12714 0e39469 Thanks @phryneas! - Rework option handling for fetchMore.

    • Previously, if the query option was specified, no options would be inherited
      from the underlying ObservableQuery.
      Now, even if query is specified, all unspecified options except for variables will be inherited from the underlying ObservableQuery.
    • If query is not specified, variables will still be shallowly merged with the variables of the underlying ObservableQuery. If a query option is specified, the variables passed to fetchMore are used instead.
    • errorPolicy of fetchMore will now always default to "none" instead of inherited from the ObservableQuery options. This can prevent accidental cache writes of partial data for a paginated query. To opt into receive partial data that may be written to the cache, pass an errorPolicy to fetchMore to override the default.
  • #12700 8e96e08 Thanks @phryneas! - Added a new Streaming type that will mark data in results while dataStatus
    is "streaming".

    Streaming<TData> defaults to TData, but can be overwritten in userland to
    integrate with different codegen dialects.

    You can override this type globally - this example shows how to override it
    with DeepPartial<TData>:

    import { HKT, DeepPartial } from "@apollo/client/utilities";
    
    type StreamingOverride<TData> = DeepPartial<TData>;
    
    interface StreamingOverrideHKT extends HKT {
      return: StreamingOverride<this["arg1"]>;
    }
    
    declare module "@apollo/client" {
      export interface TypeOverrides {
        Streaming: StreamingOverrideHKT;
      }
    }
  • #12499 ce35ea2 Thanks @phryneas! - Enable React compiler for hooks in ESM builds.

  • #12704 45dba43 Thanks @jerelmiller! - The ErrorResponse object passed to the disable and retry callback options provided to createPersistedQueryLink no longer provides separate graphQLErrors and networkError properties and instead have been combined to a single error property of type ErrorLike.

    // The following also applies to the `retry` function since it has the same signature
    createPersistedQueryLink({
    - disable: ({ graphQLErrors, networkError }) => {
    + disable: ({ error }) => {
    -   if (graphQLErrors) {
    +   if (CombinedGraphQLErrors.is(error)) {
          // ... handle GraphQL errors
        }
    
    -   if (networkError) {
    +   if (error) {
          // ... handle link errors
        }
    
        // optionally check for a specific kind of error
    -   if (networkError) {
    +   if (ServerError.is(error)) {
          // ... handle a server error
        }
    });

    The response property has also been renamed to result.

    createPersistedQueryLink({
    -  disable: ({ response }) => {
    +  disable: ({ result }) => {
          // ... handle GraphQL errors
        }
      }
    });
  • #12712 bbb2b61 Thanks @jerelmiller! - cache-only queries no longer poll when a pollInterval is set. Instead a warning is now emitted that polling has no effect. If the fetchPolicy is changed to cache-only after polling is already active, polling is stopped.

  • #12704 45dba43 Thanks @jerelmiller! - The response property in onError link has been renamed to result.

    - onError(({ response }) => {
    + onError(({ result }) => {
        // ...
    });
  • #12715 0be0b3f Thanks @phryneas! - All links are now available as classes. The old creator functions have been deprecated.

    Please migrate these function calls to class creations:

    import {
    - setContext
    + SetContextLink
    } from "@apollo/client/link/context"
    
    -const link = setContext(...)
    +const link = new SetContextLink(...)
    import {
    - createHttpLink
    + HttpLink
    } from "@apollo/client/link/http"
    
    -const link = createHttpLink(...)
    +const link = new HttpLink(...)
    import {
    - createPersistedQueryLink
    + PersistedQueryLink
    } from "@apollo/client/link/persisted-queries"
    
    -const link = createPersistedQueryLink(...)
    +const link = new PersistedQueryLink(...)
    import {
    - removeTypenameFromVariables
    + RemoveTypenameFromVariablesLink
    } from "@apollo/client/link/remove-typename"
    
    -const link = removeTypenameFromVariables(...)
    +const link = new RemoveTypenameFromVariablesLink(...)

Minor Changes

  • #12711 f730f83 Thanks @jerelmiller! - Add an extensions property to CombinedGraphQLErrors to capture any extensions from the original response.

  • #12700 8e96e08 Thanks @phryneas! - The callback function that can be passed to the ApolloClient.mutate
    refetchQueries option will now receive a FormattedExecutionResult with an
    additional dataState option that describes if the result is "streaming"
    or "complete".
    This indicates whether the data value is of type

    • Unmasked<TData> (if "complete")
    • Streaming<Unmasked<TData>> (if "streaming")
  • #12714 0e39469 Thanks @phryneas! - Allow passing errorPolicy option to fetchMore and change default value to "none".

  • #12714 0e39469 Thanks @phryneas! - The FetchMoreQueryOptions type has been inlined into FetchMoreOptions, and
    FetchMoreQueryOptions has been removed.

  • #12700 [`8e96...

Read more

@apollo/client@4.0.0-alpha.22

13 Jun 17:47
ddf196a
Compare
Choose a tag to compare
Pre-release

Major Changes

  • #12673 cee90ab Thanks @phryneas! - The includeExtensions option of HttpLink and BatchHttpLink now defaults
    to true.

    If includeExtensions is true, but extensions is not set or empty, extensions
    will not be included in outgoing requests.

  • #12673 cee90ab Thanks @phryneas! - The ApolloClient constructor options name and version that are used to
    configure the client awareness feature have moved onto a clientAwareness key.

    const client = new ApolloClient({
      // ..
    -  name: "my-app",
    -  version: "1.0.0",
    +  clientAwareness: {
    +    name: "my-app",
    +    version: "1.0.0",
    +  },
    });
  • #12690 5812759 Thanks @phryneas! - Aliasing any other field to __typename is now forbidden.

  • #12690 5812759 Thanks @phryneas! - Aliasing a field to an alias beginning with __ac_ is now forbidden - this namespace is now reserved for internal use.

  • #12673 cee90ab Thanks @phryneas! - Adds enhanced client awareness to the client.

    HttpLink and BatchHttpLink will now per default send information about the
    client library you are using in extensions.

    This could look like this:

    {
      "query": "query GetUser($id: ID!) { user(id: $id) { __typename id name } }",
      "variables": {
        "id": 5
      },
      "extensions": {
        "clientLibrary": {
          "name": "@apollo/client",
          "version": "4.0.0"
        }
      }
    }

    This feature can be disabled by passing enhancedClientAwareness: { transport: false } to your
    ApolloClient, HttpLink or BatchHttpLink constructor options.

Minor Changes

  • #12698 be77d1a Thanks @phryneas! - Adjusted the accept header for multipart requests according to the new GraphQL over HTTP spec with these changes:

    -multipart/mixed;boundary=graphql;subscriptionSpec=1.0,application/json
    +multipart/mixed;boundary=graphql;subscriptionSpec=1.0,application/graphql-response+json,application/json;q=0.9
    -multipart/mixed;deferSpec=20220824,application/json
    +multipart/mixed;deferSpec=20220824,application/graphql-response+json,application/json;q=0.9
  • #12673 cee90ab Thanks @phryneas! - Add the new ClientAwarenessLink.

    This link is already included in HttpLink and BatchHttpLink to enable the
    "client awareness" and "enhanced client awareness" features, but you can also use
    ClientAwarenessLink directly in your link chain to combine it with other
    terminating links.

    If you want to save the bundle size that ClientAwarenessLink adds to HttpLink
    and BatchHttpLink, you can use BaseHttpLink or BaseBatchHttpLink instead.
    These links come without the ClientAwarenessLink included.

    For example:

    import {
      ApolloClient,
    -  HttpLink,
    } from "@apollo/client";
    +import { BaseHttpLink } from "@apollo/client/link/http";
    
    const client = new ApolloClient({
    -  link: new HttpLink({
    +  link: new BaseHttpLink({
        uri,
      }),
      cache: new InMemoryCache(),
    });
  • #12698 be77d1a Thanks @phryneas! - Adds an accept option to HttpOptions that allows to add additional Accept headers to be merged in without overriding user-specified or default accept headers.

Patch Changes

  • #12673 cee90ab Thanks @phryneas! - Fixed a bug in PersistedQueryLink where the persistedQuery extension would still be sent after a PersistedQueryNotSupported if includeExtensions was enabled on HttpLink.

@apollo/client@4.0.0-alpha.21

10 Jun 18:03
7187540
Compare
Choose a tag to compare
Pre-release

Major Changes

  • #12686 dc4b1d0 Thanks @jerelmiller! - A @defer query that has not yet finished streaming is now considered loading and thus the loading flag will be true until the response has completed. A new NetworkStatus.streaming value has been introduced and will be set as the networkStatus while the response is streaming.

  • #12685 3b74800 Thanks @jerelmiller! - Remove the check and warning for cache.fragmentMatches when applying data masking. cache.fragmentMatches is a required API and data masking may crash when cache.fragmentMatches does not exist.

  • #12684 e697431 Thanks @jerelmiller! - Remove context from useLazyQuery hook options. If used, context must now be provided to the execute function. context will reset to {} if not provided as an option to execute.

@apollo/client@4.0.0-alpha.20

06 Jun 15:49
ad641e4
Compare
Choose a tag to compare
Pre-release

Major Changes

  • #12675 8f1d974 Thanks @phryneas! - ObservableQuery no longer has a queryId property.
    ApolloClient.getObservableQueries no longer returns a Map<string, ObservableQuery>, but a Set<ObservableQuery>.

  • #12647 a70fac6 Thanks @phryneas! - ObservableQuerys will now only be registered with the ApolloClient while they
    have subscribers.

    That means that ApolloClient.getObservableQueries and ApolloClient.refetchQueries
    will only be able to return/refetch queries that have at least one subscriber.

    This changes the previous meaning of active and inactive queries:

    • inactive queries are queries with a subscriber that are skipped from a
      React hook or have a fetchPolicy of standby
    • active queries are queries with at least one subscriber that are not skipped or in standby.

    ObservableQuerys without subscribers but with an active ongoing network request
    (e.g. caused by calling reobserve) will be handled as if they had a subscriber
    for the duration of the query.

  • #12678 91a876b Thanks @jerelmiller! - queryRefs created by preloadQuery no longer have a .toPromise() function. Instead preloadQuery now has a toPromise function that accepts a queryRef and will resolve when the underlying promise has been resolved.

    const queryRef = preloadQuery(query, options);
    
    - await queryRef.toPromise();
    + await preloadQuery.toPromise(queryRef);
  • #12647 a70fac6 Thanks @phryneas! - ApolloClient.stop() now cleans up more agressively to prevent memory leaks:

    • It will now unsubscribe all active ObservableQuery instances by emitting a completed event.
    • It will now reject all currently running queries with "QueryManager stopped while query was in flight".
    • It will remove all queryRefs from the suspense cache.

Minor Changes

  • #12647 a70fac6 Thanks @phryneas! - Added a new .stop function on ObservableQuery.
    Calling this method will unsubscribe all current subscribers by sending a complete event from the observable and tear down the ObservableQuery.

@apollo/client@4.0.0-alpha.19

05 Jun 17:13
ca2d63b
Compare
Choose a tag to compare
Pre-release

Major Changes

  • #12663 01512f2 Thanks @jerelmiller! - Unsubscribing from an ObservableQuery before a value has been emitted will remove the query from the tracked list of queries and will no longer be eligible for query deduplication.

Minor Changes

  • #12663 01512f2 Thanks @jerelmiller! - Subscriptions created by client.subscribe() can now be restarted. Restarting a subscription will terminate the connection with the link chain and recreate the request. Restarts also work across deduplicated subscriptions so calling restart on an observable who's request is deduplicated will restart the connection for each observable.

    const observable = client.subscribe({ query: subscription });
    
    // Restart the connection to the link
    observable.restart();
  • #12663 01512f2 Thanks @jerelmiller! - Deduplicating subscription operations is now supported. Previously it was possible to deduplicate a subscription only if the new subscription was created before a previously subscribed subscription emitted any values. As soon as a value was emitted from a subscription, new subscriptions would create new connections. Deduplication is now active for as long as a subscription connection is open (i.e. the source observable hasn't emitted a complete or error notification yet.)

    To disable deduplication and force a new connection, use the queryDeduplication option in context like you would a query operation.

    As a result of this change, calling the restart function returned from useSubscription will now restart the connection on deduplicated subscriptions.

@apollo/client@4.0.0-alpha.18

05 Jun 00:04
85dc598
Compare
Choose a tag to compare
Pre-release

Minor Changes

  • #12670 0a880ea Thanks @phryneas! - Provide a mechanism to override the DataMasking types.

    Up until now, our types Masked, MaskedDocumentNode, FragmentType, MaybeMasked and Unmasked would assume that you are stictly using the type output format of GraphQL Codegen.

    With this change, you can now modify the behaviour of those types if you use a different form of codegen that produces different types for your queries.

    A simple implementation that would override the Masked type to remove all fields starting with _ from a type would look like this:

    // your actual implementation of `Masked`
    type CustomMaskedImplementation<TData> = {
      [K in keyof TData as K extends `_${string}` ? never : K]: TData[K];
    };
    
    import { HKT } from "@apollo/client/utilities";
    // transform this type into a higher kinded type that can be evaulated at a later time
    interface CustomMaskedType extends HKT {
      arg1: unknown; // TData
      return: CustomMaskedImplementation<this["arg1"]>;
    }
    
    // create an "implementation interface" for the types you want to override
    export interface CustomDataMaskingImplementation {
      Masked: CustomMaskedType;
      // other possible keys: `MaskedDocumentNode`, `FragmentType`, `MaybeMasked` and `Unmasked`
    }

    then you would use that CustomDataMaskingImplementation interface in your project to extend the DataMasking interface exported by @apollo/client with it's functionality:

    declare module "@apollo/client" {
      export interface DataMasking extends CustomDataMaskingImplementation {}
    }

    After that, all internal usage of Masked in Apollo Client as well as all usage in your code base will use the new CustomMaskedType implementation.

    If you don't specify overrides, Apollo Client will still default to the GraphQL Codegen data masking implementation.
    The types for that are also explicitly exported as the GraphQLCodegenDataMasking namespace in @apollo/client/masking.

@apollo/client@4.0.0-alpha.17

03 Jun 15:43
3f58bf3
Compare
Choose a tag to compare
Pre-release

Major Changes

  • #12649 0be92ad Thanks @jerelmiller! - The TData generic provided to types that return a dataState property is now modified by the given DataState generic instead of passing a modified TData type. For example, a QueryRef that could return partial data was defined as QueryRef<DeepPartial<TData>, TVariables>. Now TData should be provided unmodified and a set of allowed states should be given instead: QueryRef<TData, TVariables, 'complete' | 'streaming' | 'partial'>.

    To migrate, use the following guide to replace your type with the right set of states (all types listed below are changed the same way):

    - QueryRef<TData, TVariables>
    // `QueryRef`'s default is 'complete' | 'streaming' so this can also be left alone if you prefer
    // All other types affected by this change default to all states
    + QueryRef<TData, TVariables>
    + QueryRef<TData, TVariables, 'complete' | 'streaming'>
    
    - QueryRef<TData | undefined, TVariables>
    + QueryRef<TData, TVariables, 'complete' | 'streaming' | 'empty'>
    
    - QueryRef<DeepPartial<TData>, TVariables>
    + QueryRef<TData, TVariables, 'complete' | 'streaming' | 'partial'>
    
    - QueryRef<DeepPartial<TData> | undefined, TVariables>
    + QueryRef<TData, TVariables, 'complete' | 'streaming' | 'partial' | 'empty'>

    The following types are affected. Provide the allowed dataState values to the TDataState generic:

    • ApolloQueryResult
    • QueryRef
    • PreloadedQueryRef
    • useLazyQuery.Result
    • useQuery.Result
    • useReadQuery.Result
    • useSuspenseQuery.Result

    All *QueryRef types default to complete | streaming states while the rest of the types default to 'complete' | 'streaming' | 'partial' | 'empty' states. You shouldn't need to provide the states unless you need to either allow for partial data/empty values (*QueryRef) or a restricted set of states.

  • #12649 0be92ad Thanks @jerelmiller! - Remove the deprecated QueryReference type. Please use QueryRef instead.

  • #12633 9bfb51f Thanks @phryneas! - If the execute function of useLazyQuery is executed, previously started queries
    from the same useLazyQuery usage will be rejected with an AbortError unless
    .retain() is called on the promise returned by previous execute calls.

    Please keep in mind that useLazyQuery is primarily meant as a means to synchronize
    your component to the status of a query and that it's purpose it not to make a
    series of network calls.
    If you plan on making a series of network calls without the need to synchronize
    the result with your component, consider using ApolloClient.query instead.

Minor Changes

  • #12633 9bfb51f Thanks @phryneas! - ObservableQuery.refetch and ObservableQuery.reobserve and the execute function of useLazyQuery now return a
    ResultPromise with an additional .retain method.
    If this method is called, the underlying network operation will be kept running even if the ObservableQuery itself does
    not require the result anymore, and the Promise will resolve with the final result instead of resolving with an intermediate
    result in the case of early cancellation.

  • #12649 0be92ad Thanks @jerelmiller! - Add a new dataState property that determines the completeness of the data property. dataState helps narrow the type of data. dataState is now emitted from ObservableQuery and returned from all React hooks that return a data property.

    The dataState values are:

    • empty: No data could be fulfilled from the cache or the result is incomplete. data is undefined.
    • partial: Some data could be fulfilled from the cache but data is incomplete. This is only possible when returnPartialData is true.
    • streaming: data is incomplete as a result of a deferred query and the result is still streaming in.
    • complete: data is a fully satisfied query result fulfilled either from the cache or network.

    Example:

    const { data, dataState } = useQuery<TData>(query);
    
    if (dataState === "empty") {
      expectTypeOf(data).toEqualTypeOf<undefined>();
    }
    
    if (dataState === "partial") {
      expectTypeOf(data).toEqualTypeOf<DeepPartial<TData>>();
    }
    
    if (dataState === "streaming") {
      expectTypeOf(data).toEqualTypeOf<TData>();
    }
    
    if (dataState === "complete") {
      expectTypeOf(data).toEqualTypeOf<TData>();
    }

@apollo/client@4.0.0-alpha.16

28 May 22:54
Compare
Choose a tag to compare
Pre-release

Major Changes

  • #12644 fe2f005 Thanks @jerelmiller! - Replace the result property on ServerError with bodyText. bodyText is set to the raw string body. HttpLink and BatchHttpLink no longer try and parse the response body as JSON when a ServerError is thrown.

  • #12644 fe2f005 Thanks @jerelmiller! - More strictly adhere to the GraphQL over HTTP spec. This change adds support for the application/graphql-response+json media type and modifies the behavior of the application/json media type.

    • The client will parse the response as a well-formed GraphQL response when the server encodes content-type using application/graphql-response+json with a non-200 status code.
    • The client will now throw a ServerError when the server encodes content-type using application/json and returns a non-200 status code.
    • The client will now throw a ServerError when the server encodes using any other content-type and returns a non-200 status code.

    NOTE: If you use a testing utility to mock requests in your test, you may experience different behavior than production if your testing utility responds as application/json but your production server responds as application/graphql-response+json. If a content-type header is not set, the client interprets the response as application/json.

  • #12644 fe2f005 Thanks @jerelmiller! - Change the default Accept header to application/graphql-response+json,application/json;q=0.9.

  • #12644 fe2f005 Thanks @jerelmiller! - HttpLink and BatchHttpLink no longer emit a next notification with the JSON-parsed response body when a well-formed GraphQL response is returned and a ServerError is thrown.