Releases: apollographql/apollo-client
@apollo/client-graphql-codegen@1.0.0-rc.0
Major Changes
- #12723
1f9ed72
Thanks @jerelmiller! - Version bump only for codegen to release asrc
.
@apollo/client@4.0.0-rc.0
Major Changes
- #12718
ecfc02a
Thanks @jerelmiller! - Version bump only to release latest asrc
.
@apollo/client@4.0.0-alpha.23
Major Changes
-
#12712
bbb2b61
Thanks @jerelmiller! - An error is now thrown when trying to callfetchMore
on acache-only
query. -
#12712
bbb2b61
Thanks @jerelmiller! -cache-only
queries are no longer refetched when callingclient.reFetchObservableQueries
whenincludeStandby
istrue
. -
#12705
a60f411
Thanks @jerelmiller! -cache-only
queries will now initialize withloading: false
andnetworkStatus: NetworkStatus.ready
when there is no data in the cache.This means
useQuery
will no longer render a short initial loading state before renderingloading: false
andObservableQuery.getCurrentResult()
will now returnloading: false
immediately. -
#12712
bbb2b61
Thanks @jerelmiller! -cache-only
queries are now excluded fromclient.refetchQueries
in all situations.cache-only
queries affected byupdateCache
are also excluded fromrefetchQueries
whenonQueryUpdated
is not provided. -
#12681
b181f98
Thanks @jerelmiller! - Changing most options when rerenderinguseQuery
will no longer trigger areobserve
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 fromstandby
-
#12714
0e39469
Thanks @phryneas! - Rework option handling forfetchMore
.- Previously, if the
query
option was specified, no options would be inherited
from the underlyingObservableQuery
.
Now, even ifquery
is specified, all unspecified options except forvariables
will be inherited from the underlyingObservableQuery
. - If
query
is not specified,variables
will still be shallowly merged with thevariables
of the underlyingObservableQuery
. If aquery
option is specified, thevariables
passed tofetchMore
are used instead. errorPolicy
offetchMore
will now always default to"none"
instead of inherited from theObservableQuery
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 anerrorPolicy
tofetchMore
to override the default.
- Previously, if the
-
#12700
8e96e08
Thanks @phryneas! - Added a newStreaming
type that will markdata
in results whiledataStatus
is"streaming"
.Streaming<TData>
defaults toTData
, 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
withDeepPartial<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! - TheErrorResponse
object passed to thedisable
andretry
callback options provided tocreatePersistedQueryLink
no longer provides separategraphQLErrors
andnetworkError
properties and instead have been combined to a singleerror
property of typeErrorLike
.// 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 toresult
.createPersistedQueryLink({ - disable: ({ response }) => { + disable: ({ result }) => { // ... handle GraphQL errors } } });
-
#12712
bbb2b61
Thanks @jerelmiller! -cache-only
queries no longer poll when apollInterval
is set. Instead a warning is now emitted that polling has no effect. If thefetchPolicy
is changed tocache-only
after polling is already active, polling is stopped. -
#12704
45dba43
Thanks @jerelmiller! - Theresponse
property inonError
link has been renamed toresult
.- 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 anextensions
property toCombinedGraphQLErrors
to capture any extensions from the original response. -
#12700
8e96e08
Thanks @phryneas! - The callback function that can be passed to theApolloClient.mutate
refetchQueries
option will now receive aFormattedExecutionResult
with an
additionaldataState
option that describes if the result is"streaming"
or"complete"
.
This indicates whether thedata
value is of typeUnmasked<TData>
(if"complete"
)Streaming<Unmasked<TData>>
(if"streaming"
)
-
#12714
0e39469
Thanks @phryneas! - Allow passingerrorPolicy
option tofetchMore
and change default value to "none". -
#12714
0e39469
Thanks @phryneas! - TheFetchMoreQueryOptions
type has been inlined intoFetchMoreOptions
, and
FetchMoreQueryOptions
has been removed. -
#12700 [`8e96...
@apollo/client@4.0.0-alpha.22
Major Changes
-
#12673
cee90ab
Thanks @phryneas! - TheincludeExtensions
option ofHttpLink
andBatchHttpLink
now defaults
totrue
.If
includeExtensions
istrue
, butextensions
is not set or empty, extensions
will not be included in outgoing requests. -
#12673
cee90ab
Thanks @phryneas! - TheApolloClient
constructor optionsname
andversion
that are used to
configure the client awareness feature have moved onto aclientAwareness
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
andBatchHttpLink
will now per default send information about the
client library you are using inextensions
.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
orBatchHttpLink
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 newClientAwarenessLink
.This link is already included in
HttpLink
andBatchHttpLink
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 toHttpLink
andBatchHttpLink
, you can useBaseHttpLink
orBaseBatchHttpLink
instead.
These links come without theClientAwarenessLink
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 anaccept
option toHttpOptions
that allows to add additionalAccept
headers to be merged in without overriding user-specified or default accept headers.
Patch Changes
@apollo/client@4.0.0-alpha.21
Major Changes
-
#12686
dc4b1d0
Thanks @jerelmiller! - A@defer
query that has not yet finished streaming is now considered loading and thus theloading
flag will betrue
until the response has completed. A newNetworkStatus.streaming
value has been introduced and will be set as thenetworkStatus
while the response is streaming. -
#12685
3b74800
Thanks @jerelmiller! - Remove the check and warning forcache.fragmentMatches
when applying data masking.cache.fragmentMatches
is a required API and data masking may crash whencache.fragmentMatches
does not exist. -
#12684
e697431
Thanks @jerelmiller! - Removecontext
fromuseLazyQuery
hook options. If used,context
must now be provided to theexecute
function.context
will reset to{}
if not provided as an option toexecute
.
@apollo/client@4.0.0-alpha.20
Major Changes
-
#12675
8f1d974
Thanks @phryneas! -ObservableQuery
no longer has aqueryId
property.
ApolloClient.getObservableQueries
no longer returns aMap<string, ObservableQuery>
, but aSet<ObservableQuery>
. -
#12647
a70fac6
Thanks @phryneas! -ObservableQuery
s will now only be registered with theApolloClient
while they
have subscribers.That means that
ApolloClient.getObservableQueries
andApolloClient.refetchQueries
will only be able to return/refetch queries that have at least one subscriber.This changes the previous meaning of
active
andinactive
queries:inactive
queries are queries with a subscriber that are skipped from a
React hook or have afetchPolicy
ofstandby
active
queries are queries with at least one subscriber that are not skipped or instandby
.
ObservableQuery
s without subscribers but with an active ongoing network request
(e.g. caused by callingreobserve
) will be handled as if they had a subscriber
for the duration of the query. -
#12678
91a876b
Thanks @jerelmiller! -queryRef
s created bypreloadQuery
no longer have a.toPromise()
function. InsteadpreloadQuery
now has atoPromise
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 acompleted
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.
- It will now unsubscribe all active
Minor Changes
@apollo/client@4.0.0-alpha.19
Major Changes
- #12663
01512f2
Thanks @jerelmiller! - Unsubscribing from anObservableQuery
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 byclient.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 callingrestart
on anobservable
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 acomplete
orerror
notification yet.)To disable deduplication and force a new connection, use the
queryDeduplication
option incontext
like you would a query operation.As a result of this change, calling the
restart
function returned fromuseSubscription
will now restart the connection on deduplicated subscriptions.
@apollo/client@4.0.0-alpha.18
Minor Changes
-
#12670
0a880ea
Thanks @phryneas! - Provide a mechanism to override the DataMasking types.Up until now, our types
Masked
,MaskedDocumentNode
,FragmentType
,MaybeMasked
andUnmasked
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 theDataMasking
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 newCustomMaskedType
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 theGraphQLCodegenDataMasking
namespace in@apollo/client/masking
.
@apollo/client@4.0.0-alpha.17
Major Changes
-
#12649
0be92ad
Thanks @jerelmiller! - TheTData
generic provided to types that return adataState
property is now modified by the givenDataState
generic instead of passing a modifiedTData
type. For example, aQueryRef
that could return partial data was defined asQueryRef<DeepPartial<TData>, TVariables>
. NowTData
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 theTDataState
generic:ApolloQueryResult
QueryRef
PreloadedQueryRef
useLazyQuery.Result
useQuery.Result
useReadQuery.Result
useSuspenseQuery.Result
All
*QueryRef
types default tocomplete | 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 deprecatedQueryReference
type. Please useQueryRef
instead. -
#12633
9bfb51f
Thanks @phryneas! - If theexecute
function ofuseLazyQuery
is executed, previously started queries
from the sameuseLazyQuery
usage will be rejected with anAbortError
unless
.retain()
is called on the promise returned by previousexecute
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 usingApolloClient.query
instead.
Minor Changes
-
#12633
9bfb51f
Thanks @phryneas! -ObservableQuery.refetch
andObservableQuery.reobserve
and theexecute
function ofuseLazyQuery
now return a
ResultPromise
with an additional.retain
method.
If this method is called, the underlying network operation will be kept running even if theObservableQuery
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 newdataState
property that determines the completeness of thedata
property.dataState
helps narrow the type ofdata
.dataState
is now emitted fromObservableQuery
and returned from all React hooks that return adata
property.The
dataState
values are:empty
: No data could be fulfilled from the cache or the result is incomplete.data
isundefined
.partial
: Some data could be fulfilled from the cache butdata
is incomplete. This is only possible whenreturnPartialData
istrue
.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
Major Changes
-
#12644
fe2f005
Thanks @jerelmiller! - Replace theresult
property onServerError
withbodyText
.bodyText
is set to the raw string body.HttpLink
andBatchHttpLink
no longer try and parse the response body as JSON when aServerError
is thrown. -
#12644
fe2f005
Thanks @jerelmiller! - More strictly adhere to the GraphQL over HTTP spec. This change adds support for theapplication/graphql-response+json
media type and modifies the behavior of theapplication/json
media type.- The client will parse the response as a well-formed GraphQL response when the server encodes
content-type
usingapplication/graphql-response+json
with a non-200 status code. - The client will now throw a
ServerError
when the server encodescontent-type
usingapplication/json
and returns a non-200 status code. - The client will now throw a
ServerError
when the server encodes using any othercontent-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 asapplication/graphql-response+json
. If acontent-type
header is not set, the client interprets the response asapplication/json
. - The client will parse the response as a well-formed GraphQL response when the server encodes
-
#12644
fe2f005
Thanks @jerelmiller! - Change the defaultAccept
header toapplication/graphql-response+json,application/json;q=0.9
. -
#12644
fe2f005
Thanks @jerelmiller! -HttpLink
andBatchHttpLink
no longer emit anext
notification with the JSON-parsed response body when a well-formed GraphQL response is returned and aServerError
is thrown.