#1346437f700e Thanks @jerelmiller! - Fix an issue where useLazyQuery did not rerender with new variables until the network request had completed when calling execute with new variables while a request was already in-flight.
#1344724133fe Thanks @jerelmiller! - Field policies and inputObjects can now tell the cache whether a field is a list of scalars or a scalar whose value is an array. Previously all arrays were iterated and only the inner type was provided to the scalar parse/serialize functions.
This required some breaking changes from previous prerelease versions:
The field policy scalar option and inputObjects type string now use GraphQL list syntax to mark a field as a list of scalars
The abstract cache.getScalarForField is now cache.getScalarTypeForField and is expected to return the string representing the scalar type rather than the Scalar instance
newInMemoryCache({scalars:{DateTime: newScalar(/*...*/),},inputObjects:{EventFilter:{fields:{// Previously only the scalar type was provided
datesBefore:"DateTime",// List syntax now required
datesAfter:"[DateTime]",dates2d:"[[DateTime]]",},},},typePolicies:{Event:{fields:{// Previously only the scalar type was provided
datesBefore:{scalar:"DateTime",},// List syntax now required
datesAfter:{scalar:"[DateTime]",},dates2d:{scalar:"[[DateTime]]",},},},},});
Now it's possible to handle scalars that are represented by arrays:
constdateTimeRangeScalar=newScalar<[string,string],{start: Date;end: Date}>({parse:([start,end])=>({start: newDate(start),end: newDate(end),}),serialize:(range)=>[range.start.toISOString(),range.end.toISOString()],is:(value)=>!Array.isArray(value),});constcache=newInMemoryCache({scalars:{DateTimeRange: dateTimeRangeScalar,},typePolicies:{Event:{fields:{range:{scalar:"DateTimeRange",},},},},});constquery=gql`
query {
event {
range
}
}
`;cache.writeQuery({query,data:{event:{__typename:"Event",// Server returns DateTimeRange as a JSON array
range:["2024-01-01T00:00:00Z","2024-06-01T00:00:00Z"],},},});const{data}=useQuery(query);// => { event: { __typename: "Event", range: { start: Date, end: Date } } }
#133240abd8de Thanks @jerelmiller! - Fix the accuracy of dataState in complex incremental streaming scenarios, especially when combined with returnPartialData: true.
Prior to this change, all intermediate chunks used for both @defer and @stream directives returned a dataState of streaming, regardless of whether the actual data shape fit the definition of the streaming data state. The streaming data state represents an incomplete incremental response where the only holes in the data occur at @defer boundaries.
Let's use the following example of where the previous dataState fell down when combined with returnPartialData.
This data is not complete because recipient.email is missing. This data is also not streaming because the data requirements in the @defer boundary are partially fulfilled due to the existence of recipient. This could lead to runtime crashes on recipient.email if you use the existence of recipient to detect whether data in the @defer boundary has streamed in or not. This change now accurately reports this as partial to ensure the field is marked as a partial field in recipient.
Scenario 2: partial data written to the cache that fulfills the data requirements of the @defer boundary
Let's say the cache contained the following partial data:
In this case, the combination of the first chunk and the partial data in the cache now fulfills the data requirements of the query. Even though the server is still streaming data (NetworkStatus.streaming), we can report this as dataState: "complete" since it is safe to access data on all fields.
This change also means @stream queries by definition fulfill the data requirements of the query after the first chunk arrives since @stream operates on lists and contains no data holes. @stream queries now accurately report dataState as complete or partial, depending on whether the list mixes partial data with streamed list items.
As a result of this change, some cases where you'd previously see dataState reported as "streaming" are now reported as partial or complete.
If you use dataState to determine whether an incremental request is still in-flight, please use networkStatus instead to check for NetworkStatus.streaming. dataState is type narrowing feature and not intended to report the network status.
#132747b10078 Thanks @jerelmiller! - Adds Scalar.fromGraphQLScalarType helper to create a Scalar instance from an existing graphql.js GraphQLScalarType.
#13270d080f11 Thanks @jerelmiller! - Adds the plumbing and types implementation for declaring custom scalars and configuring custom scalars in InMemoryCache.
You can declare custom scalar types with declaration merging on the ApolloCache.Scalars interface:
#13250bad7035 Thanks @jerelmiller! - Add the ability to define the cache type for the client. client.cache currently returns ApolloCache as the cache type regardless of what cache you've provided to ApolloClient.
Declare the cache type using the cache property in the TypeOverrides interface to set the cache implementation used for the client.
[!NOTE]
Setting a cache type enforces that cache type in the cache option for the ApolloClient constructor.
#13406bd74ccb Thanks @jerelmiller! - Emit a development-only warning when a feud is detected between queries that overwrite each other's data. This should make it easier to detect when you need to select a key field or add a merge function to a field policy.
#1339090e338c Thanks @jerelmiller! - Fix issue where sibling @defer fragments were pruned incorrectly when at least one of the @defer fragments wasn't delivered.
As a result of this change, a label argument is now added to all outgoing @defer directives when using the GraphQL17Alpha9Handler in order to disambiguate the @defer fragments from each other.
#13416f2d5d5a Thanks @jerelmiller! - Add GraphQLCodegenIncremental type overrides that assemble GraphQL Codegen @defer operation types when dataState is "complete".
#133860be8fd8 Thanks @atharv-sys32! - Support skipToken with useSubscription to provide a more type-safe way to skip subscription execution with required variables.
import{skipToken,useSubscription}from"@apollo/client/react";// Use `skipToken` in place of `skip: true` for better type safety
// for required variables
const{data}=useSubscription(SUBSCRIPTION,id?{variables:{id}}:skipToken);
#133372df711f Thanks @jcostello-atlassian! - Allow overriding the from input of useFragment, useSuspenseFragment, readFragment, writeFragment and related fragment APIs via a new FromOptionValue key on the TypeOverrides interface.
By default, from continues to accept StoreObject | Reference | FragmentType<TData> | string. Apps can now supply a stricter policy (for example, requiring __typename and disallowing nullish identifier values) without affecting StoreObject, cache.identify, cache.modify or optimistic writes.
// apollo.d.ts
import"@apollo/client";importtype{HKT,StoreValue}from"@apollo/client/utilities";typeStrictFrom<TDataextends{__typename:string}>=|{// the `__typename` has to match the one of the fragment type
__typename: TData["__typename"];// `& {}` forces values to be "defined" so an explicit `undefined`
// (as well as `null`) is rejected.
[key: string]:Exclude<StoreValue,null|undefined>&{};}|{__ref: string}|string|null;interfaceStrictFromHKTextendsHKT{arg1:{__typename: string};// TData
return:StrictFrom<this["arg1"]>;}declaremodule"@apollo/client"{exportinterfaceTypeOverrides{FromOptionValue: StrictFromHKT;}}
#13405f923ab4 Thanks @jerelmiller! - Field policy read and merge functions are now ignored when the field policy configures the scalar option. If a read or merge function is provided alongside scalar, a development-only warning is emitted.
#13393434d25f Thanks @jerelmiller! - Change when @defer fragments and @stream fields are pruned for cache-first and cache-and-network fetch policies to better match the network when the initial value contained a partial result:
cache-first: prune undelivered @defer fragments or @stream items when the result is fetched from the network due to a partial result
cache-and-network: prune undelivered @defer fragments or @stream items if the initial cache value was partial. If the first value emitted from the cache is complete, the results will not be pruned.
This makes the emitted results more predictable by following what the network has delivered and avoids some ambiguity in other edge cases.
For example, with a cache-first fetch policy where all @defer fields are written to the cache, but a non-deferred field is partial, the values emitted from the client previously looked like the following:
query{user{idname...@defer{email}}}
// data written to the cache is missing name
{user:{id: 1,email:"user.cache@example.com"}}// 1. empty because the result is partial
{data: undefined,dataState:"empty",...}// 2. returns all data because the cache contains a value for email
{data:{user: 1,name:"User",email:"user.cache@example.com"},dataState:"complete"}// 3. email updated from the server
{data:{user: 1,name:"User",email:"user.network@example.com"},dataState:"complete"}
Here the result is confusing because the initial value returned from the query was undefined, yet a complete result was returned after the initial chunk from the network returned (which did not contain email).
The cache values are now pruned if the network hasn't delivered them yet:
// 1. empty because the result is partial
{data: undefined,dataState:"empty"}// 2. email hasn't been delivered by the network so it gets pruned
{data:{user: 1,name:"User"},dataState:"streaming"}// 3. full result returned after the network streams the email field
{data:{user: 1,name:"User",email:"user.network@example.com"},dataState:"complete"}
This is especially helpful in situations where @defer boundaries that are never delivered due to errors prevent an awkward situation where the client would otherwise have to choose whether to serve the stale cache result from the cache, or prune the undelivered fragment on the final chunk.
#132706031987 Thanks @jerelmiller! - Adds a scalar option to InMemoryCache field policies that tells the cache which scalar to use when parsing or serializing the field value.
import{Scalar}from"@apollo/client";newInMemoryCache({scalars:{DateTime: newScalar({parse:(dateString)=>newDate(dateString),serialize:(date)=>date.toISOString(),}),},typePolicies:{Event:{fields:{startTime:{// Parse this field using the DateTime scalar
scalar:"DateTime",},},},},});
This scalar definition is now used to properly parse or serialize the field value for cache reads and writes as well as cache.extract() and cache.restore().
#132730886de1 Thanks @jerelmiller! - Automatically serialize variables that include custom scalar values. This includes cache reads and writes as well as requests to the network.
For more complex input objects, a new inputObjects option is available to InMemoryCache that specifies where nested scalar fields are found.
constcache=newInMemoryCache({scalars:{DateTime: newScalar({parse:(value)=>newDate(value),serialize:(value)=>value.toISOString(),is:(value)=>valueinstanceofDate,}),},inputObjects:{EventFilter:{fields:{date:"DateTime",},},},});constclient=newApolloClient({cache,link});awaitclient.query({query: gql`
query Event($filter: EventFilter!) {
event(filter: $filter) {
name
}
}
`,variables:{filter:{date: newDate("2026-01-01T00:00:00.000Z"),},},});// The link receives:
// { filter: { date: "2026-01-01T00:00:00.000Z" } }
#13424d2bca2e Thanks @jerelmiller! - Remove the custom NoInfer type utility in favor of the native NoInfer introduced in TypeScript 5.4.
#13270d080f11 Thanks @jerelmiller! - Adds the getScalar abstract method to ApolloCache that cache subclasses override to provide scalar behavior to Apollo Client. Defaults to unconditionally return undefined if not specified.
#13406bd74ccb Thanks @jerelmiller! - Fixes an issue where cache feuds between queries selecting incompatible non-normalized data could return untransformed network values.
Apollo Client now always writes network results to the cache before delivering them, ensuring custom scalars and field read functions are applied. To prevent repeated refetches when competing queries repeatedly make each other's cache results incomplete, Apollo Client stops automatically refetching a query after it sees the same incomplete result again.
This may add one network request in these cache-feud scenarios.
Patch Changes
#134087a5164d Thanks @jerelmiller! - Fix dataState to report "streaming" instead of "partial" when returnPartialData is true and the cache result is missing only @defer fields.
#133819c73762 Thanks @jerelmiller! - Fix an issue where a network-only query leaked partial cache data for @defer fragments that were not delivered by the network due to an error that bubbled to the @defer fragment boundary.
#1339090e338c Thanks @jerelmiller! - Fix an issue where a sibling non-deferred fragment might be accidentally pruned when the @defer fragment hadn't been delivered.
#13442ed033d4 Thanks @jerelmiller! - Remove the optional modifier from the variables property provided to the update function in client.mutate and useMutation. variables is always a defined object, even when variables are not provided to the mutation.
#133240abd8de Thanks @jerelmiller! - Fix an issue where field read functions were not applied to intermediate results while streaming @defer responses. cache.diff ran the read functions, but the transformed values were only applied to the emitted result when the updated cache result was considered complete. Intermediate chunks whose only holes were at @defer boundaries now correctly return the result of field read functions.
#13403aaff7a8 Thanks @jerelmiller! - Fix issue where the wrong dataState was returned when there was nothing written to the cache and a @defer fragment was marked pending.
#133477d543d6 Thanks @jerelmiller! - Fix an issue where network-only incremental queries could cause cache data to leak into the emitted result when a @defer or @stream boundary already had complete data in the cache. Cache data inside pending @defer objects and @stream arrays are now pruned so that only completed @defer or @stream boundaries are returned.
NOTE: This change only applies to InMemoryCache when using GraphQL17Alpha9Handler.
#133291d581d2 Thanks @AmariahAK! - Cache diffs for incomplete queries no longer pay the cost of building a full MissingFieldError when the missing property is not accessed. The error object is now only constructed when the missing property is accessed the first time. This improves performance by avoiding a V8 stack capture when missing is ignored entirely.
As an additional small performance improvement, JSON.stringify is no longer used in the error message on objects whose cache ID is known. JSON.stringify is only used for non-normalized objects.
#133819c73762 Thanks @jerelmiller! - Fix an issue where a @defer query reported the dataState as complete instead of streaming when an error occurs on a deferred field that bubbled to the defer boundary.
#133240abd8de Thanks @jerelmiller! - Fix an issue with @stream queries when using returnPartialData: true where the streamed list was truncated after the first incremental chunk when the list contained partial cache data. The list is no longer truncated and partial list items are now retained as incremental chunks arrive. The dataState is now reported as partial until the server has streamed enough of the list so that each list item fully satisfies the query.
This change also updates @stream queries so that they reported with dataState: "complete instead of "streaming" since it is safe to access all fields in the response.
#133732551937 Thanks @jerelmiller! - Fix an issue where a cache write in the middle of polling would remain as the query value if future poll requests returned deep equal results to previous polling results.
#1344877e1e35 Thanks @jerelmiller! - Mark skip as deprecated in useQuery and useSubscription now that both of these hooks support skipToken.
#13403aaff7a8 Thanks @jerelmiller! - Fix issue where setting returnPartialData: true might report the wrong dataState when partial data was written to the cache and @defer fragments were pending.
#133477d543d6 Thanks @jerelmiller! - Fix an issue where partial cache data could leak into intermediate incremental results. This could cause runtime crashes if you relied on the presence of values to determine whether the @defer data had streamed in or not.
#133819c73762 Thanks @jerelmiller! - Fix an invariant error thrown when a @defer boundary received a payload after it had already been marked complete.
#13268419e2b5 Thanks @DaleSeo! - Align the remaining cache generic constraints with Cache.Implementation. The deprecated React mutation types (MutationHookOptions, MutationFunctionOptions, MutationTuple) and the internal InternalRefetchQueriesOptions and QueryInfo types still constrained their cache type parameter to ApolloCache, so they now match the rest of the overridable cache API.
#133983dd3e9a Thanks @phryneas! - Fix type signature of some DocumentationTypes to fix their display in our documentation.
#13392d4f0771 Thanks @jerelmiller! - Add a development-only warning when a network result is written to the cache but reading the query back from the cache returns a partial result. This usually points at a merge or read function that did not repair missing fields in the cache, which prevents Apollo Client from applying the cache result to the data received by the network.
#13385bfb674e Thanks @jerelmiller! - Fix accidental widening of the client.mutate return type when optimisticResponse was present.
#13382365373e Thanks @jerelmiller! - Fix result types widened when a query's variables had constant types (e.g. TypedDocumentNode<Data, { type: "main" }>). This caused options such as returnPartialData or errorPolicy to be reported as their widened types (e.g. boolean, ErrorPolicy) instead of the value that was passed which returned the wrong data and dataState types.
#13382365373e Thanks @jerelmiller! - Fix issue where unknown options were permitted by TypeScript when passed alongside a valid option to APIs with modern signatures.
#133835840f50 Thanks @jerelmiller! - Update the return type of refetch, fetchMore and useLazyQuery's execute function on the provided errorPolicy. Previously these APIs all used the default type which typed data as TData | undefined and error as ErrorLike | undefined.
#133642f383e7 Thanks @atharv-sys32! - Fix a bug where GraphQL variable default values were not applied during cache reads when variables with defaults were explicitly set to undefined. This caused @include/@skip directives to throw "Invalid variable referenced" errors when the variable was passed as undefined instead of being omitted entirely.
#133672b39cc8 Thanks @jerelmiller! - Fix an issue where some @export queries would not react to cache updates when the fields keyed by exported variables were updated.
#13349501a33b Thanks @jerelmiller! - Prevent the setTimeout in connectToDevtools that shows the devtools suggestion from firing when the user agent does not match Chrome or Firefox. This check was previously done inside the setTimeout which meant the timer was scheduled for environments where we'd never show the message anyways. For test environments, this could cause flaky tests when that setTimeout outlived the tests and ran after any virtual DOM was torn down and removed.
#13315a406cc9 Thanks @fallintoplace! - Prevent relay multipart subscriptions from issuing a fetch request after serializing the request body fails.
#13307abd0781 Thanks @wolfie! - Speed up cache writes by avoiding a full AST visit of every written field to detect @stream. The check now runs only when the result carries stream info, and only inspects the field node's own directives. As a result, fields that merely contain @stream on a nested field are no longer treated as streamed themselves and now overwrite existing lists like regular fields instead of merging chunk-wise.
#13281e4df809 Thanks @jerelmiller! - Fixes an issue where client.readFragment and client.readQuery ignored the optimistic option when passed in the options object.
#13184c207b88 Thanks @audrius-savickas! - Preserve referential equality of masked data on refetch when the result is deeply equal to the previous result.
#13132f3ce805 Thanks @phryneas! - Introduce "classic" and "modern" method and hook signatures.
Apollo Client 4.2 introduces two signature styles for methods and hooks. All signatures previously present are now "classic" signatures, and a new set of "modern" signatures are added alongside them.
Classic signatures are the default and are identical to the signatures before Apollo Client 4.2, preserving backward compatibility. Classic signatures still work with manually specified TypeScript generics (e.g., useSuspenseQuery<MyData>(...)). However, manually specifying generics has been discouraged for a long time—instead, we recommend using TypedDocumentNode to automatically infer types, which provides more accurate results without any manual annotations.
Modern signatures automatically incorporate your declared defaultOptions into return types, providing more accurate types. Modern signatures infer types from the document node and do not support manually passing generic type arguments; TypeScript will produce a type error if you attempt to do so.
Methods and hooks automatically switch to modern signatures the moment any non-optional property is declared in DeclareDefaultOptions. The switch happens across all methods and hooks globally:
// apollo.d.ts
import"@apollo/client";declaremodule"@apollo/client"{namespaceApolloClient{namespaceDeclareDefaultOptions{interfaceWatchQuery{errorPolicy:"all";// non-optional → modern signatures activated automatically
}}}}
Users can also manually switch to modern signatures without declaring any defaultOptions, for example when wanting accurate type inference without relying on global defaultOptions:
Note that this is not recommended for long-term use. When combined with DeclareDefaultOptions, switching back to classic results in the same incorrect types as before Apollo Client 4.2—methods and hooks will not reflect the defaultOptions you've declared.
#13130dd12231 Thanks @jerelmiller! - Improve the accuracy of client.query return type to better detect the current errorPolicy. The data property is no longer nullable when the errorPolicy is none. This makes it possible to remove the undefined checks or optional chaining in most cases.
#132101f9a428 Thanks @jerelmiller! - Add support for automatic event-based refetching, such as window focus.
The RefetchEventManager class handles automatic refetches in response to events. Apollo Client provides built-in sources for window focus and network reconnect as windowFocusSource and onlineSource.
Event refetching is fully opt-in. Create and pass a RefetchEventManager instance to the ApolloClient constructor to activate the event listeners.
import{ApolloClient,InMemoryCache,RefetchEventManager,windowFocusSource,onlineSource,}from"@apollo/client";constclient=newApolloClient({link,cache: newInMemoryCache(),refetchEventManager: newRefetchEventManager({sources:{// Refetch when window is focused
windowFocus: windowFocusSource,// Refetch when the user comes back online
online: onlineSource,},}),});
By default, all active queries refetch when the events fire. Queries can opt out per-event or disable all event refetches:
// Skip refetch on window focus for this query, but keep `online`
useQuery(QUERY,{refetchOn:{windowFocus: false},});// Disable all event-driven refetches for this query
useQuery(OTHER_QUERY,{refetchOn: false,});// Enable every event for this query, regardless of defaultOptions
useQuery(LIVE_DASHBOARD,{refetchOn: true,});// Dynamically enable or disable a refetch when the event fires
useQuery(LIVE_DASHBOARD,{refetchOn:({source,payload})=>{if(source==="windowFocus"){// payload is the data associated with the event
returnsomeCondition(payload);}returntrue;},});// Dynamically enable or disable a refetch for a specific event
useQuery(LIVE_DASHBOARD,{refetchOn:{windowFocus:({payload})=>{// payload is the data associated with the event
returnsomeCondition(payload);},},});
To enable per-query opt-in rather than opt-out, set defaultOptions.watchQuery.refetchOn to false and enable it per-query instead.
constclient=newApolloClient({link,cache,refetchEventManager: newRefetchEventManager({sources:{windowFocus: windowFocusSource},}),defaultOptions:{watchQuery:{refetchOn: false},},});// Only this query refetches on window focus
useQuery(DASHBOARD_QUERY,{refetchOn:{windowFocus: true}});
When defaultOptions.watchQuery.refetchOn and per-query refetchOn options are provided, the objects are merged together.
Custom events
You can also add your own custom events that trigger refetches. Register your event name and payload type using TypeScript module augmentation, then provide a source function that returns an Observable. The source's emitted value becomes the event's payload.
import{Observable}from"@apollo/client";import{filter}from"rxjs";import{AppState,AppStateStatus,Platform}from"react-native";declaremodule"@apollo/client"{interfaceRefetchEvents{reactNativeAppStatus: AppStateStatus;}}constrefetchEventManager=newRefetchEventManager({sources:{reactNativeAppStatus:()=>{returnnewObservable((observer)=>{constsubscription=AppState.addEventListener("change",(status)=>{observer.next(status);});return()=>subscription.remove();}).pipe(filter((status)=>Platform.OS!=="web"&&status==="active"));},},});// Disable per-query by setting the event to false
useQuery(QUERY,{refetchOn:{reactNativeAppStatus: false}});
Manually trigger an event refetch
Refetches can be triggered imperatively by calling emit with the event name and its payload (if any).
A source that has no automatic detection logic but still wants imperative emit support can be declared as true. Type the event as void to omit the payload argument.
Note: Calling emit on an event without a registered source will log a warning and result in a no-op.
Custom handlers
When an event fires, the default handler calls client.refetchQueries({ include: "active" }) filtered by each query's refetchOn setting. You can override the handler for an event to add your own custom filtering. For example, to refetch all queries, including standby queries, define a handler for the event:
"ignore" → { data: TData | undefined; error?: never }
client.mutate and useMutation pick up the declared defaultOptions.mutate.errorPolicy and the explicit errorPolicy on each call to narrow return types accordingly.
useMutation.Result.error is narrowed to undefined when errorPolicy is "ignore", since client.mutate never resolves with an error in that case.
DeclareDefaultOptions.Mutate already accepted errorPolicy; the new behavior is that once you declare it, hook and method return types reflect it:
Setting errorPolicy on an individual call overrides the default for that call's return type.
#13222b93c172 Thanks @jerelmiller! - Extend the defaultOptions type-safety work to preloadQuery (returned from createQueryPreloader). Defaults declared in DeclareDefaultOptions.WatchQuery now work with preloadQuery to ensure the PreloadedQueryRef's data states are correctly set.
While these types are generally correct, if you were to set errorPolicy: 'all' as a default option, the type of result.data for the first query would remain TData instead of changing to TData | undefined to match the runtime behavior.
We are now enforcing that certain defaultOptions types need to be registered globally. This means that if you want to use errorPolicy: 'all' as a default option for a query, you will need to register its type like this:
// apollo.d.ts
import"@apollo/client";declaremodule"@apollo/client"{namespaceApolloClient{namespaceDeclareDefaultOptions{interfaceWatchQuery{// possible global-registered values:
// * `errorPolicy`
// * `returnPartialData`
errorPolicy:"all";}interfaceQuery{// possible global-registered values:
// * `errorPolicy`
}interfaceMutate{// possible global-registered values:
// * `errorPolicy`
}}}}
Once this type declaration is in place, the type of result.data in the above example will correctly be changed to TData | undefined, reflecting the possibility that if an error occurs, data might be undefined. Manually specifying useSuspenseQuery(MY_QUERY, { errorPolicy: "none" }); changes result.data to TData to reflect the local override.
This change means that you will need to declare your default options types in order to use defaultOptions with ApolloClient, otherwise you will see a TypeScript error.
Without the type declaration, the following (previously valid) code will now error:
newApolloClient({link: ApolloLink.empty(),cache: newInMemoryCache(),defaultOptions:{watchQuery:{// results in a type error:
// Type '"all"' is not assignable to type '"A default option for watchQuery.errorPolicy must be declared in ApolloClient.DeclareDefaultOptions before usage. See https://www.apollographql.com/docs/react/data/typescript#declaring-default-options-for-type-safety."'.
errorPolicy:"all",},},});
If you are creating multiple instances of Apollo Client with conflicting default options and you cannot register a single defaultOptions value as a result, you can relax the constraints by declaring those options as union types covering all values used by all clients. The properties can be required (to enforce them in defaultOptions) or optional (if some constructor calls won't pass a value):
With this declaration, the ApolloClient constructor accepts any of those values in defaultOptions. The tradeoff is that hook and method return types become more generic. For example, calling useSuspenseQuery without an explicit errorPolicy will return a result typed as if all error policies are possible, since TypeScript can't know which specific value your instance uses at runtime.
Note that making a property optional (errorPolicy?:) is equivalent to adding the TypeScript default value ("none") to the union. So errorPolicy?: "all" | "ignore" has the same effect on return types as errorPolicy: "none" | "all" | "ignore", because TypeScript assumes the option could also be absent (i.e., "none").
You can also use a partial union that only lists the values you actually use. For example, if you only ever use "all" or "ignore", declare errorPolicy: "all" | "ignore" (required) to keep the union narrow and avoid unused values broadening your signatures unnecessarily.
Patch Changes
#13217790f987 Thanks @jerelmiller! - Fix the deprecation for the classic signatures for function overloads that rely on type inference from a TypedDocumentNode. The deprecation now only applies to classic signatures that provide explicit type arguments to encourage the use of TypedDocumentNode.
#1321554c9eb7 Thanks @jerelmiller! - Ensure the options object for the useQuery, useSuspenseQuery, and useBackgroundQuery hooks provide proper IntelliSense suggestions.
#132299a7f65a Thanks @jerelmiller! - Fix refetchOn merging when defaultOptions.watchQuery.refetchOn is set to a non-object value (false, true, or a function) and the per-query refetchOn is an object. Previously the per-query object completely replaced the default so unspecified events fell back to "enabled" regardless of the default.
The defaultOptions value now applies to any event the per-query object does not explicitly configure:
false - unspecified events stay disabled
true - unspecified events refetch
Callback function - the function is called for unspecified events to determine whether to refetch
constclient=newApolloClient({// ...
defaultOptions:{watchQuery:{refetchOn: false,},},});// Only `windowFocus` refetches. Other events stay disabled per the default.
useQuery(QUERY,{refetchOn:{windowFocus: true}});
#13230b25b659 Thanks @jerelmiller! - Add the ability to override the default event handler on RefetchEventManager. The default handler runs when no per-source handler is configured for an event. Provide a custom handler via the defaultHandler constructor option or the setDefaultEventHandler instance method.
#13203099954b Thanks @copilot-swe-agent! - Remove the workspaces field from the published package.json in dist to avoid Yarn v1 warnings about workspaces requiring private packages.
#131286c0b8e4 Thanks @pavelivanov! - Fix useQuery hydration mismatch when ssr: false and skip: true are used together
When both options were combined, the server would return loading: false (because useSSRQuery checks skip first), but the client's getServerSnapshot was returning ssrDisabledResult with loading: true, causing a hydration mismatch.
#13111bf46fe0 Thanks @RogerHYang! - Fix createFetchMultipartSubscription to support cancellation via AbortController
Previously, calling dispose() or unsubscribe() on a subscription created by createFetchMultipartSubscription had no effect - the underlying fetch request would continue running until completion. This was because no AbortController was created or passed to fetch(), and no cleanup function was returned from the Observable.
#131058b62263 Thanks @phryneas! - ssrMode, ssrForceFetchDelay or prioritizeCacheValues should not override fetchPolicy: 'cache-only', fetchPolicy: 'no-cache', fetchPolicy: 'standby', skip: true, or skipToken when reading the initial value of an ObservableQuery.
#131058b62263 Thanks @phryneas! - Fix skipToken in useQuery with prerenderStatic and related SSR functions.
#131058b62263 Thanks @phryneas! - Avoid fetches with fetchPolicy: no-cache in useQuery with prerenderStatic and related SSR functions.
#12927785e223 Thanks @jerelmiller! - You can now provide a callback function as the context option on the mutate function returned by useMutation. The callback function is called with the value of the context option provided to the useMutation hook. This is useful if you'd like to merge the context object provided to the useMutation hook with a value provided to the mutate function.
functionMyComponent() {const[mutate,result]=useMutation(MUTATION,{context:{foo: true},});asyncfunctionrunMutation() {awaitmutate({// sends context as { foo: true, bar: true }
context:(hookContext)=>({...hookContext,bar: true}),});}// ...
}
#1292394ea3e3 Thanks @jerelmiller! - Fix an issue where deferred payloads that returned arrays with fewer items than the original cached array would retain items from the cached array. This change includes @stream arrays where stream arrays replace the cached arrays.
#1292796b531f Thanks @jerelmiller! - Don't set the fallback value of a @client field to null when a read function is defined. Instead the read function will be called with an existing value of undefined to allow default arguments to be used to set the returned value.
When a read function is not defined nor is there a defined resolver for the field, warn and set the value to null only in that instance.
#1292745ebb52 Thanks @jerelmiller! - Add support for from: null in client.watchFragment and cache.watchFragment. When from is null, the emitted result is:
{data: null,dataState:"complete",complete: true,}
#129262b7f2c1 Thanks @jerelmiller! - Support the newer incremental delivery format for the @defer directive implemented in graphql@17.0.0-alpha.9. Import the GraphQL17Alpha9Handler to use the newer incremental delivery format with @defer.
[!NOTE]
In order to use the GraphQL17Alpha9Handler, the GraphQL server MUST implement the newer incremental delivery format. You may see errors or unusual behavior if you use the wrong handler. If you are using Apollo Router, continue to use the Defer20220824Handler because Apollo Router does not yet support the newer incremental delivery format.
#1292745ebb52 Thanks @jerelmiller! - Add support for arrays with useFragment, useSuspenseFragment, and client.watchFragment. This allows the ability to use a fragment to watch multiple entities in the cache. Passing an array to from will return data as an array where each array index corresponds to the index in the from array.
functionMyComponent() {constresult=useFragment({fragment,from:[item1,item2,item3],});// `data` is an array with 3 items
console.log(result);// { data: [{...}, {...}, {...}], dataState: "complete", complete: true }
}
#1292745ebb52 Thanks @jerelmiller! - Add a getCurrentResult function to the observable returned by client.watchFragment and cache.watchFragment that returns the current value for the watched fragment.
#13038109efe7 Thanks @jerelmiller! - Add the from option to readFragment, watchFragment, and updateFragment.
#129182e224b9 Thanks @jerelmiller! - Add support for the @stream directive on both the Defer20220824Handler and the GraphQL17Alpha2Handler.
[!NOTE]
The implementations of @stream differ in the delivery of incremental results between the different GraphQL spec versions. If you upgrading from the older format to the newer format, expect the timing of some incremental results to change.
#13056b224efc Thanks @jerelmiller! - InMemoryCache no longer filters out explicitly returned undefined items from read functions for array fields. This now makes it possible to create read functions on array fields that return partial data and trigger a fetch for the full list.
#13058121a2cb Thanks @jerelmiller! - Add an extensions option to cache.write, cache.writeQuery, and client.writeQuery. This makes extensions available in cache merge functions which can be accessed with the other merge function options.
As a result of this change, any extensions returned in GraphQL operations are now available in merge in the cache writes for these operations.
#1292796b531f Thanks @jerelmiller! - Add an abstract resolvesClientField function to ApolloCache that can be used by caches to tell LocalState if it can resolve a @client field when a local resolver is not defined.
LocalState will emit a warning and set a fallback value of null when no local resolver is defined and resolvesClientField returns false, or isn't defined. Returning true from resolvesClientField signals that a mechanism in the cache will set the field value. In this case, LocalState won't set the field value.
#13078bf1e0dc Thanks @phryneas! - Use the default stream merge function for @stream fields only if stream info is present. This change means that using the older Defer20220824Handler will not use the default stream merge function and will instead truncate the streamed array on the first chunk.
Patch Changes
#12884d329790 Thanks @phryneas! - Ensure that PreloadedQueryRef instances are unsubscribed when garbage collected
#130861a1d408 Thanks @phryneas! - Change the returned value from null to {} when all fields in a query were skipped.
This also fixes a bug where useSuspenseQuery would suspend indefinitely when all fields were skipped.
#130107627000 Thanks @jerelmiller! - Fix an issue where errors parsed from incremental chunks in ErrorLink might throw when using the GraphQL17Alpha9Handler.
#1292745ebb52 Thanks @jerelmiller! - Deduplicate watches created by useFragment, client.watchFragment, and cache.watchFragment that contain the same fragment, variables, and identifier. This should improve performance in situations where a useFragment or a client.watchFragment is used to watch the same object in multiple places of an application.
#12927259ae9b Thanks @jerelmiller! - Allow FragmentType not only to be called as FragmentType<TData>, but also as FragmentType<TypedDocumentNode>.
#129255851800 Thanks @jerelmiller! - Fix an issue where calling fetchMore with @defer or @stream would not rerender incremental results as they were streamed.
#13083f3c2be1 Thanks @phryneas! - Expose the ExtensionsWithStreamInfo type for extensions in Cache.writeQuery, Cache.write and Cache.update so other cache implementations also can correctly access them.
#1292394ea3e3 Thanks @jerelmiller! - Improve the cache data loss warning message when existing or incoming is an array.
#129274631175 Thanks @jerelmiller! - Ignore top-level data values on subsequent chunks in incremental responses.
#129274631175 Thanks @jerelmiller! - Fix the Defer20220824Handler.SubsequentResult type to match the FormattedSubsequentIncrementalExecutionResult type in graphql@17.0.0-alpha.2.
#1292796b531f Thanks @jerelmiller! - Warn when using a no-cache fetch policy without a local resolver defined. no-cache queries do not read or write to the cache which meant no-cache queries are silently incomplete when the @client field value was handled by a cache read function.
#129275776ea0 Thanks @jerelmiller! - Update the accept header used with the GraphQL17Alpha9Handler to multipart/mixed;incrementalSpec=v0.2 to ensure the newest incremental delivery format is requested.
#1292745ebb52 Thanks @jerelmiller! - DeepPartial<Array<TData>> now returns Array<DeepPartial<TData>> instead of Array<DeepPartial<TData | undefined>>.
#1307199ffe9a Thanks @phryneas! - prerenderStatic: Expose return value of renderFunction to userland, fix aborted property.
This enables usage of resumeAndPrerender with React 19.2.
#1302605eee67 Thanks @jerelmiller! - Reduce the number of observables created by watchFragment by reusing existing observables as much as possible. This should improve performance when watching the same item in the cache multiple times after a cache update occurs.
#130107627000 Thanks @jerelmiller! - Handle @stream payloads that send multiple items in the same chunk when using the Defer20220824Handler.
#130107627000 Thanks @jerelmiller! - Handle an edge case with the Defer20220824Handler where an error for a @stream item that bubbles to the @stream boundary (such as an item returning null for a non-null array item) would write items from future chunks to the wrong array index. In these cases, the @stream field is no longer processed and future updates to the field are ignored. This prevents runtime errors that TypeScript would otherwise not be able to catch.
#130811e06ad7 Thanks @jerelmiller! - Avoid calling merge functions more than once for the same incremental chunk.
This fixes an issue where the change introduced in 4.0.11 via #13049 would not
be applied if defaultOptions for watchQuery were declared.
Please note that compact and mergeOptions are considered internal utilities
and they might have similar behavior changes in future releases.
Do not use them in your application code - a change like this is not considered
breaking and will not be announced as such.
#130508020829 Thanks @phryneas! - Replace usage of findLast with more backwards-compatible methods.
#1304905638de Thanks @phryneas! - Fixes an issue where queries starting with skipToken or lazy queries from useLazyQuery were included in client.refetchQueries() before they had been executed for the first time. While generally queries with a standbyfetchPolicy should be included in refetch, these queries never had variables passed in, so they should be excluded until they have run once and received their actual variables.
These queries are now properly excluded from refetch operations until after their initial execution.
This change adds a new hidden option to client.watchQuery, [variablesUnknownSymbol], which may be set true for queries starting with a fetchPolicy of standby. It will only be applied when creating the ObservableQuery instance and cannot be changed later. This flag indicates that the query's variables are not yet known, and thus it should be excluded from refetch operations until they are. This option is not meant for everyday use and is intended for framework integrations only.
#129938f3bc9b Thanks @jerelmiller! - Fix an issue where switching from options with variables to skipToken with useSuspenseQuery and useBackgroundQuery would create a new ObservableQuery. This could cause unintended refetches where variables were absent in the request when the query was referenced with refetchQueries.
#129373b0d89b Thanks @phryneas! - Fix a problem with fetchMore where the loading state wouldn't reset if the result wouldn't result in a data update.
#12892db8a04b Thanks @jerelmiller! - Prevent unhandled rejections from the promise returned by calling the mutate function from the useMutation hook.
#128995352c12 Thanks @phryneas! - Fix an issue when invariant is called by external libraries when no dev error message handler is loaded.
#1289571f2517 Thanks @jerelmiller! - Support skipToken with useQuery to provide a more type-safe way to skip query execution.
import{skipToken,useQuery}from"@apollo/client/react";// Use `skipToken` in place of `skip: true` for better type safety
// for required variables
const{data}=useQuery(QUERY,id?{variables:{id}}:skipToken);
Note: this change is provided as a patch within the 4.0 minor version because the changes to TypeScript validation with required variables in version 4.0 made using the skip option more difficult.
#12900c0d5be7 Thanks @phryneas! - Use named export equal instead of default from "@wry/equality"
This PR contains the following updates:
| Package | Change | [Age](https://docs.renovatebot.com/merge-confidence/) | [Confidence](https://docs.renovatebot.com/merge-confidence/) |
|---|---|---|---|
| [@apollo/client](https://www.apollographql.com/docs/react/) ([source](https://github.com/apollographql/apollo-client)) | [`3.14.1` → `4.3.1`](https://renovatebot.com/diffs/npm/@apollo%2fclient/3.14.1/4.3.1) |  |  |
---
### Release Notes
<details>
<summary>apollographql/apollo-client (@​apollo/client)</summary>
### [`v4.3.1`](https://github.com/apollographql/apollo-client/blob/HEAD/CHANGELOG.md#431)
[Compare Source](https://github.com/apollographql/apollo-client/compare/@apollo/client@4.3.0...@apollo/client@4.3.1)
##### Patch Changes
- [#​13464](https://github.com/apollographql/apollo-client/pull/13464) [`37f700e`](https://github.com/apollographql/apollo-client/commit/37f700eb4c65ec7683111e128bca087d4a97cf41) Thanks [@​jerelmiller](https://github.com/jerelmiller)! - Fix an issue where `useLazyQuery` did not rerender with new `variables` until the network request had completed when calling `execute` with new variables while a request was already in-flight.
### [`v4.3.0`](https://github.com/apollographql/apollo-client/blob/HEAD/CHANGELOG.md#430)
[Compare Source](https://github.com/apollographql/apollo-client/compare/@apollo/client@4.2.12...@apollo/client@4.3.0)
##### Minor Changes
- [#​13447](https://github.com/apollographql/apollo-client/pull/13447) [`24133fe`](https://github.com/apollographql/apollo-client/commit/24133fe429af460fcfe44d529375ebb063a29326) Thanks [@​jerelmiller](https://github.com/jerelmiller)! - Field policies and `inputObjects` can now tell the cache whether a field is a list of scalars or a scalar whose value is an array. Previously all arrays were iterated and only the inner type was provided to the scalar `parse`/`serialize` functions.
This required some breaking changes from previous prerelease versions:
- The field policy `scalar` option and `inputObjects` type string now use GraphQL list syntax to mark a field as a list of scalars
- The abstract `cache.getScalarForField` is now `cache.getScalarTypeForField` and is expected to return the string representing the scalar type rather than the `Scalar` instance
```ts
new InMemoryCache({
scalars: {
DateTime: new Scalar(/*...*/),
},
inputObjects: {
EventFilter: {
fields: {
// Previously only the scalar type was provided
datesBefore: "DateTime",
// List syntax now required
datesAfter: "[DateTime]",
dates2d: "[[DateTime]]",
},
},
},
typePolicies: {
Event: {
fields: {
// Previously only the scalar type was provided
datesBefore: {
scalar: "DateTime",
},
// List syntax now required
datesAfter: {
scalar: "[DateTime]",
},
dates2d: {
scalar: "[[DateTime]]",
},
},
},
},
});
```
Now it's possible to handle scalars that are represented by arrays:
```ts
const dateTimeRangeScalar = new Scalar<
[string, string],
{ start: Date; end: Date }
>({
parse: ([start, end]) => ({
start: new Date(start),
end: new Date(end),
}),
serialize: (range) => [range.start.toISOString(), range.end.toISOString()],
is: (value) => !Array.isArray(value),
});
const cache = new InMemoryCache({
scalars: {
DateTimeRange: dateTimeRangeScalar,
},
typePolicies: {
Event: {
fields: {
range: {
scalar: "DateTimeRange",
},
},
},
},
});
const query = gql`
query {
event {
range
}
}
`;
cache.writeQuery({
query,
data: {
event: {
__typename: "Event",
// Server returns DateTimeRange as a JSON array
range: ["2024-01-01T00:00:00Z", "2024-06-01T00:00:00Z"],
},
},
});
const { data } = useQuery(query);
// => { event: { __typename: "Event", range: { start: Date, end: Date } } }
```
- [#​13324](https://github.com/apollographql/apollo-client/pull/13324) [`0abd8de`](https://github.com/apollographql/apollo-client/commit/0abd8de53a408c6b5925b2a909acde5179eaac46) Thanks [@​jerelmiller](https://github.com/jerelmiller)! - Fix the accuracy of `dataState` in complex incremental streaming scenarios, especially when combined with `returnPartialData: true`.
Prior to this change, all intermediate chunks used for both `@defer` and `@stream` directives returned a `dataState` of `streaming`, regardless of whether the actual data shape fit the definition of the `streaming` data state. The `streaming` data state represents an incomplete incremental response where the only holes in the data occur at `@defer` boundaries.
Let's use the following example of where the previous `dataState` fell down when combined with `returnPartialData`.
```gql
query GreetingQuery {
greeting {
message
... @defer {
recipient {
name
email
}
}
}
}
```
1. Scenario 1: partial data inside a `@defer` boundary written to the cache
Let's say the cache contained the following partial data:
```ts
{
greeting: {
__typename: "Greeting",
recipient: {
__typename: "Person",
name: "John Doe",
},
},
};
```
After the first chunk arrives from the server, the data looks like the following:
```ts
{
greeting: {
__typename: "Greeting",
message: "Hello, John",
recipient: {
__typename: "Person",
name: "John Doe",
},
},
};
```
This data is not `complete` because `recipient.email` is missing. This data is also not `streaming` because the data requirements in the `@defer` boundary are partially fulfilled due to the existence of `recipient`. This could lead to runtime crashes on `recipient.email` if you use the existence of `recipient` to detect whether data in the `@defer` boundary has streamed in or not. This change now accurately reports this as `partial` to ensure the field is marked as a partial field in `recipient`.
2. Scenario 2: partial data written to the cache that fulfills the data requirements of the `@defer` boundary
Let's say the cache contained the following partial data:
```ts
{
greeting: {
__typename: "Greeting",
recipient: {
__typename: "Person",
name: "John Doe",
email: "john@example.com",
},
},
};
```
After the first chunk arrives from the server, the data looks like the following:
```ts
{
greeting: {
__typename: "Greeting",
message: "Hello, John",
recipient: {
__typename: "Person",
name: "John Doe",
email: "john@example.com",
},
},
};
```
In this case, the combination of the first chunk and the partial data in the cache now fulfills the data requirements of the query. Even though the server is still streaming data (`NetworkStatus.streaming`), we can report this as `dataState: "complete"` since it is safe to access data on all fields.
This change also means `@stream` queries by definition fulfill the data requirements of the query after the first chunk arrives since `@stream` operates on lists and contains no data holes. `@stream` queries now accurately report `dataState` as `complete` or `partial`, depending on whether the list mixes partial data with streamed list items.
As a result of this change, some cases where you'd previously see `dataState` reported as `"streaming"` are now reported as `partial` or `complete`.
If you use `dataState` to determine whether an incremental request is still in-flight, please use `networkStatus` instead to check for `NetworkStatus.streaming`. `dataState` is type narrowing feature and not intended to report the network status.
- [#​13274](https://github.com/apollographql/apollo-client/pull/13274) [`7b10078`](https://github.com/apollographql/apollo-client/commit/7b10078f4bcd8d82890ca438bf7355677fe2f841) Thanks [@​jerelmiller](https://github.com/jerelmiller)! - Adds `Scalar.fromGraphQLScalarType` helper to create a `Scalar` instance from an existing graphql.js `GraphQLScalarType`.
```ts
import { GraphQLScalarType } from "graphql";
import { Scalar } from "@apollo/client";
const dateTimeScalarType = new GraphQLScalarType<Date, string>({
// ...
});
const dateTimeScalar = Scalar.fromGraphQLScalarType(dateTimeScalarType, {
is: (value) => value instanceof Date,
});
```
- [#​13421](https://github.com/apollographql/apollo-client/pull/13421) [`d6197a4`](https://github.com/apollographql/apollo-client/commit/d6197a417ee7ed0c6e1dcc651c3d28ad7559a29c) Thanks [@​jerelmiller](https://github.com/jerelmiller)! - The minimum supported TypeScript version is now 5.9.x.
- [#​13270](https://github.com/apollographql/apollo-client/pull/13270) [`d080f11`](https://github.com/apollographql/apollo-client/commit/d080f1114541475842335dfc77e431f455d45de7) Thanks [@​jerelmiller](https://github.com/jerelmiller)! - Adds the plumbing and types implementation for declaring custom scalars and configuring custom scalars in `InMemoryCache`.
You can declare custom scalar types with declaration merging on the `ApolloCache.Scalars` interface:
```ts
// apollo.d.ts
import "@apollo/client";
declare module "@apollo/client" {
namespace ApolloCache {
interface Scalars {
Date: { serialized: string; parsed: Date };
}
}
}
```
This enables the `scalars` option in `InMemoryCache`:
```ts
import { Scalar } from "@apollo/client";
const cache = new InMemoryCache({
scalars: {
Date: new Scalar({
parse: (dateString) => new Date(dateString),
serialize: (date) => date.toISOString(),
is: (value) => value instanceof Date,
}),
},
});
```
- [#​13250](https://github.com/apollographql/apollo-client/pull/13250) [`bad7035`](https://github.com/apollographql/apollo-client/commit/bad7035565e15c18800080d9e0abf1d89b3d82fa) Thanks [@​jerelmiller](https://github.com/jerelmiller)! - Add the ability to define the cache type for the client. `client.cache` currently returns `ApolloCache` as the cache type regardless of what cache you've provided to `ApolloClient`.
Declare the cache type using the `cache` property in the `TypeOverrides` interface to set the cache implementation used for the client.
```ts
// apollo.d.ts
import type { InMemoryCache } from "@apollo/client";
declare module "@apollo/client" {
export interface TypeOverrides {
cache: InMemoryCache;
}
}
```
Now anywhere `cache` is accessible, the type is the declared cache type:
```ts
client.cache;
// ^? InMemoryCache
client.mutate({
update: (cache) => {
// ^? InMemoryCache
},
});
```
> \[!NOTE]
> Setting a cache type enforces that cache type in the `cache` option for the `ApolloClient` constructor.
- [#​13406](https://github.com/apollographql/apollo-client/pull/13406) [`bd74ccb`](https://github.com/apollographql/apollo-client/commit/bd74ccb2f75bc434afc4f5172311b551266f8196) Thanks [@​jerelmiller](https://github.com/jerelmiller)! - Emit a development-only warning when a feud is detected between queries that overwrite each other's data. This should make it easier to detect when you need to select a key field or add a `merge` function to a field policy.
- [#​13390](https://github.com/apollographql/apollo-client/pull/13390) [`90e338c`](https://github.com/apollographql/apollo-client/commit/90e338c3cd5ec1be23852cc5ef0ca6078a98f548) Thanks [@​jerelmiller](https://github.com/jerelmiller)! - Fix issue where sibling `@defer` fragments were pruned incorrectly when at least one of the `@defer` fragments wasn't delivered.
As a result of this change, a `label` argument is now added to all outgoing `@defer` directives when using the `GraphQL17Alpha9Handler` in order to disambiguate the `@defer` fragments from each other.
- [#​13426](https://github.com/apollographql/apollo-client/pull/13426) [`a9beaff`](https://github.com/apollographql/apollo-client/commit/a9beaff117e6eae791b078e22ecdfc93b82ded8f) Thanks [@​jerelmiller](https://github.com/jerelmiller)! - Version bump only to `rc`.
- [#​13416](https://github.com/apollographql/apollo-client/pull/13416) [`f2d5d5a`](https://github.com/apollographql/apollo-client/commit/f2d5d5ac26f0ad19f1aaa315f92b19f268bd0509) Thanks [@​jerelmiller](https://github.com/jerelmiller)! - Add `GraphQLCodegenIncremental` type overrides that assemble GraphQL Codegen `@defer` operation types when `dataState` is `"complete"`.
- [#​13372](https://github.com/apollographql/apollo-client/pull/13372) [`e4cde69`](https://github.com/apollographql/apollo-client/commit/e4cde6999e64e81d8fbef42326a7b2e83d90aa10) Thanks [@​jerelmiller](https://github.com/jerelmiller)! - Parse scalar fields for `no-cache` queries.
- [#​13386](https://github.com/apollographql/apollo-client/pull/13386) [`0be8fd8`](https://github.com/apollographql/apollo-client/commit/0be8fd8495800389f779bd883daae2e27b96fce6) Thanks [@​atharv-sys32](https://github.com/atharv-sys32)! - Support `skipToken` with `useSubscription` to provide a more type-safe way to skip subscription execution with required variables.
```ts
import { skipToken, useSubscription } from "@apollo/client/react";
// Use `skipToken` in place of `skip: true` for better type safety
// for required variables
const { data } = useSubscription(
SUBSCRIPTION,
id ? { variables: { id } } : skipToken
);
```
- [#​13337](https://github.com/apollographql/apollo-client/pull/13337) [`2df711f`](https://github.com/apollographql/apollo-client/commit/2df711fd6f889ca3a62779483243d909800cd0c7) Thanks [@​jcostello-atlassian](https://github.com/jcostello-atlassian)! - Allow overriding the `from` input of `useFragment`, `useSuspenseFragment`, `readFragment`, `writeFragment` and related fragment APIs via a new `FromOptionValue` key on the `TypeOverrides` interface.
By default, `from` continues to accept `StoreObject | Reference | FragmentType<TData> | string`. Apps can now supply a stricter policy (for example, requiring `__typename` and disallowing nullish identifier values) without affecting `StoreObject`, `cache.identify`, `cache.modify` or optimistic writes.
```ts
// apollo.d.ts
import "@apollo/client";
import type { HKT, StoreValue } from "@apollo/client/utilities";
type StrictFrom<TData extends { __typename: string }> =
| {
// the `__typename` has to match the one of the fragment type
__typename: TData["__typename"];
// `& {}` forces values to be "defined" so an explicit `undefined`
// (as well as `null`) is rejected.
[key: string]: Exclude<StoreValue, null | undefined> & {};
}
| { __ref: string }
| string
| null;
interface StrictFromHKT extends HKT {
arg1: { __typename: string }; // TData
return: StrictFrom<this["arg1"]>;
}
declare module "@apollo/client" {
export interface TypeOverrides {
FromOptionValue: StrictFromHKT;
}
}
```
- [#​13405](https://github.com/apollographql/apollo-client/pull/13405) [`f923ab4`](https://github.com/apollographql/apollo-client/commit/f923ab422e1bcd35c1bcd2939f58dc3723508b55) Thanks [@​jerelmiller](https://github.com/jerelmiller)! - Field policy `read` and `merge` functions are now ignored when the field policy configures the `scalar` option. If a `read` or `merge` function is provided alongside `scalar`, a development-only warning is emitted.
- [#​13393](https://github.com/apollographql/apollo-client/pull/13393) [`434d25f`](https://github.com/apollographql/apollo-client/commit/434d25facdcb214cac4ee33abbe1f1fecd05637b) Thanks [@​jerelmiller](https://github.com/jerelmiller)! - Change when `@defer` fragments and `@stream` fields are pruned for `cache-first` and `cache-and-network` fetch policies to better match the network when the initial value contained a partial result:
- `cache-first`: prune undelivered `@defer` fragments or `@stream` items when the result is fetched from the network due to a partial result
- `cache-and-network`: prune undelivered `@defer` fragments or `@stream` items if the initial cache value was partial. If the first value emitted from the cache is complete, the results will not be pruned.
This makes the emitted results more predictable by following what the network has delivered and avoids some ambiguity in other edge cases.
For example, with a `cache-first` fetch policy where all `@defer` fields are written to the cache, but a non-deferred field is partial, the values emitted from the client previously looked like the following:
```graphql
query {
user {
id
name
... @defer {
email
}
}
}
```
```ts
// data written to the cache is missing name
{ user: { id: 1, email: "user.cache@example.com" }}
// 1. empty because the result is partial
{ data: undefined, dataState: "empty", ... }
// 2. returns all data because the cache contains a value for email
{ data: { user: 1, name: "User", email: "user.cache@example.com" }, dataState: "complete" }
// 3. email updated from the server
{ data: { user: 1, name: "User", email: "user.network@example.com" }, dataState: "complete" }
```
Here the result is confusing because the initial value returned from the query was `undefined`, yet a complete result was returned after the initial chunk from the network returned (which did not contain `email`).
The cache values are now pruned if the network hasn't delivered them yet:
```ts
// 1. empty because the result is partial
{ data: undefined, dataState: "empty" }
// 2. email hasn't been delivered by the network so it gets pruned
{ data: { user: 1, name: "User" }, dataState: "streaming" }
// 3. full result returned after the network streams the email field
{ data: { user: 1, name: "User", email: "user.network@example.com" }, dataState: "complete" }
```
This is especially helpful in situations where `@defer` boundaries that are never delivered due to errors prevent an awkward situation where the client would otherwise have to choose whether to serve the stale cache result from the cache, or prune the undelivered fragment on the final chunk.
- [#​13270](https://github.com/apollographql/apollo-client/pull/13270) [`6031987`](https://github.com/apollographql/apollo-client/commit/60319870f8f38463ba94c798c91752bf8a15eb91) Thanks [@​jerelmiller](https://github.com/jerelmiller)! - Adds a `scalar` option to `InMemoryCache` field policies that tells the cache which scalar to use when parsing or serializing the field value.
```ts
import { Scalar } from "@apollo/client";
new InMemoryCache({
scalars: {
DateTime: new Scalar({
parse: (dateString) => new Date(dateString),
serialize: (date) => date.toISOString(),
}),
},
typePolicies: {
Event: {
fields: {
startTime: {
// Parse this field using the DateTime scalar
scalar: "DateTime",
},
},
},
},
});
```
This scalar definition is now used to properly parse or serialize the field value for cache reads and writes as well as `cache.extract()` and `cache.restore()`.
- [#​13273](https://github.com/apollographql/apollo-client/pull/13273) [`0886de1`](https://github.com/apollographql/apollo-client/commit/0886de19ed67ca24bbcc075dcf5a94ba01589902) Thanks [@​jerelmiller](https://github.com/jerelmiller)! - Automatically serialize variables that include custom scalar values. This includes cache reads and writes as well as requests to the network.
For more complex input objects, a new `inputObjects` option is available to `InMemoryCache` that specifies where nested scalar fields are found.
```ts
const cache = new InMemoryCache({
scalars: {
DateTime: new Scalar({
parse: (value) => new Date(value),
serialize: (value) => value.toISOString(),
is: (value) => value instanceof Date,
}),
},
inputObjects: {
EventFilter: {
fields: {
date: "DateTime",
},
},
},
});
const client = new ApolloClient({ cache, link });
await client.query({
query: gql`
query Event($filter: EventFilter!) {
event(filter: $filter) {
name
}
}
`,
variables: {
filter: {
date: new Date("2026-01-01T00:00:00.000Z"),
},
},
});
// The link receives:
// { filter: { date: "2026-01-01T00:00:00.000Z" } }
```
- [#​13424](https://github.com/apollographql/apollo-client/pull/13424) [`d2bca2e`](https://github.com/apollographql/apollo-client/commit/d2bca2ec0ada9205c337d685047b3e9f4ef3ad43) Thanks [@​jerelmiller](https://github.com/jerelmiller)! - Remove the custom `NoInfer` type utility in favor of the native `NoInfer` introduced in TypeScript 5.4.
- [#​13270](https://github.com/apollographql/apollo-client/pull/13270) [`d080f11`](https://github.com/apollographql/apollo-client/commit/d080f1114541475842335dfc77e431f455d45de7) Thanks [@​jerelmiller](https://github.com/jerelmiller)! - Adds the `getScalar` abstract method to `ApolloCache` that cache subclasses override to provide scalar behavior to Apollo Client. Defaults to unconditionally return `undefined` if not specified.
- [#​13406](https://github.com/apollographql/apollo-client/pull/13406) [`bd74ccb`](https://github.com/apollographql/apollo-client/commit/bd74ccb2f75bc434afc4f5172311b551266f8196) Thanks [@​jerelmiller](https://github.com/jerelmiller)! - Fixes an issue where cache feuds between queries selecting incompatible non-normalized data could return untransformed network values.
Apollo Client now always writes network results to the cache before delivering them, ensuring custom scalars and field `read` functions are applied. To prevent repeated refetches when competing queries repeatedly make each other's cache results incomplete, Apollo Client stops automatically refetching a query after it sees the same incomplete result again.
This may add one network request in these cache-feud scenarios.
##### Patch Changes
- [#​13408](https://github.com/apollographql/apollo-client/pull/13408) [`7a5164d`](https://github.com/apollographql/apollo-client/commit/7a5164d3ce21b7f88f625588ec72dbce8ea33810) Thanks [@​jerelmiller](https://github.com/jerelmiller)! - Fix `dataState` to report `"streaming"` instead of `"partial"` when `returnPartialData` is `true` and the cache result is missing only `@defer` fields.
- [#​13381](https://github.com/apollographql/apollo-client/pull/13381) [`9c73762`](https://github.com/apollographql/apollo-client/commit/9c73762b8e8f1d16885140df847b8222f16a39f4) Thanks [@​jerelmiller](https://github.com/jerelmiller)! - Fix an issue where a `network-only` query leaked partial cache data for `@defer` fragments that were not delivered by the network due to an error that bubbled to the `@defer` fragment boundary.
- [#​13390](https://github.com/apollographql/apollo-client/pull/13390) [`90e338c`](https://github.com/apollographql/apollo-client/commit/90e338c3cd5ec1be23852cc5ef0ca6078a98f548) Thanks [@​jerelmiller](https://github.com/jerelmiller)! - Fix an issue where a sibling non-deferred fragment might be accidentally pruned when the `@defer` fragment hadn't been delivered.
- [#​13442](https://github.com/apollographql/apollo-client/pull/13442) [`ed033d4`](https://github.com/apollographql/apollo-client/commit/ed033d46fad08dd0f216da39a30d8d048346ed0c) Thanks [@​jerelmiller](https://github.com/jerelmiller)! - Remove the optional modifier from the `variables` property provided to the `update` function in `client.mutate` and `useMutation`. `variables` is always a defined object, even when variables are not provided to the mutation.
- [#​13324](https://github.com/apollographql/apollo-client/pull/13324) [`0abd8de`](https://github.com/apollographql/apollo-client/commit/0abd8de53a408c6b5925b2a909acde5179eaac46) Thanks [@​jerelmiller](https://github.com/jerelmiller)! - Fix an issue where field `read` functions were not applied to intermediate results while streaming `@defer` responses. `cache.diff` ran the `read` functions, but the transformed values were only applied to the emitted result when the updated cache result was considered complete. Intermediate chunks whose only holes were at `@defer` boundaries now correctly return the result of field `read` functions.
```ts
new InMemoryCache({
typePolicies: {
Greeting: {
fields: {
message: {
read: (message) => message.toUpperCase(),
},
},
},
},
});
// query GreetingQuery {
// greeting {
// message
// ... @defer {
// recipient { name }
// }
// }
// }
// First chunk previously returned:
// { greeting: { message: "Hello world" } }
//
// Now correctly returns while still streaming:
// { greeting: { message: "HELLO WORLD" } }
```
- [#​13403](https://github.com/apollographql/apollo-client/pull/13403) [`aaff7a8`](https://github.com/apollographql/apollo-client/commit/aaff7a8a833c261e0514488c493a18d51e07a983) Thanks [@​jerelmiller](https://github.com/jerelmiller)! - Fix issue where the wrong `dataState` was returned when there was nothing written to the cache and a `@defer` fragment was marked pending.
- [#​13347](https://github.com/apollographql/apollo-client/pull/13347) [`7d543d6`](https://github.com/apollographql/apollo-client/commit/7d543d6416688ed113295a69e73b706c097a0d31) Thanks [@​jerelmiller](https://github.com/jerelmiller)! - Fix an issue where `network-only` incremental queries could cause cache data to leak into the emitted result when a `@defer` or `@stream` boundary already had complete data in the cache. Cache data inside pending `@defer` objects and `@stream` arrays are now pruned so that only completed `@defer` or `@stream` boundaries are returned.
NOTE: This change only applies to `InMemoryCache` when using `GraphQL17Alpha9Handler`.
- [#​13329](https://github.com/apollographql/apollo-client/pull/13329) [`1d581d2`](https://github.com/apollographql/apollo-client/commit/1d581d282fe223e4bf39ea5e7a3cbc44fdbf32b5) Thanks [@​AmariahAK](https://github.com/AmariahAK)! - Cache diffs for incomplete queries no longer pay the cost of building a full `MissingFieldError` when the `missing` property is not accessed. The error object is now only constructed when the `missing` property is accessed the first time. This improves performance by avoiding a V8 stack capture when `missing` is ignored entirely.
As an additional small performance improvement, `JSON.stringify` is no longer used in the error message on objects whose cache ID is known. `JSON.stringify` is only used for non-normalized objects.
- [#​13381](https://github.com/apollographql/apollo-client/pull/13381) [`9c73762`](https://github.com/apollographql/apollo-client/commit/9c73762b8e8f1d16885140df847b8222f16a39f4) Thanks [@​jerelmiller](https://github.com/jerelmiller)! - Fix an issue where a `@defer` query reported the `dataState` as `complete` instead of `streaming` when an error occurs on a deferred field that bubbled to the defer boundary.
- [#​13324](https://github.com/apollographql/apollo-client/pull/13324) [`0abd8de`](https://github.com/apollographql/apollo-client/commit/0abd8de53a408c6b5925b2a909acde5179eaac46) Thanks [@​jerelmiller](https://github.com/jerelmiller)! - Fix an issue with `@stream` queries when using `returnPartialData: true` where the streamed list was truncated after the first incremental chunk when the list contained partial cache data. The list is no longer truncated and partial list items are now retained as incremental chunks arrive. The `dataState` is now reported as `partial` until the server has streamed enough of the list so that each list item fully satisfies the query.
This change also updates `@stream` queries so that they reported with `dataState: "complete` instead of `"streaming"` since it is safe to access all fields in the response.
- [#​13373](https://github.com/apollographql/apollo-client/pull/13373) [`2551937`](https://github.com/apollographql/apollo-client/commit/25519374c7137dee7b1ddd4a70b28288936fcef0) Thanks [@​jerelmiller](https://github.com/jerelmiller)! - Fix an issue where a cache write in the middle of polling would remain as the query value if future poll requests returned deep equal results to previous polling results.
- [#​13448](https://github.com/apollographql/apollo-client/pull/13448) [`77e1e35`](https://github.com/apollographql/apollo-client/commit/77e1e350514f4574f77d9a682587d4bfe2ee03ec) Thanks [@​jerelmiller](https://github.com/jerelmiller)! - Mark `skip` as deprecated in `useQuery` and `useSubscription` now that both of these hooks support `skipToken`.
- [#​13403](https://github.com/apollographql/apollo-client/pull/13403) [`aaff7a8`](https://github.com/apollographql/apollo-client/commit/aaff7a8a833c261e0514488c493a18d51e07a983) Thanks [@​jerelmiller](https://github.com/jerelmiller)! - Fix issue where setting `returnPartialData: true` might report the wrong `dataState` when partial data was written to the cache and `@defer` fragments were pending.
- [#​13347](https://github.com/apollographql/apollo-client/pull/13347) [`7d543d6`](https://github.com/apollographql/apollo-client/commit/7d543d6416688ed113295a69e73b706c097a0d31) Thanks [@​jerelmiller](https://github.com/jerelmiller)! - Fix an issue where partial cache data could leak into intermediate incremental results. This could cause runtime crashes if you relied on the presence of values to determine whether the `@defer` data had streamed in or not.
- [#​13381](https://github.com/apollographql/apollo-client/pull/13381) [`9c73762`](https://github.com/apollographql/apollo-client/commit/9c73762b8e8f1d16885140df847b8222f16a39f4) Thanks [@​jerelmiller](https://github.com/jerelmiller)! - Fix an invariant error thrown when a `@defer` boundary received a payload after it had already been marked complete.
- [#​13268](https://github.com/apollographql/apollo-client/pull/13268) [`419e2b5`](https://github.com/apollographql/apollo-client/commit/419e2b5bfe573d1eb4c3a0ff7aa9084e6aaa2f37) Thanks [@​DaleSeo](https://github.com/DaleSeo)! - Align the remaining cache generic constraints with `Cache.Implementation`. The deprecated React mutation types (`MutationHookOptions`, `MutationFunctionOptions`, `MutationTuple`) and the internal `InternalRefetchQueriesOptions` and `QueryInfo` types still constrained their cache type parameter to `ApolloCache`, so they now match the rest of the overridable cache API.
### [`v4.2.12`](https://github.com/apollographql/apollo-client/blob/HEAD/CHANGELOG.md#4212)
[Compare Source](https://github.com/apollographql/apollo-client/compare/@apollo/client@4.2.11...@apollo/client@4.2.12)
##### Patch Changes
- [#​13400](https://github.com/apollographql/apollo-client/pull/13400) [`56ca81b`](https://github.com/apollographql/apollo-client/commit/56ca81b40962d1aeef3d753e562672dfed042ea2) Thanks [@​QiRaining](https://github.com/QiRaining)! - Preserve multi-byte UTF-8 characters split across multipart response chunks.
### [`v4.2.11`](https://github.com/apollographql/apollo-client/blob/HEAD/CHANGELOG.md#4211)
[Compare Source](https://github.com/apollographql/apollo-client/compare/@apollo/client@4.2.10...@apollo/client@4.2.11)
##### Patch Changes
- [#​13398](https://github.com/apollographql/apollo-client/pull/13398) [`3dd3e9a`](https://github.com/apollographql/apollo-client/commit/3dd3e9a6f195ea5dd27a973f153a0538ccdffd20) Thanks [@​phryneas](https://github.com/phryneas)! - Fix type signature of some `DocumentationTypes` to fix their display in our documentation.
- [#​13392](https://github.com/apollographql/apollo-client/pull/13392) [`d4f0771`](https://github.com/apollographql/apollo-client/commit/d4f0771976766b54e0a95a3d51b708b64eb3cfe0) Thanks [@​jerelmiller](https://github.com/jerelmiller)! - Add a development-only warning when a network result is written to the cache but reading the query back from the cache returns a partial result. This usually points at a `merge` or `read` function that did not repair missing fields in the cache, which prevents Apollo Client from applying the cache result to the data received by the network.
### [`v4.2.10`](https://github.com/apollographql/apollo-client/blob/HEAD/CHANGELOG.md#4210)
[Compare Source](https://github.com/apollographql/apollo-client/compare/@apollo/client@4.2.9...@apollo/client@4.2.10)
##### Patch Changes
- [#​13385](https://github.com/apollographql/apollo-client/pull/13385) [`bfb674e`](https://github.com/apollographql/apollo-client/commit/bfb674ec0ac9cd296b7ea2992d9deebf68edaea9) Thanks [@​jerelmiller](https://github.com/jerelmiller)! - Fix accidental widening of the `client.mutate` return type when `optimisticResponse` was present.
- [#​13382](https://github.com/apollographql/apollo-client/pull/13382) [`365373e`](https://github.com/apollographql/apollo-client/commit/365373e0a0b647e89183245c3904d58499aa63e1) Thanks [@​jerelmiller](https://github.com/jerelmiller)! - Fix result types widened when a query's variables had constant types (e.g. `TypedDocumentNode<Data, { type: "main" }>`). This caused options such as `returnPartialData` or `errorPolicy` to be reported as their widened types (e.g. `boolean`, `ErrorPolicy`) instead of the value that was passed which returned the wrong `data` and `dataState` types.
- [#​13382](https://github.com/apollographql/apollo-client/pull/13382) [`365373e`](https://github.com/apollographql/apollo-client/commit/365373e0a0b647e89183245c3904d58499aa63e1) Thanks [@​jerelmiller](https://github.com/jerelmiller)! - Fix issue where unknown options were permitted by TypeScript when passed alongside a valid option to APIs with modern signatures.
- [#​13383](https://github.com/apollographql/apollo-client/pull/13383) [`5840f50`](https://github.com/apollographql/apollo-client/commit/5840f5014d0a6bb9b963801657cd68b0a1aba6c8) Thanks [@​jerelmiller](https://github.com/jerelmiller)! - Update the return type of `refetch`, `fetchMore` and `useLazyQuery`'s `execute` function on the provided `errorPolicy`. Previously these APIs all used the default type which typed `data` as `TData | undefined` and `error` as `ErrorLike | undefined`.
### [`v4.2.9`](https://github.com/apollographql/apollo-client/blob/HEAD/CHANGELOG.md#429)
[Compare Source](https://github.com/apollographql/apollo-client/compare/@apollo/client@4.2.8...@apollo/client@4.2.9)
##### Patch Changes
- [#​13364](https://github.com/apollographql/apollo-client/pull/13364) [`2f383e7`](https://github.com/apollographql/apollo-client/commit/2f383e7e484ceaec72df205b52abf8430cc59891) Thanks [@​atharv-sys32](https://github.com/atharv-sys32)! - Fix a bug where GraphQL variable default values were not applied during cache reads when variables with defaults were explicitly set to `undefined`. This caused `@include`/`@skip` directives to throw "Invalid variable referenced" errors when the variable was passed as `undefined` instead of being omitted entirely.
- [#​13367](https://github.com/apollographql/apollo-client/pull/13367) [`2b39cc8`](https://github.com/apollographql/apollo-client/commit/2b39cc8b2e0a6b0a6c1dfc2f64fa2940c59b23bd) Thanks [@​jerelmiller](https://github.com/jerelmiller)! - Fix an issue where some `@export` queries would not react to cache updates when the fields keyed by exported variables were updated.
### [`v4.2.8`](https://github.com/apollographql/apollo-client/blob/HEAD/CHANGELOG.md#428)
[Compare Source](https://github.com/apollographql/apollo-client/compare/@apollo/client@4.2.7...@apollo/client@4.2.8)
##### Patch Changes
- [#​13349](https://github.com/apollographql/apollo-client/pull/13349) [`501a33b`](https://github.com/apollographql/apollo-client/commit/501a33bba831828da0398c994662582054272743) Thanks [@​jerelmiller](https://github.com/jerelmiller)! - Prevent the `setTimeout` in `connectToDevtools` that shows the devtools suggestion from firing when the user agent does not match Chrome or Firefox. This check was previously done inside the `setTimeout` which meant the timer was scheduled for environments where we'd never show the message anyways. For test environments, this could cause flaky tests when that `setTimeout` outlived the tests and ran after any virtual DOM was torn down and removed.
### [`v4.2.7`](https://github.com/apollographql/apollo-client/blob/HEAD/CHANGELOG.md#427)
[Compare Source](https://github.com/apollographql/apollo-client/compare/@apollo/client@4.2.6...@apollo/client@4.2.7)
##### Patch Changes
- [#​13320](https://github.com/apollographql/apollo-client/pull/13320) [`538c906`](https://github.com/apollographql/apollo-client/commit/538c906143c18dcc4fd9c29427413451fcd72c22) Thanks [@​jerelmiller](https://github.com/jerelmiller)! - Cleanup some unused internals. Please file an issue if you notice anything change.
### [`v4.2.6`](https://github.com/apollographql/apollo-client/blob/HEAD/CHANGELOG.md#426)
[Compare Source](https://github.com/apollographql/apollo-client/compare/@apollo/client@4.2.5...@apollo/client@4.2.6)
##### Patch Changes
- [#​13315](https://github.com/apollographql/apollo-client/pull/13315) [`a406cc9`](https://github.com/apollographql/apollo-client/commit/a406cc9669246972a8f067462422aec716b6213b) Thanks [@​fallintoplace](https://github.com/fallintoplace)! - Prevent relay multipart subscriptions from issuing a fetch request after serializing the request body fails.
- [#​13307](https://github.com/apollographql/apollo-client/pull/13307) [`abd0781`](https://github.com/apollographql/apollo-client/commit/abd07814bbe80d9307458a450dd28addf1d38ef1) Thanks [@​wolfie](https://github.com/wolfie)! - Speed up cache writes by avoiding a full AST `visit` of every written field to detect `@stream`. The check now runs only when the result carries stream info, and only inspects the field node's own directives. As a result, fields that merely contain `@stream` on a nested field are no longer treated as streamed themselves and now overwrite existing lists like regular fields instead of merging chunk-wise.
### [`v4.2.5`](https://github.com/apollographql/apollo-client/blob/HEAD/CHANGELOG.md#425)
[Compare Source](https://github.com/apollographql/apollo-client/compare/@apollo/client@4.2.4...@apollo/client@4.2.5)
##### Patch Changes
- [#​13302](https://github.com/apollographql/apollo-client/pull/13302) [`bb75dd3`](https://github.com/apollographql/apollo-client/commit/bb75dd3a42bab21a0ff14c4482a5cb99a61843eb) Thanks [@​tpict](https://github.com/tpict)! - Export `KeyArgsFunction` and `RelayFieldPolicy` types from public entrypoints.
### [`v4.2.4`](https://github.com/apollographql/apollo-client/blob/HEAD/CHANGELOG.md#424)
[Compare Source](https://github.com/apollographql/apollo-client/compare/@apollo/client@4.2.3...@apollo/client@4.2.4)
##### Patch Changes
- [#​13281](https://github.com/apollographql/apollo-client/pull/13281) [`e4df809`](https://github.com/apollographql/apollo-client/commit/e4df809e87a1d2b72728df53327f531f65411ed3) Thanks [@​jerelmiller](https://github.com/jerelmiller)! - Fixes an issue where `client.readFragment` and `client.readQuery` ignored the `optimistic` option when passed in the options object.
### [`v4.2.3`](https://github.com/apollographql/apollo-client/blob/HEAD/CHANGELOG.md#423)
[Compare Source](https://github.com/apollographql/apollo-client/compare/@apollo/client@4.2.2...@apollo/client@4.2.3)
##### Patch Changes
- [#​13254](https://github.com/apollographql/apollo-client/pull/13254) [`66e9dfc`](https://github.com/apollographql/apollo-client/commit/66e9dfcf7964345dac949ab4c6004460d224d1cf) Thanks [@​jerelmiller](https://github.com/jerelmiller)! - Add support for `graphql` v17 as a valid peer dependency.
### [`v4.2.2`](https://github.com/apollographql/apollo-client/blob/HEAD/CHANGELOG.md#422)
[Compare Source](https://github.com/apollographql/apollo-client/compare/@apollo/client@4.2.1...@apollo/client@4.2.2)
##### Patch Changes
- [#​13184](https://github.com/apollographql/apollo-client/pull/13184) [`c207b88`](https://github.com/apollographql/apollo-client/commit/c207b886026114943dc7f5c85e997a1938e74cfe) Thanks [@​audrius-savickas](https://github.com/audrius-savickas)! - Preserve referential equality of masked data on refetch when the result is deeply equal to the previous result.
### [`v4.2.1`](https://github.com/apollographql/apollo-client/blob/HEAD/CHANGELOG.md#4212)
[Compare Source](https://github.com/apollographql/apollo-client/compare/@apollo/client@4.2.0...@apollo/client@4.2.1)
##### Patch Changes
- [#​13400](https://github.com/apollographql/apollo-client/pull/13400) [`56ca81b`](https://github.com/apollographql/apollo-client/commit/56ca81b40962d1aeef3d753e562672dfed042ea2) Thanks [@​QiRaining](https://github.com/QiRaining)! - Preserve multi-byte UTF-8 characters split across multipart response chunks.
### [`v4.2.0`](https://github.com/apollographql/apollo-client/blob/HEAD/CHANGELOG.md#420)
[Compare Source](https://github.com/apollographql/apollo-client/compare/@apollo/client@4.1.9...@apollo/client@4.2.0)
##### Minor Changes
- [#​13132](https://github.com/apollographql/apollo-client/pull/13132) [`f3ce805`](https://github.com/apollographql/apollo-client/commit/f3ce805425d10a9666218a8e109288a2d46dcab1) Thanks [@​phryneas](https://github.com/phryneas)! - Introduce "classic" and "modern" method and hook signatures.
Apollo Client 4.2 introduces two signature styles for methods and hooks. All signatures previously present are now "classic" signatures, and a new set of "modern" signatures are added alongside them.
**Classic signatures** are the default and are identical to the signatures before Apollo Client 4.2, preserving backward compatibility. Classic signatures still work with manually specified TypeScript generics (e.g., `useSuspenseQuery<MyData>(...)`). However, manually specifying generics has been discouraged for a long time—instead, we recommend using `TypedDocumentNode` to automatically infer types, which provides more accurate results without any manual annotations.
**Modern signatures** automatically incorporate your declared `defaultOptions` into return types, providing more accurate types. Modern signatures infer types from the document node and do not support manually passing generic type arguments; TypeScript will produce a type error if you attempt to do so.
Methods and hooks automatically switch to modern signatures the moment any non-optional property is declared in `DeclareDefaultOptions`. The switch happens across all methods and hooks globally:
```ts
// apollo.d.ts
import "@apollo/client";
declare module "@apollo/client" {
namespace ApolloClient {
namespace DeclareDefaultOptions {
interface WatchQuery {
errorPolicy: "all"; // non-optional → modern signatures activated automatically
}
}
}
}
```
Users can also manually switch to modern signatures without declaring any `defaultOptions`, for example when wanting accurate type inference without relying on global `defaultOptions`:
```ts
// apollo.d.ts
import "@apollo/client";
declare module "@apollo/client" {
export interface TypeOverrides {
signatureStyle: "modern";
}
}
```
Users can do a global `DeclareDefaultOptions` type augmentation and then manually switch back to "classic" for migration purposes:
```ts
// apollo.d.ts
import "@apollo/client";
declare module "@apollo/client" {
export interface TypeOverrides {
signatureStyle: "classic";
}
}
```
Note that this is **not recommended for long-term use**. When combined with `DeclareDefaultOptions`, switching back to classic results in the same incorrect types as before Apollo Client 4.2—methods and hooks will not reflect the `defaultOptions` you've declared.
- [#​13130](https://github.com/apollographql/apollo-client/pull/13130) [`dd12231`](https://github.com/apollographql/apollo-client/commit/dd122316028b55307de4a40335512307c8fa916a) Thanks [@​jerelmiller](https://github.com/jerelmiller)! - Improve the accuracy of `client.query` return type to better detect the current `errorPolicy`. The `data` property is no longer nullable when the `errorPolicy` is `none`. This makes it possible to remove the `undefined` checks or optional chaining in most cases.
- [#​13210](https://github.com/apollographql/apollo-client/pull/13210) [`1f9a428`](https://github.com/apollographql/apollo-client/commit/1f9a4287eb1eeef2cc08c81c92961f1cecd0dbca) Thanks [@​jerelmiller](https://github.com/jerelmiller)! - Add support for automatic event-based refetching, such as window focus.
The `RefetchEventManager` class handles automatic refetches in response to events. Apollo Client provides built-in sources for window focus and network reconnect as `windowFocusSource` and `onlineSource`.
Event refetching is fully opt-in. Create and pass a `RefetchEventManager` instance to the `ApolloClient` constructor to activate the event listeners.
```ts
import {
ApolloClient,
InMemoryCache,
RefetchEventManager,
windowFocusSource,
onlineSource,
} from "@apollo/client";
const client = new ApolloClient({
link,
cache: new InMemoryCache(),
refetchEventManager: new RefetchEventManager({
sources: {
// Refetch when window is focused
windowFocus: windowFocusSource,
// Refetch when the user comes back online
online: onlineSource,
},
}),
});
```
By default, all active queries refetch when the events fire. Queries can opt out per-event or disable all event refetches:
```ts
// Skip refetch on window focus for this query, but keep `online`
useQuery(QUERY, {
refetchOn: { windowFocus: false },
});
// Disable all event-driven refetches for this query
useQuery(OTHER_QUERY, {
refetchOn: false,
});
// Enable every event for this query, regardless of defaultOptions
useQuery(LIVE_DASHBOARD, {
refetchOn: true,
});
// Dynamically enable or disable a refetch when the event fires
useQuery(LIVE_DASHBOARD, {
refetchOn: ({ source, payload }) => {
if (source === "windowFocus") {
// payload is the data associated with the event
return someCondition(payload);
}
return true;
},
});
// Dynamically enable or disable a refetch for a specific event
useQuery(LIVE_DASHBOARD, {
refetchOn: {
windowFocus: ({ payload }) => {
// payload is the data associated with the event
return someCondition(payload);
},
},
});
```
To enable per-query opt-in rather than opt-out, set `defaultOptions.watchQuery.refetchOn` to `false` and enable it per-query instead.
```ts
const client = new ApolloClient({
link,
cache,
refetchEventManager: new RefetchEventManager({
sources: { windowFocus: windowFocusSource },
}),
defaultOptions: {
watchQuery: { refetchOn: false },
},
});
// Only this query refetches on window focus
useQuery(DASHBOARD_QUERY, { refetchOn: { windowFocus: true } });
```
When `defaultOptions.watchQuery.refetchOn` and per-query `refetchOn` options are provided, the objects are merged together.
##### Custom events
You can also add your own custom events that trigger refetches. Register your event name and payload type using TypeScript module augmentation, then provide a source function that returns an Observable. The source's emitted value becomes the event's `payload`.
```ts
import { Observable } from "@apollo/client";
import { filter } from "rxjs";
import { AppState, AppStateStatus, Platform } from "react-native";
declare module "@apollo/client" {
interface RefetchEvents {
reactNativeAppStatus: AppStateStatus;
}
}
const refetchEventManager = new RefetchEventManager({
sources: {
reactNativeAppStatus: () => {
return new Observable((observer) => {
const subscription = AppState.addEventListener("change", (status) => {
observer.next(status);
});
return () => subscription.remove();
}).pipe(
filter((status) => Platform.OS !== "web" && status === "active")
);
},
},
});
// Disable per-query by setting the event to false
useQuery(QUERY, { refetchOn: { reactNativeAppStatus: false } });
```
##### Manually trigger an event refetch
Refetches can be triggered imperatively by calling `emit` with the event name and its payload (if any).
```ts
refetchEventManager.emit("reactNativeAppStatus", "active");
```
##### Sourceless events
A source that has no automatic detection logic but still wants imperative `emit` support can be declared as `true`. Type the event as `void` to omit the payload argument.
```ts
declare module "@apollo/client" {
interface RefetchEvents {
userTriggered: void;
}
}
const refetchEventManager = new RefetchEventManager({
sources: { userTriggered: true },
});
refetchEventManager.emit("userTriggered");
```
Note: Calling `emit` on an event without a registered source will log a warning and result in a no-op.
##### Custom handlers
When an event fires, the default handler calls `client.refetchQueries({ include: "active" })` filtered by each query's `refetchOn` setting. You can override the handler for an event to add your own custom filtering. For example, to refetch all queries, including `standby` queries, define a handler for the event:
```ts
const refetchEventManager = new RefetchEventManager({
// ...
handlers: {
userTriggered: ({ client, source, payload, matchesRefetchOn }) => {
return client.refetchQueries({
include: "all",
onQueryUpdated: (observableQuery) => {
return matchesRefetchOn(observableQuery);
},
});
},
},
});
```
Handlers must return either a `RefetchQueriesResult` or `void`. Returning `void` skips refetching for the event.
- [#​13232](https://github.com/apollographql/apollo-client/pull/13232) [`f1b541f`](https://github.com/apollographql/apollo-client/commit/f1b541fed4111028b6842727178288156582e669) Thanks [@​jerelmiller](https://github.com/jerelmiller)! - Version bump to `rc`.
- [#​13206](https://github.com/apollographql/apollo-client/pull/13206) [`08fccab`](https://github.com/apollographql/apollo-client/commit/08fccab68822e99c6edd539cb4162d1a3df4f4c9) Thanks [@​jerelmiller](https://github.com/jerelmiller)! - Extend the `defaultOptions` type-safety work to `client.mutate` and `useMutation`.
The `errorPolicy` option now flows through to the result types for mutations in the same way it already does for queries:
- `ApolloClient.MutateResult<TData, TErrorPolicy>` maps `errorPolicy` to the concrete shape of `data` and `error`:
- `"none"` → `{ data: TData; error?: never }`
- `"all"` → `{ data: TData | undefined; error?: ErrorLike }`
- `"ignore"` → `{ data: TData | undefined; error?: never }`
- `client.mutate` and `useMutation` pick up the declared `defaultOptions.mutate.errorPolicy` and the explicit `errorPolicy` on each call to narrow return types accordingly.
- `useMutation.Result.error` is narrowed to `undefined` when `errorPolicy` is `"ignore"`, since `client.mutate` never resolves with an error in that case.
`DeclareDefaultOptions.Mutate` already accepted `errorPolicy`; the new behavior is that once you declare it, hook and method return types reflect it:
```ts
// apollo.d.ts
import "@apollo/client";
declare module "@apollo/client" {
namespace ApolloClient {
namespace DeclareDefaultOptions {
interface Mutate {
errorPolicy: "all";
}
}
}
}
```
```ts
const result = await client.mutate({ mutation: MUTATION });
result.data;
// ^? TData | undefined
result.error;
// ^? ErrorLike | undefined
```
Setting `errorPolicy` on an individual call overrides the default for that call's return type.
- [#​13222](https://github.com/apollographql/apollo-client/pull/13222) [`b93c172`](https://github.com/apollographql/apollo-client/commit/b93c1723b4b7a9d1296ddd57035bc4fe39c8d971) Thanks [@​jerelmiller](https://github.com/jerelmiller)! - Extend the `defaultOptions` type-safety work to `preloadQuery` (returned from `createQueryPreloader`). Defaults declared in `DeclareDefaultOptions.WatchQuery` now work with `preloadQuery` to ensure the `PreloadedQueryRef`'s data states are correctly set.
```ts
// apollo.d.ts
import "@apollo/client";
declare module "@apollo/client" {
namespace ApolloClient {
namespace DeclareDefaultOptions {
interface WatchQuery {
errorPolicy: "all";
}
}
}
}
```
```ts
const preloadQuery = createQueryPreloader(client);
const queryRef = preloadQuery(QUERY);
// ^? PreloadedQueryRef<TData, TVariables, "complete" | "streaming" | "empty">
```
- [#​13132](https://github.com/apollographql/apollo-client/pull/13132) [`f3ce805`](https://github.com/apollographql/apollo-client/commit/f3ce805425d10a9666218a8e109288a2d46dcab1) Thanks [@​phryneas](https://github.com/phryneas)! - Synchronize method and hook return types with `defaultOptions`.
Prior to this change, the following code snippet would always apply:
```ts
declare const MY_QUERY: TypedDocumentNode<TData, TVariables>;
const result1 = useSuspenseQuery(MY_QUERY);
result1.data;
// ^? TData
const result2 = useSuspenseQuery(MY_QUERY, { errorPolicy: "all" });
result2.data;
// ^? TData | undefined
```
While these types are generally correct, if you were to set `errorPolicy: 'all'` as a default option, the type of `result.data` for the first query would remain `TData` instead of changing to `TData | undefined` to match the runtime behavior.
We are now enforcing that certain `defaultOptions` types need to be registered globally. This means that if you want to use `errorPolicy: 'all'` as a default option for a query, you will need to register its type like this:
```ts
// apollo.d.ts
import "@apollo/client";
declare module "@apollo/client" {
namespace ApolloClient {
namespace DeclareDefaultOptions {
interface WatchQuery {
// possible global-registered values:
// * `errorPolicy`
// * `returnPartialData`
errorPolicy: "all";
}
interface Query {
// possible global-registered values:
// * `errorPolicy`
}
interface Mutate {
// possible global-registered values:
// * `errorPolicy`
}
}
}
}
```
Once this type declaration is in place, the type of `result.data` in the above example will correctly be changed to `TData | undefined`, reflecting the possibility that if an error occurs, `data` might be `undefined`. Manually specifying `useSuspenseQuery(MY_QUERY, { errorPolicy: "none" });` changes `result.data` to `TData` to reflect the local override.
This change means that you will need to declare your default options types in order to use `defaultOptions` with `ApolloClient`, otherwise you will see a TypeScript error.
Without the type declaration, the following (previously valid) code will now error:
```ts
new ApolloClient({
link: ApolloLink.empty(),
cache: new InMemoryCache(),
defaultOptions: {
watchQuery: {
// results in a type error:
// Type '"all"' is not assignable to type '"A default option for watchQuery.errorPolicy must be declared in ApolloClient.DeclareDefaultOptions before usage. See https://www.apollographql.com/docs/react/data/typescript#declaring-default-options-for-type-safety."'.
errorPolicy: "all",
},
},
});
```
If you are creating multiple instances of Apollo Client with conflicting default options and you cannot register a single `defaultOptions` value as a result, you can relax the constraints by declaring those options as union types covering all values used by all clients. The properties can be required (to enforce them in `defaultOptions`) or optional (if some constructor calls won't pass a value):
```ts
// apollo.d.ts
import "@apollo/client";
declare module "@apollo/client" {
export namespace ApolloClient {
export namespace DeclareDefaultOptions {
interface WatchQuery {
errorPolicy?: "none" | "all" | "ignore";
returnPartialData?: boolean;
}
interface Query {
errorPolicy?: "none" | "all" | "ignore";
}
interface Mutate {
errorPolicy?: "none" | "all" | "ignore";
}
}
}
}
```
With this declaration, the `ApolloClient` constructor accepts any of those values in `defaultOptions`. The tradeoff is that hook and method return types become more generic. For example, calling `useSuspenseQuery` without an explicit `errorPolicy` will return a result typed as if all error policies are possible, since TypeScript can't know which specific value your instance uses at runtime.
Note that making a property optional (`errorPolicy?:`) is equivalent to adding the TypeScript default value (`"none"`) to the union. So `errorPolicy?: "all" | "ignore"` has the same effect on return types as `errorPolicy: "none" | "all" | "ignore"`, because TypeScript assumes the option could also be absent (i.e., `"none"`).
You can also use a **partial union** that only lists the values you actually use. For example, if you only ever use `"all"` or `"ignore"`, declare `errorPolicy: "all" | "ignore"` (required) to keep the union narrow and avoid unused values broadening your signatures unnecessarily.
##### Patch Changes
- [#​13217](https://github.com/apollographql/apollo-client/pull/13217) [`790f987`](https://github.com/apollographql/apollo-client/commit/790f987ed65435159dd2c6df5fe2fa01587a179e) Thanks [@​jerelmiller](https://github.com/jerelmiller)! - Fix the deprecation for the classic signatures for function overloads that rely on type inference from a `TypedDocumentNode`. The deprecation now only applies to classic signatures that provide explicit type arguments to encourage the use of `TypedDocumentNode`.
- [#​13166](https://github.com/apollographql/apollo-client/pull/13166) [`0537d97`](https://github.com/apollographql/apollo-client/commit/0537d97161a51479141a182d869458912e1b8e1d) Thanks [@​jerelmiller](https://github.com/jerelmiller)! - Release changes in 4.1.5 and 4.1.6.
- [#​13215](https://github.com/apollographql/apollo-client/pull/13215) [`54c9eb7`](https://github.com/apollographql/apollo-client/commit/54c9eb7f95d3cd12dc5d12ec27090f1f23b0c471) Thanks [@​jerelmiller](https://github.com/jerelmiller)! - Ensure the options object for the `useQuery`, `useSuspenseQuery`, and `useBackgroundQuery` hooks provide proper IntelliSense suggestions.
- [#​13229](https://github.com/apollographql/apollo-client/pull/13229) [`9a7f65a`](https://github.com/apollographql/apollo-client/commit/9a7f65a0059433c83307ef2d8117dac67947d791) Thanks [@​jerelmiller](https://github.com/jerelmiller)! - Fix `refetchOn` merging when `defaultOptions.watchQuery.refetchOn` is set to a non-object value (`false`, `true`, or a function) and the per-query `refetchOn` is an object. Previously the per-query object completely replaced the default so unspecified events fell back to "enabled" regardless of the default.
The `defaultOptions` value now applies to any event the per-query object does not explicitly configure:
- `false` - unspecified events stay disabled
- `true` - unspecified events refetch
- Callback function - the function is called for unspecified events to determine whether to refetch
```ts
const client = new ApolloClient({
// ...
defaultOptions: {
watchQuery: {
refetchOn: false,
},
},
});
// Only `windowFocus` refetches. Other events stay disabled per the default.
useQuery(QUERY, { refetchOn: { windowFocus: true } });
```
- [#​13230](https://github.com/apollographql/apollo-client/pull/13230) [`b25b659`](https://github.com/apollographql/apollo-client/commit/b25b6593f5d968db505b127e7ff7f2bb2419d5ee) Thanks [@​jerelmiller](https://github.com/jerelmiller)! - Add the ability to override the default event handler on `RefetchEventManager`. The default handler runs when no per-source handler is configured for an event. Provide a custom handler via the `defaultHandler` constructor option or the `setDefaultEventHandler` instance method.
```ts
new RefetchEventManager({
defaultHandler: ({ client, matchesRefetchOn }) => {
return client.refetchQueries({
include: "all",
onQueryUpdated: matchesRefetchOn,
});
},
});
```
### [`v4.1.9`](https://github.com/apollographql/apollo-client/blob/HEAD/CHANGELOG.md#419)
[Compare Source](https://github.com/apollographql/apollo-client/compare/@apollo/client@4.1.8...@apollo/client@4.1.9)
##### Patch Changes
- [#​13203](https://github.com/apollographql/apollo-client/pull/13203) [`099954b`](https://github.com/apollographql/apollo-client/commit/099954b9905c0f80b57563eb64157386f4493e84) Thanks [@​copilot-swe-agent](https://github.com/apps/copilot-swe-agent)! - Remove the `workspaces` field from the published `package.json` in `dist` to avoid Yarn v1 warnings about workspaces requiring private packages.
### [`v4.1.8`](https://github.com/apollographql/apollo-client/blob/HEAD/CHANGELOG.md#418)
[Compare Source](https://github.com/apollographql/apollo-client/compare/@apollo/client@4.1.7...@apollo/client@4.1.8)
##### Patch Changes
- [#​13202](https://github.com/apollographql/apollo-client/pull/13202) [`8a51ea6`](https://github.com/apollographql/apollo-client/commit/8a51ea636600dbe4b48477d32f30469b7d36b152) Thanks [@​phryneas](https://github.com/phryneas)! - Ship agent skill for usage with [@​tanstack/intent](https://github.com/tanstack/intent) — the skill is now bundled in the npm package under `skills/apollo-client/` and discoverable by `intent list`.
For more context, see the [TanStack Intent QuickStart](https://tanstack.com/intent/latest/docs/getting-started/quick-start-consumers).
### [`v4.1.7`](https://github.com/apollographql/apollo-client/blob/HEAD/CHANGELOG.md#417)
[Compare Source](https://github.com/apollographql/apollo-client/compare/@apollo/client@4.1.6...@apollo/client@4.1.7)
##### Patch Changes
- [#​13187](https://github.com/apollographql/apollo-client/pull/13187) [`bb3fd9b`](https://github.com/apollographql/apollo-client/commit/bb3fd9b3d40a2505add673a6ee89d85b8b4c8984) Thanks [@​jerelmiller](https://github.com/jerelmiller)! - Fix RxJS interop issue with the observable returned by `WebSocketLink`.
### [`v4.1.6`](https://github.com/apollographql/apollo-client/blob/HEAD/CHANGELOG.md#416)
[Compare Source](https://github.com/apollographql/apollo-client/compare/@apollo/client@4.1.5...@apollo/client@4.1.6)
##### Patch Changes
- [#​13128](https://github.com/apollographql/apollo-client/pull/13128) [`6c0b8e4`](https://github.com/apollographql/apollo-client/commit/6c0b8e4301609b62ed599340589c978e4f51f020) Thanks [@​pavelivanov](https://github.com/pavelivanov)! - Fix `useQuery` hydration mismatch when `ssr: false` and `skip: true` are used together
When both options were combined, the server would return `loading: false` (because `useSSRQuery` checks `skip` first), but the client's `getServerSnapshot` was returning `ssrDisabledResult` with `loading: true`, causing a hydration mismatch.
### [`v4.1.5`](https://github.com/apollographql/apollo-client/blob/HEAD/CHANGELOG.md#415)
[Compare Source](https://github.com/apollographql/apollo-client/compare/@apollo/client@4.1.4...@apollo/client@4.1.5)
##### Patch Changes
- [#​13155](https://github.com/apollographql/apollo-client/pull/13155) [`3ba1583`](https://github.com/apollographql/apollo-client/commit/3ba1583f93c40343501acd9d598ce506537d1c9b) Thanks [@​jerelmiller](https://github.com/jerelmiller)! - Fix an issue where `useQuery` would poll with `pollInterval` when `skip` was initialized to `true`.
- [#​13135](https://github.com/apollographql/apollo-client/pull/13135) [`fd42142`](https://github.com/apollographql/apollo-client/commit/fd42142495d24859a9bc7145a85bc8f8d857ec88) Thanks [@​jerelmiller](https://github.com/jerelmiller)! - Fix issue where `client.query` would apply options from `defaultOptions.watchQuery`.
### [`v4.1.4`](https://github.com/apollographql/apollo-client/blob/HEAD/CHANGELOG.md#414)
[Compare Source](https://github.com/apollographql/apollo-client/compare/@apollo/client@4.1.3...@apollo/client@4.1.4)
##### Patch Changes
- [#​13124](https://github.com/apollographql/apollo-client/pull/13124) [`578081f`](https://github.com/apollographql/apollo-client/commit/578081f2da7f2f54c0dd2711ee4a97530a5c38fc) Thanks [@​Re-cool](https://github.com/Re-cool)! - Ensure `PersistedQueryLink` merges `http` and `fetchOptions` context values instead of overwriting them.
### [`v4.1.3`](https://github.com/apollographql/apollo-client/blob/HEAD/CHANGELOG.md#413)
[Compare Source](https://github.com/apollographql/apollo-client/compare/@apollo/client@4.1.2...@apollo/client@4.1.3)
##### Patch Changes
- [#​13111](https://github.com/apollographql/apollo-client/pull/13111) [`bf46fe0`](https://github.com/apollographql/apollo-client/commit/bf46fe019b316ea8a87a05981a89fac5411260b4) Thanks [@​RogerHYang](https://github.com/RogerHYang)! - Fix `createFetchMultipartSubscription` to support cancellation via `AbortController`
Previously, calling `dispose()` or `unsubscribe()` on a subscription created by `createFetchMultipartSubscription` had no effect - the underlying fetch request would continue running until completion. This was because no `AbortController` was created or passed to `fetch()`, and no cleanup function was returned from the Observable.
### [`v4.1.2`](https://github.com/apollographql/apollo-client/blob/HEAD/CHANGELOG.md#412)
[Compare Source](https://github.com/apollographql/apollo-client/compare/@apollo/client@4.1.1...@apollo/client@4.1.2)
##### Patch Changes
- [#​13105](https://github.com/apollographql/apollo-client/pull/13105) [`8b62263`](https://github.com/apollographql/apollo-client/commit/8b62263e19b3442e20fea822de62074cf4f5cb22) Thanks [@​phryneas](https://github.com/phryneas)! - `ssrMode`, `ssrForceFetchDelay` or `prioritizeCacheValues` should not override `fetchPolicy: 'cache-only'`, `fetchPolicy: 'no-cache'`, `fetchPolicy: 'standby'`, `skip: true`, or `skipToken` when reading the initial value of an `ObservableQuery`.
- [#​13105](https://github.com/apollographql/apollo-client/pull/13105) [`8b62263`](https://github.com/apollographql/apollo-client/commit/8b62263e19b3442e20fea822de62074cf4f5cb22) Thanks [@​phryneas](https://github.com/phryneas)! - Fix `skipToken` in `useQuery` with `prerenderStatic` and related SSR functions.
- [#​13105](https://github.com/apollographql/apollo-client/pull/13105) [`8b62263`](https://github.com/apollographql/apollo-client/commit/8b62263e19b3442e20fea822de62074cf4f5cb22) Thanks [@​phryneas](https://github.com/phryneas)! - Avoid fetches with `fetchPolicy: no-cache` in `useQuery` with `prerenderStatic` and related SSR functions.
### [`v4.1.1`](https://github.com/apollographql/apollo-client/blob/HEAD/CHANGELOG.md#411)
[Compare Source](https://github.com/apollographql/apollo-client/compare/@apollo/client@4.1.0...@apollo/client@4.1.1)
##### Patch Changes
- [#​13103](https://github.com/apollographql/apollo-client/pull/13103) [`dee7dcf`](https://github.com/apollographql/apollo-client/commit/dee7dcff4d4baa26d623d1ecace60be88c684c1a) Thanks [@​jerelmiller](https://github.com/jerelmiller)! - Ensure `@client` fields that are children of aliased server fields are resolved correctly.
### [`v4.1.0`](https://github.com/apollographql/apollo-client/blob/HEAD/CHANGELOG.md#410)
[Compare Source](https://github.com/apollographql/apollo-client/compare/@apollo/client@4.0.13...@apollo/client@4.1.0)
##### Minor Changes
- [#​13043](https://github.com/apollographql/apollo-client/pull/13043) [`65e66ca`](https://github.com/apollographql/apollo-client/commit/65e66cafb6828b63d14b64877bbad47af95f66e4) Thanks [@​jerelmiller](https://github.com/jerelmiller)! - Support `headers` transport for enhanced client awareness.
- [#​12927](https://github.com/apollographql/apollo-client/pull/12927) [`785e223`](https://github.com/apollographql/apollo-client/commit/785e2232b4f7d9e561611cd4f45b8fdd1e44319e) Thanks [@​jerelmiller](https://github.com/jerelmiller)! - You can now provide a callback function as the `context` option on the `mutate` function returned by `useMutation`. The callback function is called with the value of the `context` option provided to the `useMutation` hook. This is useful if you'd like to merge the context object provided to the `useMutation` hook with a value provided to the `mutate` function.
```ts
function MyComponent() {
const [mutate, result] = useMutation(MUTATION, {
context: { foo: true },
});
async function runMutation() {
await mutate({
// sends context as { foo: true, bar: true }
context: (hookContext) => ({ ...hookContext, bar: true }),
});
}
// ...
}
```
- [#​12923](https://github.com/apollographql/apollo-client/pull/12923) [`94ea3e3`](https://github.com/apollographql/apollo-client/commit/94ea3e32c82dd767b62a6907be6c3891864633af) Thanks [@​jerelmiller](https://github.com/jerelmiller)! - Fix an issue where deferred payloads that returned arrays with fewer items than the original cached array would retain items from the cached array. This change includes `@stream` arrays where stream arrays replace the cached arrays.
- [#​12927](https://github.com/apollographql/apollo-client/pull/12927) [`96b531f`](https://github.com/apollographql/apollo-client/commit/96b531f6b57a158aa2c57da976c6dd22c1a7f4d5) Thanks [@​jerelmiller](https://github.com/jerelmiller)! - Don't set the fallback value of a `@client` field to `null` when a `read` function is defined. Instead the `read` function will be called with an `existing` value of `undefined` to allow default arguments to be used to set the returned value.
When a `read` function is not defined nor is there a defined resolver for the field, warn and set the value to `null` only in that instance.
- [#​12927](https://github.com/apollographql/apollo-client/pull/12927) [`45ebb52`](https://github.com/apollographql/apollo-client/commit/45ebb52bcb84b81ce3a066204456c2e20f3d4c98) Thanks [@​jerelmiller](https://github.com/jerelmiller)! - Add support for `from: null` in `client.watchFragment` and `cache.watchFragment`. When `from` is `null`, the emitted result is:
```ts
{
data: null,
dataState: "complete",
complete: true,
}
```
- [#​12926](https://github.com/apollographql/apollo-client/pull/12926) [`2b7f2c1`](https://github.com/apollographql/apollo-client/commit/2b7f2c167fc4a94e06457777f0c57b6dac7b2f2f) Thanks [@​jerelmiller](https://github.com/jerelmiller)! - Support the newer incremental delivery format for the `@defer` directive implemented in `graphql@17.0.0-alpha.9`. Import the `GraphQL17Alpha9Handler` to use the newer incremental delivery format with `@defer`.
```ts
import { GraphQL17Alpha9Handler } from "@apollo/client/incremental";
const client = new ApolloClient({
// ...
incrementalHandler: new GraphQL17Alpha9Handler(),
});
```
> \[!NOTE]
> In order to use the `GraphQL17Alpha9Handler`, the GraphQL server MUST implement the newer incremental delivery format. You may see errors or unusual behavior if you use the wrong handler. If you are using Apollo Router, continue to use the `Defer20220824Handler` because Apollo Router does not yet support the newer incremental delivery format.
- [#​12927](https://github.com/apollographql/apollo-client/pull/12927) [`45ebb52`](https://github.com/apollographql/apollo-client/commit/45ebb52bcb84b81ce3a066204456c2e20f3d4c98) Thanks [@​jerelmiller](https://github.com/jerelmiller)! - Add support for arrays with `useFragment`, `useSuspenseFragment`, and `client.watchFragment`. This allows the ability to use a fragment to watch multiple entities in the cache. Passing an array to `from` will return `data` as an array where each array index corresponds to the index in the `from` array.
```ts
function MyComponent() {
const result = useFragment({
fragment,
from: [item1, item2, item3],
});
// `data` is an array with 3 items
console.log(result); // { data: [{...}, {...}, {...}], dataState: "complete", complete: true }
}
```
- [#​12927](https://github.com/apollographql/apollo-client/pull/12927) [`45ebb52`](https://github.com/apollographql/apollo-client/commit/45ebb52bcb84b81ce3a066204456c2e20f3d4c98) Thanks [@​jerelmiller](https://github.com/jerelmiller)! - Add a `getCurrentResult` function to the observable returned by `client.watchFragment` and `cache.watchFragment` that returns the current value for the watched fragment.
```ts
const observable = client.watchFragment({
fragment,
from: { __typename: "Item", id: 1 },
});
console.log(observable.getCurrentResult());
// {
// data: {...},
// dataState: "complete",
// complete: true,
// }
```
- [#​13038](https://github.com/apollographql/apollo-client/pull/13038) [`109efe7`](https://github.com/apollographql/apollo-client/commit/109efe7e4380b579c6a577982bd9a6e8c6a53892) Thanks [@​jerelmiller](https://github.com/jerelmiller)! - Add the `from` option to `readFragment`, `watchFragment`, and `updateFragment`.
- [#​12918](https://github.com/apollographql/apollo-client/pull/12918) [`2e224b9`](https://github.com/apollographql/apollo-client/commit/2e224b99894432822f926fdfec36bd46dd73b35e) Thanks [@​jerelmiller](https://github.com/jerelmiller)! - Add support for the `@stream` directive on both the `Defer20220824Handler` and the `GraphQL17Alpha2Handler`.
> \[!NOTE]
> The implementations of `@stream` differ in the delivery of incremental results between the different GraphQL spec versions. If you upgrading from the older format to the newer format, expect the timing of some incremental results to change.
- [#​13056](https://github.com/apollographql/apollo-client/pull/13056) [`b224efc`](https://github.com/apollographql/apollo-client/commit/b224efc25515370c68b514405762e68a443e4a4a) Thanks [@​jerelmiller](https://github.com/jerelmiller)! - `InMemoryCache` no longer filters out explicitly returned `undefined` items from `read` functions for array fields. This now makes it possible to create `read` functions on array fields that return partial data and trigger a fetch for the full list.
- [#​13058](https://github.com/apollographql/apollo-client/pull/13058) [`121a2cb`](https://github.com/apollographql/apollo-client/commit/121a2cb68820727186ecd74ce1041ef95284682e) Thanks [@​jerelmiller](https://github.com/jerelmiller)! - Add an `extensions` option to `cache.write`, `cache.writeQuery`, and `client.writeQuery`. This makes `extensions` available in cache `merge` functions which can be accessed with the other merge function options.
As a result of this change, any `extensions` returned in GraphQL operations are now available in `merge` in the cache writes for these operations.
- [#​12927](https://github.com/apollographql/apollo-client/pull/12927) [`96b531f`](https://github.com/apollographql/apollo-client/commit/96b531f6b57a158aa2c57da976c6dd22c1a7f4d5) Thanks [@​jerelmiller](https://github.com/jerelmiller)! - Add an abstract `resolvesClientField` function to `ApolloCache` that can be used by caches to tell `LocalState` if it can resolve a `@client` field when a local resolver is not defined.
`LocalState` will emit a warning and set a fallback value of `null` when no local resolver is defined and `resolvesClientField` returns `false`, or isn't defined. Returning `true` from `resolvesClientField` signals that a mechanism in the cache will set the field value. In this case, `LocalState` won't set the field value.
- [#​13078](https://github.com/apollographql/apollo-client/pull/13078) [`bf1e0dc`](https://github.com/apollographql/apollo-client/commit/bf1e0dcb2f6c9b94576dc6d049745f1869cd0043) Thanks [@​phryneas](https://github.com/phryneas)! - Use the default stream merge function for `@stream` fields only if stream info is present. This change means that using the older `Defer20220824Handler` will not use the default stream merge function and will instead truncate the streamed array on the first chunk.
##### Patch Changes
- [#​12884](https://github.com/apollographql/apollo-client/pull/12884) [`d329790`](https://github.com/apollographql/apollo-client/commit/d32979070381f1897c90fb276e25a0c8375cc29a) Thanks [@​phryneas](https://github.com/phryneas)! - Ensure that `PreloadedQueryRef` instances are unsubscribed when garbage collected
- [#​13086](https://github.com/apollographql/apollo-client/pull/13086) [`1a1d408`](https://github.com/apollographql/apollo-client/commit/1a1d4088f549088d4af3ff1f2d08d1c8e9af2a4d) Thanks [@​phryneas](https://github.com/phryneas)! - Change the returned value from `null` to `{}` when all fields in a query were skipped.
This also fixes a bug where `useSuspenseQuery` would suspend indefinitely when all fields were skipped.
- [#​13010](https://github.com/apollographql/apollo-client/pull/13010) [`7627000`](https://github.com/apollographql/apollo-client/commit/76270002254b0c6acb18872a39ab180f9f1e4067) Thanks [@​jerelmiller](https://github.com/jerelmiller)! - Fix an issue where errors parsed from incremental chunks in `ErrorLink` might throw when using the `GraphQL17Alpha9Handler`.
- [#​12927](https://github.com/apollographql/apollo-client/pull/12927) [`45ebb52`](https://github.com/apollographql/apollo-client/commit/45ebb52bcb84b81ce3a066204456c2e20f3d4c98) Thanks [@​jerelmiller](https://github.com/jerelmiller)! - Deduplicate watches created by `useFragment`, `client.watchFragment`, and `cache.watchFragment` that contain the same fragment, variables, and identifier. This should improve performance in situations where a `useFragment` or a `client.watchFragment` is used to watch the same object in multiple places of an application.
- [#​12927](https://github.com/apollographql/apollo-client/pull/12927) [`259ae9b`](https://github.com/apollographql/apollo-client/commit/259ae9bafaa8122996b0a52dd99828b2261087e5) Thanks [@​jerelmiller](https://github.com/jerelmiller)! - Allow `FragmentType` not only to be called as `FragmentType<TData>`, but also as `FragmentType<TypedDocumentNode>`.
- [#​12925](https://github.com/apollographql/apollo-client/pull/12925) [`5851800`](https://github.com/apollographql/apollo-client/commit/58518000edebb2a4b75c36ed22e9b67b3a254fa0) Thanks [@​jerelmiller](https://github.com/jerelmiller)! - Fix an issue where calling `fetchMore` with `@defer` or `@stream` would not rerender incremental results as they were streamed.
- [#​12927](https://github.com/apollographql/apollo-client/pull/12927) [`9e55188`](https://github.com/apollographql/apollo-client/commit/9e55188adcb4cf4236b14eb552286a4505650a29) Thanks [@​jerelmiller](https://github.com/jerelmiller)! - Truncate `@stream` arrays only on last chunk by default.
- [#​13083](https://github.com/apollographql/apollo-client/pull/13083) [`f3c2be1`](https://github.com/apollographql/apollo-client/commit/f3c2be1665d8e2e260a4f55ec803d6e609748390) Thanks [@​phryneas](https://github.com/phryneas)! - Expose the `ExtensionsWithStreamInfo` type for `extensions` in `Cache.writeQuery`, `Cache.write` and `Cache.update` so other cache implementations also can correctly access them.
- [#​12923](https://github.com/apollographql/apollo-client/pull/12923) [`94ea3e3`](https://github.com/apollographql/apollo-client/commit/94ea3e32c82dd767b62a6907be6c3891864633af) Thanks [@​jerelmiller](https://github.com/jerelmiller)! - Improve the cache data loss warning message when `existing` or `incoming` is an array.
- [#​12927](https://github.com/apollographql/apollo-client/pull/12927) [`4631175`](https://github.com/apollographql/apollo-client/commit/46311758f703ec7baa9013a49b897e823fd4edb0) Thanks [@​jerelmiller](https://github.com/jerelmiller)! - Ignore top-level `data` values on subsequent chunks in incremental responses.
- [#​12927](https://github.com/apollographql/apollo-client/pull/12927) [`2be8de2`](https://github.com/apollographql/apollo-client/commit/2be8de26f1bb68d2d6cd0d286565d47455332b47) Thanks [@​jerelmiller](https://github.com/jerelmiller)! - Create mechanism to add experimental features to Apollo Client
- [#​12927](https://github.com/apollographql/apollo-client/pull/12927) [`96b531f`](https://github.com/apollographql/apollo-client/commit/96b531f6b57a158aa2c57da976c6dd22c1a7f4d5) Thanks [@​jerelmiller](https://github.com/jerelmiller)! - Ensure `LocalState` doesn't try to read from the cache when using a `no-cache` fetch policy.
- [#​12927](https://github.com/apollographql/apollo-client/pull/12927) [`bb8ed7b`](https://github.com/apollographql/apollo-client/commit/bb8ed7b6b7e36e313822e44b230e27031d6fcbd9) Thanks [@​jerelmiller](https://github.com/jerelmiller)! - Ensure an error is thrown when `@stream` is detected and an `incrementalDelivery` handler is not configured.
- [#​13053](https://github.com/apollographql/apollo-client/pull/13053) [`23ca0ba`](https://github.com/apollographql/apollo-client/commit/23ca0ba895473b397805e6bcc70e0fcf987547c5) Thanks [@​phryneas](https://github.com/phryneas)! - Use memoized observable mapping when using `watchFragment`, `useFragment` or `useSuspenseFragment`.
- [#​12927](https://github.com/apollographql/apollo-client/pull/12927) [`44706a2`](https://github.com/apollographql/apollo-client/commit/44706a2e7ae2c977fa917214a1ff5e5fe4a9b3a7) Thanks [@​jerelmiller](https://github.com/jerelmiller)! - Add helper type `QueryRef.ForQuery<TypedDocumentNode>`
- [#​13082](https://github.com/apollographql/apollo-client/pull/13082) [`c257418`](https://github.com/apollographql/apollo-client/commit/c2574181f6b0d9ae059dfa3822a7842ec5f8ff1f) Thanks [@​phryneas](https://github.com/phryneas)! - Pass `streamInfo` through result extensions as a `WeakRef`.
- [#​12927](https://github.com/apollographql/apollo-client/pull/12927) [`4631175`](https://github.com/apollographql/apollo-client/commit/46311758f703ec7baa9013a49b897e823fd4edb0) Thanks [@​jerelmiller](https://github.com/jerelmiller)! - Fix the `Defer20220824Handler.SubsequentResult` type to match the `FormattedSubsequentIncrementalExecutionResult` type in `graphql@17.0.0-alpha.2`.
- [#​12927](https://github.com/apollographql/apollo-client/pull/12927) [`96b531f`](https://github.com/apollographql/apollo-client/commit/96b531f6b57a158aa2c57da976c6dd22c1a7f4d5) Thanks [@​jerelmiller](https://github.com/jerelmiller)! - Warn when using a `no-cache` fetch policy without a local resolver defined. `no-cache` queries do not read or write to the cache which meant `no-cache` queries are silently incomplete when the `@client` field value was handled by a cache `read` function.
- [#​12927](https://github.com/apollographql/apollo-client/pull/12927) [`5776ea0`](https://github.com/apollographql/apollo-client/commit/5776ea0db1f082663dcf470c3b22b9182a3eea28) Thanks [@​jerelmiller](https://github.com/jerelmiller)! - Update the `accept` header used with the `GraphQL17Alpha9Handler` to `multipart/mixed;incrementalSpec=v0.2` to ensure the newest incremental delivery format is requested.
- [#​12927](https://github.com/apollographql/apollo-client/pull/12927) [`45ebb52`](https://github.com/apollographql/apollo-client/commit/45ebb52bcb84b81ce3a066204456c2e20f3d4c98) Thanks [@​jerelmiller](https://github.com/jerelmiller)! - `DeepPartial<Array<TData>>` now returns `Array<DeepPartial<TData>>` instead of `Array<DeepPartial<TData | undefined>>`.
- [#​13071](https://github.com/apollographql/apollo-client/pull/13071) [`99ffe9a`](https://github.com/apollographql/apollo-client/commit/99ffe9a8ede1683d902101c5371807a8442fcdcb) Thanks [@​phryneas](https://github.com/phryneas)! - `prerenderStatic`: Expose return value of `renderFunction` to userland, fix `aborted` property.
This enables usage of `resumeAndPrerender` with React 19.2.
- [#​13026](https://github.com/apollographql/apollo-client/pull/13026) [`05eee67`](https://github.com/apollographql/apollo-client/commit/05eee67e91b480252923879987534e81d2866aba) Thanks [@​jerelmiller](https://github.com/jerelmiller)! - Reduce the number of observables created by `watchFragment` by reusing existing observables as much as possible. This should improve performance when watching the same item in the cache multiple times after a cache update occurs.
- [#​13010](https://github.com/apollographql/apollo-client/pull/13010) [`7627000`](https://github.com/apollographql/apollo-client/commit/76270002254b0c6acb18872a39ab180f9f1e4067) Thanks [@​jerelmiller](https://github.com/jerelmiller)! - Handle `@stream` payloads that send multiple items in the same chunk when using the `Defer20220824Handler`.
- [#​13010](https://github.com/apollographql/apollo-client/pull/13010) [`7627000`](https://github.com/apollographql/apollo-client/commit/76270002254b0c6acb18872a39ab180f9f1e4067) Thanks [@​jerelmiller](https://github.com/jerelmiller)! - Handle an edge case with the `Defer20220824Handler` where an error for a `@stream` item that bubbles to the `@stream` boundary (such as an item returning `null` for a non-null array item) would write items from future chunks to the wrong array index. In these cases, the `@stream` field is no longer processed and future updates to the field are ignored. This prevents runtime errors that TypeScript would otherwise not be able to catch.
- [#​13081](https://github.com/apollographql/apollo-client/pull/13081) [`1e06ad7`](https://github.com/apollographql/apollo-client/commit/1e06ad7399716139fcfbec7423697eafc5750f5e) Thanks [@​jerelmiller](https://github.com/jerelmiller)! - Avoid calling `merge` functions more than once for the same incremental chunk.
### [`v4.0.13`](https://github.com/apollographql/apollo-client/blob/HEAD/CHANGELOG.md#4013)
[Compare Source](https://github.com/apollographql/apollo-client/compare/@apollo/client@4.0.12...@apollo/client@4.0.13)
##### Patch Changes
- [#​13094](https://github.com/apollographql/apollo-client/pull/13094) [`9cbe2c2`](https://github.com/apollographql/apollo-client/commit/9cbe2c2dd2282ac861327d3c394578db7706df05) Thanks [@​phryneas](https://github.com/phryneas)! - Ensure that `compact` and `mergeOptions` preserve symbol keys.
This fixes an issue where the change introduced in 4.0.11 via [#​13049](https://github.com/apollographql/apollo-client/issues/13049) would not
be applied if `defaultOptions` for `watchQuery` were declared.
Please note that `compact` and `mergeOptions` are considered internal utilities
and they might have similar behavior changes in future releases.
Do not use them in your application code - a change like this is not considered
breaking and will not be announced as such.
### [`v4.0.12`](https://github.com/apollographql/apollo-client/blob/HEAD/CHANGELOG.md#4012-beta0)
[Compare Source](https://github.com/apollographql/apollo-client/compare/@apollo/client@4.0.11...@apollo/client@4.0.12)
##### Patch Changes
- [#​12884](https://github.com/apollographql/apollo-client/pull/12884) [`d329790`](https://github.com/apollographql/apollo-client/commit/d32979070381f1897c90fb276e25a0c8375cc29a) Thanks [@​phryneas](https://github.com/phryneas)! - Ensure that `PreloadedQueryRef` instances are unsubscribed when garbage collected
- [#​13069](https://github.com/apollographql/apollo-client/pull/13069) [`9cad04a`](https://github.com/apollographql/apollo-client/commit/9cad04a4228a5059ea330ac9d284407a363fc10d) Thanks [@​jerelmiller](https://github.com/jerelmiller)! - Truncate [@​stream](https://github.com/stream) arrays only on last chunk by default
### [`v4.0.11`](https://github.com/apollographql/apollo-client/blob/HEAD/CHANGELOG.md#4011)
[Compare Source](https://github.com/apollographql/apollo-client/compare/@apollo/client@4.0.10...@apollo/client@4.0.11)
##### Patch Changes
- [#​13050](https://github.com/apollographql/apollo-client/pull/13050) [`8020829`](https://github.com/apollographql/apollo-client/commit/8020829d8a3bdb3219a37e8d1f7b89179f721037) Thanks [@​phryneas](https://github.com/phryneas)! - Replace usage of `findLast` with more backwards-compatible methods.
- [#​13049](https://github.com/apollographql/apollo-client/pull/13049) [`05638de`](https://github.com/apollographql/apollo-client/commit/05638deaf598c5bf5d03b82d7deaf57468546229) Thanks [@​phryneas](https://github.com/phryneas)! - Fixes an issue where queries starting with `skipToken` or lazy queries from `useLazyQuery` were included in `client.refetchQueries()` before they had been executed for the first time. While generally queries with a `standby` `fetchPolicy` should be included in refetch, these queries never had `variables` passed in, so they should be excluded until they have run once and received their actual variables.
These queries are now properly excluded from refetch operations until after their initial execution.
This change adds a new hidden option to `client.watchQuery`, `[variablesUnknownSymbol]`, which may be set `true` for queries starting with a `fetchPolicy` of `standby`. It will only be applied when creating the `ObservableQuery` instance and cannot be changed later. This flag indicates that the query's variables are not yet known, and thus it should be excluded from refetch operations until they are.
**This option is not meant for everyday use and is intended for framework integrations only.**
### [`v4.0.10`](https://github.com/apollographql/apollo-client/blob/HEAD/CHANGELOG.md#4010)
[Compare Source](https://github.com/apollographql/apollo-client/compare/@apollo/client@4.0.9...@apollo/client@4.0.10)
##### Patch Changes
- [#​13045](https://github.com/apollographql/apollo-client/pull/13045) [`af4acdc`](https://github.com/apollographql/apollo-client/commit/af4acdc88bd3bac0d697ab300816241e4065842c) Thanks [@​phryneas](https://github.com/phryneas)! - Fix memory leak [#​13036](https://github.com/apollographql/apollo-client/issues/13036)
### [`v4.0.9`](https://github.com/apollographql/apollo-client/blob/HEAD/CHANGELOG.md#409)
[Compare Source](https://github.com/apollographql/apollo-client/compare/@apollo/client@4.0.8...@apollo/client@4.0.9)
##### Patch Changes
- [#​12993](https://github.com/apollographql/apollo-client/pull/12993) [`8f3bc9b`](https://github.com/apollographql/apollo-client/commit/8f3bc9b7253a737062dc0d652cd4f8b354f68ccc) Thanks [@​jerelmiller](https://github.com/jerelmiller)! - Fix an issue where switching from options with `variables` to `skipToken` with `useSuspenseQuery` and `useBackgroundQuery` would create a new `ObservableQuery`. This could cause unintended refetches where `variables` were absent in the request when the query was referenced with `refetchQueries`.
### [`v4.0.8`](https://github.com/apollographql/apollo-client/blob/HEAD/CHANGELOG.md#408)
[Compare Source](https://github.com/apollographql/apollo-client/compare/@apollo/client@4.0.7...@apollo/client@4.0.8)
##### Patch Changes
- [#​12983](https://github.com/apollographql/apollo-client/pull/12983) [`f6d0efa`](https://github.com/apollographql/apollo-client/commit/f6d0efac4d99375c67255aee6d9b2981753b6f55) Thanks [@​CarsonF](https://github.com/CarsonF)! - Fix cache.modify() mapping readonly arrays to singular reference
### [`v4.0.7`](https://github.com/apollographql/apollo-client/blob/HEAD/CHANGELOG.md#407)
[Compare Source](https://github.com/apollographql/apollo-client/compare/@apollo/client@4.0.6...@apollo/client@4.0.7)
##### Patch Changes
- [#​12950](https://github.com/apollographql/apollo-client/pull/12950) [`5b4f36a`](https://github.com/apollographql/apollo-client/commit/5b4f36a2b249d15e2e8165bd32d9b2fca7e70217) Thanks [@​jerelmiller](https://github.com/jerelmiller)! - Don't send `operationType` in the payload sent by `GraphQLWsLink`.
### [`v4.0.6`](https://github.com/apollographql/apollo-client/blob/HEAD/CHANGELOG.md#406)
[Compare Source](https://github.com/apollographql/apollo-client/compare/@apollo/client@4.0.5...@apollo/client@4.0.6)
##### Patch Changes
- [#​12937](https://github.com/apollographql/apollo-client/pull/12937) [`3b0d89b`](https://github.com/apollographql/apollo-client/commit/3b0d89bc9dde3eaee9ddf0aec387da43fe71abc0) Thanks [@​phryneas](https://github.com/phryneas)! - Fix a problem with `fetchMore` where the loading state wouldn't reset if the result wouldn't result in a data update.
### [`v4.0.5`](https://github.com/apollographql/apollo-client/blob/HEAD/CHANGELOG.md#405)
[Compare Source](https://github.com/apollographql/apollo-client/compare/@apollo/client@4.0.4...@apollo/client@4.0.5)
##### Patch Changes
- [#​12920](https://github.com/apollographql/apollo-client/pull/12920) [`e2fc385`](https://github.com/apollographql/apollo-client/commit/e2fc3850ddb2aa756fc44420390ae357daf31948) Thanks [@​phryneas](https://github.com/phryneas)! - Fix an invariance type error in the `MockedResponse` type.
### [`v4.0.4`](https://github.com/apollographql/apollo-client/blob/HEAD/CHANGELOG.md#404)
[Compare Source](https://github.com/apollographql/apollo-client/compare/@apollo/client@4.0.3...@apollo/client@4.0.4)
##### Patch Changes
- [#​12892](https://github.com/apollographql/apollo-client/pull/12892) [`db8a04b`](https://github.com/apollographql/apollo-client/commit/db8a04b193c157d57d6fe0f187b1892afdda1b7d) Thanks [@​jerelmiller](https://github.com/jerelmiller)! - Prevent unhandled rejections from the promise returned by calling the `mutate` function from the `useMutation` hook.
- [#​12899](https://github.com/apollographql/apollo-client/pull/12899) [`5352c12`](https://github.com/apollographql/apollo-client/commit/5352c1208e19c93678fef7860a1a87841653eb64) Thanks [@​phryneas](https://github.com/phryneas)! - Fix an issue when `invariant` is called by external libraries when no dev error message handler is loaded.
- [#​12895](https://github.com/apollographql/apollo-client/pull/12895) [`71f2517`](https://github.com/apollographql/apollo-client/commit/71f2517132a34563a14934f3971666b3691710f9) Thanks [@​jerelmiller](https://github.com/jerelmiller)! - Support `skipToken` with `useQuery` to provide a more type-safe way to skip query execution.
```ts
import { skipToken, useQuery } from "@apollo/client/react";
// Use `skipToken` in place of `skip: true` for better type safety
// for required variables
const { data } = useQuery(QUERY, id ? { variables: { id } } : skipToken);
```
Note: this change is provided as a patch within the 4.0 minor version because the changes to TypeScript validation with required variables in version 4.0 made using the `skip` option more difficult.
- [#​12900](https://github.com/apollographql/apollo-client/pull/12900) [`c0d5be7`](https://github.com/apollographql/apollo-client/commit/c0d5be7cbbb1b1f7771962eb2ae0e173de743265) Thanks [@​phryneas](https://github.com/phryneas)! - Use named export `equal` instead of default from `"@wry/equality"`
### [`v4.0.3`](https://github.com/apollographql/apollo-client/blob/HEAD/CHANGELOG.md#403)
[Compare Source](https://github.com/apollographql/apollo-client/compare/@apollo/client@4.0.2...@apollo/client@4.0.3)
##### Patch Changes
- [#​12887](https://github.com/apollographql/apollo-client/pull/12887) [`6f6ca47`](https://github.com/apollographql/apollo-client/commit/6f6ca47e9f5e80ee9c98fca2639b5cba6317fbbf) Thanks [@​phryneas](https://github.com/phryneas)! - Fix accidental deep re-export from `/react` out of `/react/internals`
- [#​12890](https://github.com/apollographql/apollo-client/pull/12890) [`019b422`](https://github.com/apollographql/apollo-client/commit/019b4224147a5a8709de54c4474e126619dd2469) Thanks [@​jerelmiller](https://github.com/jerelmiller)! - Ensure the `variables` option for `useMutation` provides proper IntelliSense suggestions.
### [`v4.0.2`](https://github.com/apollographql/apollo-client/blob/HEAD/CHANGELOG.md#402)
[Compare Source](https://github.com/apollographql/apollo-client/compare/@apollo/client@4.0.1...@apollo/client@4.0.2)
##### Patch Changes
- [#​12880](https://github.com/apollographql/apollo-client/pull/12880) [`56fac52`](https://github.com/apollographql/apollo-client/commit/56fac522549eaed5494097dc0098ea7a558382a0) Thanks [@​phryneas](https://github.com/phryneas)! - restore `getMemoryInternals` access in dev builds
### [`v4.0.1`](https://github.com/apollographql/apollo-client/blob/HEAD/CHANGELOG.md#4012-beta0)
[Compare Source](https://github.com/apollographql/apollo-client/compare/@apollo/client@4.0.0...@apollo/client@4.0.1)
##### Patch Changes
- [#​12884](https://github.com/apollographql/apollo-client/pull/12884) [`d329790`](https://github.com/apollographql/apollo-client/commit/d32979070381f1897c90fb276e25a0c8375cc29a) Thanks [@​phryneas](https://github.com/phryneas)! - Ensure that `PreloadedQueryRef` instances are unsubscribed when garbage collected
- [#​13069](https://github.com/apollographql/apollo-client/pull/13069) [`9cad04a`](https://github.com/apollographql/apollo-client/commit/9cad04a4228a5059ea330ac9d284407a363fc10d) Thanks [@​jerelmiller](https://github.com/jerelmiller)! - Truncate [@​stream](https://github.com/stream) arrays only on last chunk by default
### [`v4.0.0`](https://github.com/apollographql/apollo-client/blob/HEAD/CHANGELOG.md#400)
[Compare Source](https://github.com/apollographql/apollo-client/compare/v3.14.1...@apollo/client@4.0.0)
</details>
---
### Configuration
📅 **Schedule**: (UTC)
- Branch creation
- At any time (no schedule defined)
- Automerge
- At any time (no schedule defined)
🚦 **Automerge**: Disabled by config. Please merge this manually once you are satisfied.
♻ **Rebasing**: Whenever PR becomes conflicted, or you tick the rebase/retry checkbox.
🔕 **Ignore**: Close this PR and you won't be reminded about this update again.
---
- [ ] <!-- rebase-check -->If you want to rebase/retry this PR, check this box
---
This PR has been generated by [Mend Renovate CLI](https://github.com/renovatebot/renovate).
<!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiI0My4yMTIuNCIsInVwZGF0ZWRJblZlciI6IjQ0LjEwNC4yIiwidGFyZ2V0QnJhbmNoIjoibWFpbiIsImxhYmVscyI6W119-->
Renovate failed to update an artifact related to this branch. You probably do not want to merge this PR as-is.
♻ Renovate will retry this branch, including artifacts, only when one of the following happens:
any of the package files in this branch needs updating, or
the branch becomes conflicted, or
you click the rebase/retry checkbox if found above, or
you rename this PR's title to start with "rebase!" to trigger it manually
The artifact failure details are included below:
File name: package-lock.json
npm warn Unknown env config "store". This will error in a future major version of npm. See `npm help npmrc` for supported config options.
npm error code ERESOLVE
npm error ERESOLVE could not resolve
npm error
npm error While resolving: @vue/apollo-composable@4.2.2
npm error Found: @apollo/client@4.3.1
npm error node_modules/@apollo/client
npm error @apollo/client@"4.3.1" from the root project
npm error
npm error Could not resolve dependency:
npm error peer @apollo/client@"^3.4.13" from @vue/apollo-composable@4.2.2
npm error node_modules/@vue/apollo-composable
npm error @vue/apollo-composable@"4.2.2" from the root project
npm error
npm error Conflicting peer dependency: @apollo/client@3.14.1
npm error node_modules/@apollo/client
npm error peer @apollo/client@"^3.4.13" from @vue/apollo-composable@4.2.2
npm error node_modules/@vue/apollo-composable
npm error @vue/apollo-composable@"4.2.2" from the root project
npm error
npm error Fix the upstream dependency conflict, or retry this command with --force or --legacy-peer-deps to accept an incorrect (and potentially broken) dependency resolution.
npm error
npm error
npm error For a full report see:
npm error /tmp/renovate/cache/others/npm/_logs/2026-10-01T15_04_40_973Z-eresolve-report.txt
npm error A complete log of this run can be found in: /tmp/renovate/cache/others/npm/_logs/2026-10-01T15_04_40_973Z-debug-0.log
### ⚠️ Artifact update problem
Renovate failed to update an artifact related to this branch. You probably do not want to merge this PR as-is.
♻ Renovate will retry this branch, including artifacts, only when one of the following happens:
- any of the package files in this branch needs updating, or
- the branch becomes conflicted, or
- you click the rebase/retry checkbox if found above, or
- you rename this PR's title to start with "rebase!" to trigger it manually
The artifact failure details are included below:
##### File name: package-lock.json
```
npm warn Unknown env config "store". This will error in a future major version of npm. See `npm help npmrc` for supported config options.
npm error code ERESOLVE
npm error ERESOLVE could not resolve
npm error
npm error While resolving: @vue/apollo-composable@4.2.2
npm error Found: @apollo/client@4.3.1
npm error node_modules/@apollo/client
npm error @apollo/client@"4.3.1" from the root project
npm error
npm error Could not resolve dependency:
npm error peer @apollo/client@"^3.4.13" from @vue/apollo-composable@4.2.2
npm error node_modules/@vue/apollo-composable
npm error @vue/apollo-composable@"4.2.2" from the root project
npm error
npm error Conflicting peer dependency: @apollo/client@3.14.1
npm error node_modules/@apollo/client
npm error peer @apollo/client@"^3.4.13" from @vue/apollo-composable@4.2.2
npm error node_modules/@vue/apollo-composable
npm error @vue/apollo-composable@"4.2.2" from the root project
npm error
npm error Fix the upstream dependency conflict, or retry this command with --force or --legacy-peer-deps to accept an incorrect (and potentially broken) dependency resolution.
npm error
npm error
npm error For a full report see:
npm error /tmp/renovate/cache/others/npm/_logs/2026-10-01T15_04_40_973Z-eresolve-report.txt
npm error A complete log of this run can be found in: /tmp/renovate/cache/others/npm/_logs/2026-10-01T15_04_40_973Z-debug-0.log
```
renovate
changed title from fix(deps): update apollo graphql packages to v4 to fix(deps): update dependency @apollo/client to v42026-07-03 12:04:15 +00:00
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
This PR contains the following updates:
3.14.1→4.3.1Release Notes
apollographql/apollo-client (@apollo/client)
v4.3.1Compare Source
Patch Changes
37f700eThanks @jerelmiller! - Fix an issue whereuseLazyQuerydid not rerender with newvariablesuntil the network request had completed when callingexecutewith new variables while a request was already in-flight.v4.3.0Compare Source
Minor Changes
#13447
24133feThanks @jerelmiller! - Field policies andinputObjectscan now tell the cache whether a field is a list of scalars or a scalar whose value is an array. Previously all arrays were iterated and only the inner type was provided to the scalarparse/serializefunctions.This required some breaking changes from previous prerelease versions:
scalaroption andinputObjectstype string now use GraphQL list syntax to mark a field as a list of scalarscache.getScalarForFieldis nowcache.getScalarTypeForFieldand is expected to return the string representing the scalar type rather than theScalarinstanceNow it's possible to handle scalars that are represented by arrays:
#13324
0abd8deThanks @jerelmiller! - Fix the accuracy ofdataStatein complex incremental streaming scenarios, especially when combined withreturnPartialData: true.Prior to this change, all intermediate chunks used for both
@deferand@streamdirectives returned adataStateofstreaming, regardless of whether the actual data shape fit the definition of thestreamingdata state. Thestreamingdata state represents an incomplete incremental response where the only holes in the data occur at@deferboundaries.Let's use the following example of where the previous
dataStatefell down when combined withreturnPartialData.@deferboundary written to the cacheLet's say the cache contained the following partial data:
After the first chunk arrives from the server, the data looks like the following:
This data is not
completebecauserecipient.emailis missing. This data is also notstreamingbecause the data requirements in the@deferboundary are partially fulfilled due to the existence ofrecipient. This could lead to runtime crashes onrecipient.emailif you use the existence ofrecipientto detect whether data in the@deferboundary has streamed in or not. This change now accurately reports this aspartialto ensure the field is marked as a partial field inrecipient.@deferboundaryLet's say the cache contained the following partial data:
After the first chunk arrives from the server, the data looks like the following:
In this case, the combination of the first chunk and the partial data in the cache now fulfills the data requirements of the query. Even though the server is still streaming data (
NetworkStatus.streaming), we can report this asdataState: "complete"since it is safe to access data on all fields.This change also means
@streamqueries by definition fulfill the data requirements of the query after the first chunk arrives since@streamoperates on lists and contains no data holes.@streamqueries now accurately reportdataStateascompleteorpartial, depending on whether the list mixes partial data with streamed list items.As a result of this change, some cases where you'd previously see
dataStatereported as"streaming"are now reported aspartialorcomplete.If you use
dataStateto determine whether an incremental request is still in-flight, please usenetworkStatusinstead to check forNetworkStatus.streaming.dataStateis type narrowing feature and not intended to report the network status.#13274
7b10078Thanks @jerelmiller! - AddsScalar.fromGraphQLScalarTypehelper to create aScalarinstance from an existing graphql.jsGraphQLScalarType.#13421
d6197a4Thanks @jerelmiller! - The minimum supported TypeScript version is now 5.9.x.#13270
d080f11Thanks @jerelmiller! - Adds the plumbing and types implementation for declaring custom scalars and configuring custom scalars inInMemoryCache.You can declare custom scalar types with declaration merging on the
ApolloCache.Scalarsinterface:This enables the
scalarsoption inInMemoryCache:#13250
bad7035Thanks @jerelmiller! - Add the ability to define the cache type for the client.client.cachecurrently returnsApolloCacheas the cache type regardless of what cache you've provided toApolloClient.Declare the cache type using the
cacheproperty in theTypeOverridesinterface to set the cache implementation used for the client.Now anywhere
cacheis accessible, the type is the declared cache type:#13406
bd74ccbThanks @jerelmiller! - Emit a development-only warning when a feud is detected between queries that overwrite each other's data. This should make it easier to detect when you need to select a key field or add amergefunction to a field policy.#13390
90e338cThanks @jerelmiller! - Fix issue where sibling@deferfragments were pruned incorrectly when at least one of the@deferfragments wasn't delivered.As a result of this change, a
labelargument is now added to all outgoing@deferdirectives when using theGraphQL17Alpha9Handlerin order to disambiguate the@deferfragments from each other.#13426
a9beaffThanks @jerelmiller! - Version bump only torc.#13416
f2d5d5aThanks @jerelmiller! - AddGraphQLCodegenIncrementaltype overrides that assemble GraphQL Codegen@deferoperation types whendataStateis"complete".#13372
e4cde69Thanks @jerelmiller! - Parse scalar fields forno-cachequeries.#13386
0be8fd8Thanks @atharv-sys32! - SupportskipTokenwithuseSubscriptionto provide a more type-safe way to skip subscription execution with required variables.#13337
2df711fThanks @jcostello-atlassian! - Allow overriding thefrominput ofuseFragment,useSuspenseFragment,readFragment,writeFragmentand related fragment APIs via a newFromOptionValuekey on theTypeOverridesinterface.By default,
fromcontinues to acceptStoreObject | Reference | FragmentType<TData> | string. Apps can now supply a stricter policy (for example, requiring__typenameand disallowing nullish identifier values) without affectingStoreObject,cache.identify,cache.modifyor optimistic writes.#13405
f923ab4Thanks @jerelmiller! - Field policyreadandmergefunctions are now ignored when the field policy configures thescalaroption. If areadormergefunction is provided alongsidescalar, a development-only warning is emitted.#13393
434d25fThanks @jerelmiller! - Change when@deferfragments and@streamfields are pruned forcache-firstandcache-and-networkfetch policies to better match the network when the initial value contained a partial result:cache-first: prune undelivered@deferfragments or@streamitems when the result is fetched from the network due to a partial resultcache-and-network: prune undelivered@deferfragments or@streamitems if the initial cache value was partial. If the first value emitted from the cache is complete, the results will not be pruned.This makes the emitted results more predictable by following what the network has delivered and avoids some ambiguity in other edge cases.
For example, with a
cache-firstfetch policy where all@deferfields are written to the cache, but a non-deferred field is partial, the values emitted from the client previously looked like the following:Here the result is confusing because the initial value returned from the query was
undefined, yet a complete result was returned after the initial chunk from the network returned (which did not containemail).The cache values are now pruned if the network hasn't delivered them yet:
This is especially helpful in situations where
@deferboundaries that are never delivered due to errors prevent an awkward situation where the client would otherwise have to choose whether to serve the stale cache result from the cache, or prune the undelivered fragment on the final chunk.#13270
6031987Thanks @jerelmiller! - Adds ascalaroption toInMemoryCachefield policies that tells the cache which scalar to use when parsing or serializing the field value.This scalar definition is now used to properly parse or serialize the field value for cache reads and writes as well as
cache.extract()andcache.restore().#13273
0886de1Thanks @jerelmiller! - Automatically serialize variables that include custom scalar values. This includes cache reads and writes as well as requests to the network.For more complex input objects, a new
inputObjectsoption is available toInMemoryCachethat specifies where nested scalar fields are found.#13424
d2bca2eThanks @jerelmiller! - Remove the customNoInfertype utility in favor of the nativeNoInferintroduced in TypeScript 5.4.#13270
d080f11Thanks @jerelmiller! - Adds thegetScalarabstract method toApolloCachethat cache subclasses override to provide scalar behavior to Apollo Client. Defaults to unconditionally returnundefinedif not specified.#13406
bd74ccbThanks @jerelmiller! - Fixes an issue where cache feuds between queries selecting incompatible non-normalized data could return untransformed network values.Apollo Client now always writes network results to the cache before delivering them, ensuring custom scalars and field
readfunctions are applied. To prevent repeated refetches when competing queries repeatedly make each other's cache results incomplete, Apollo Client stops automatically refetching a query after it sees the same incomplete result again.This may add one network request in these cache-feud scenarios.
Patch Changes
#13408
7a5164dThanks @jerelmiller! - FixdataStateto report"streaming"instead of"partial"whenreturnPartialDataistrueand the cache result is missing only@deferfields.#13381
9c73762Thanks @jerelmiller! - Fix an issue where anetwork-onlyquery leaked partial cache data for@deferfragments that were not delivered by the network due to an error that bubbled to the@deferfragment boundary.#13390
90e338cThanks @jerelmiller! - Fix an issue where a sibling non-deferred fragment might be accidentally pruned when the@deferfragment hadn't been delivered.#13442
ed033d4Thanks @jerelmiller! - Remove the optional modifier from thevariablesproperty provided to theupdatefunction inclient.mutateanduseMutation.variablesis always a defined object, even when variables are not provided to the mutation.#13324
0abd8deThanks @jerelmiller! - Fix an issue where fieldreadfunctions were not applied to intermediate results while streaming@deferresponses.cache.diffran thereadfunctions, but the transformed values were only applied to the emitted result when the updated cache result was considered complete. Intermediate chunks whose only holes were at@deferboundaries now correctly return the result of fieldreadfunctions.#13403
aaff7a8Thanks @jerelmiller! - Fix issue where the wrongdataStatewas returned when there was nothing written to the cache and a@deferfragment was marked pending.#13347
7d543d6Thanks @jerelmiller! - Fix an issue wherenetwork-onlyincremental queries could cause cache data to leak into the emitted result when a@deferor@streamboundary already had complete data in the cache. Cache data inside pending@deferobjects and@streamarrays are now pruned so that only completed@deferor@streamboundaries are returned.NOTE: This change only applies to
InMemoryCachewhen usingGraphQL17Alpha9Handler.#13329
1d581d2Thanks @AmariahAK! - Cache diffs for incomplete queries no longer pay the cost of building a fullMissingFieldErrorwhen themissingproperty is not accessed. The error object is now only constructed when themissingproperty is accessed the first time. This improves performance by avoiding a V8 stack capture whenmissingis ignored entirely.As an additional small performance improvement,
JSON.stringifyis no longer used in the error message on objects whose cache ID is known.JSON.stringifyis only used for non-normalized objects.#13381
9c73762Thanks @jerelmiller! - Fix an issue where a@deferquery reported thedataStateascompleteinstead ofstreamingwhen an error occurs on a deferred field that bubbled to the defer boundary.#13324
0abd8deThanks @jerelmiller! - Fix an issue with@streamqueries when usingreturnPartialData: truewhere the streamed list was truncated after the first incremental chunk when the list contained partial cache data. The list is no longer truncated and partial list items are now retained as incremental chunks arrive. ThedataStateis now reported aspartialuntil the server has streamed enough of the list so that each list item fully satisfies the query.This change also updates
@streamqueries so that they reported withdataState: "completeinstead of"streaming"since it is safe to access all fields in the response.#13373
2551937Thanks @jerelmiller! - Fix an issue where a cache write in the middle of polling would remain as the query value if future poll requests returned deep equal results to previous polling results.#13448
77e1e35Thanks @jerelmiller! - Markskipas deprecated inuseQueryanduseSubscriptionnow that both of these hooks supportskipToken.#13403
aaff7a8Thanks @jerelmiller! - Fix issue where settingreturnPartialData: truemight report the wrongdataStatewhen partial data was written to the cache and@deferfragments were pending.#13347
7d543d6Thanks @jerelmiller! - Fix an issue where partial cache data could leak into intermediate incremental results. This could cause runtime crashes if you relied on the presence of values to determine whether the@deferdata had streamed in or not.#13381
9c73762Thanks @jerelmiller! - Fix an invariant error thrown when a@deferboundary received a payload after it had already been marked complete.#13268
419e2b5Thanks @DaleSeo! - Align the remaining cache generic constraints withCache.Implementation. The deprecated React mutation types (MutationHookOptions,MutationFunctionOptions,MutationTuple) and the internalInternalRefetchQueriesOptionsandQueryInfotypes still constrained their cache type parameter toApolloCache, so they now match the rest of the overridable cache API.v4.2.12Compare Source
Patch Changes
56ca81bThanks @QiRaining! - Preserve multi-byte UTF-8 characters split across multipart response chunks.v4.2.11Compare Source
Patch Changes
#13398
3dd3e9aThanks @phryneas! - Fix type signature of someDocumentationTypesto fix their display in our documentation.#13392
d4f0771Thanks @jerelmiller! - Add a development-only warning when a network result is written to the cache but reading the query back from the cache returns a partial result. This usually points at amergeorreadfunction that did not repair missing fields in the cache, which prevents Apollo Client from applying the cache result to the data received by the network.v4.2.10Compare Source
Patch Changes
#13385
bfb674eThanks @jerelmiller! - Fix accidental widening of theclient.mutatereturn type whenoptimisticResponsewas present.#13382
365373eThanks @jerelmiller! - Fix result types widened when a query's variables had constant types (e.g.TypedDocumentNode<Data, { type: "main" }>). This caused options such asreturnPartialDataorerrorPolicyto be reported as their widened types (e.g.boolean,ErrorPolicy) instead of the value that was passed which returned the wrongdataanddataStatetypes.#13382
365373eThanks @jerelmiller! - Fix issue where unknown options were permitted by TypeScript when passed alongside a valid option to APIs with modern signatures.#13383
5840f50Thanks @jerelmiller! - Update the return type ofrefetch,fetchMoreanduseLazyQuery'sexecutefunction on the providederrorPolicy. Previously these APIs all used the default type which typeddataasTData | undefinedanderrorasErrorLike | undefined.v4.2.9Compare Source
Patch Changes
#13364
2f383e7Thanks @atharv-sys32! - Fix a bug where GraphQL variable default values were not applied during cache reads when variables with defaults were explicitly set toundefined. This caused@include/@skipdirectives to throw "Invalid variable referenced" errors when the variable was passed asundefinedinstead of being omitted entirely.#13367
2b39cc8Thanks @jerelmiller! - Fix an issue where some@exportqueries would not react to cache updates when the fields keyed by exported variables were updated.v4.2.8Compare Source
Patch Changes
501a33bThanks @jerelmiller! - Prevent thesetTimeoutinconnectToDevtoolsthat shows the devtools suggestion from firing when the user agent does not match Chrome or Firefox. This check was previously done inside thesetTimeoutwhich meant the timer was scheduled for environments where we'd never show the message anyways. For test environments, this could cause flaky tests when thatsetTimeoutoutlived the tests and ran after any virtual DOM was torn down and removed.v4.2.7Compare Source
Patch Changes
538c906Thanks @jerelmiller! - Cleanup some unused internals. Please file an issue if you notice anything change.v4.2.6Compare Source
Patch Changes
#13315
a406cc9Thanks @fallintoplace! - Prevent relay multipart subscriptions from issuing a fetch request after serializing the request body fails.#13307
abd0781Thanks @wolfie! - Speed up cache writes by avoiding a full ASTvisitof every written field to detect@stream. The check now runs only when the result carries stream info, and only inspects the field node's own directives. As a result, fields that merely contain@streamon a nested field are no longer treated as streamed themselves and now overwrite existing lists like regular fields instead of merging chunk-wise.v4.2.5Compare Source
Patch Changes
bb75dd3Thanks @tpict! - ExportKeyArgsFunctionandRelayFieldPolicytypes from public entrypoints.v4.2.4Compare Source
Patch Changes
e4df809Thanks @jerelmiller! - Fixes an issue whereclient.readFragmentandclient.readQueryignored theoptimisticoption when passed in the options object.v4.2.3Compare Source
Patch Changes
66e9dfcThanks @jerelmiller! - Add support forgraphqlv17 as a valid peer dependency.v4.2.2Compare Source
Patch Changes
c207b88Thanks @audrius-savickas! - Preserve referential equality of masked data on refetch when the result is deeply equal to the previous result.v4.2.1Compare Source
Patch Changes
56ca81bThanks @QiRaining! - Preserve multi-byte UTF-8 characters split across multipart response chunks.v4.2.0Compare Source
Minor Changes
#13132
f3ce805Thanks @phryneas! - Introduce "classic" and "modern" method and hook signatures.Apollo Client 4.2 introduces two signature styles for methods and hooks. All signatures previously present are now "classic" signatures, and a new set of "modern" signatures are added alongside them.
Classic signatures are the default and are identical to the signatures before Apollo Client 4.2, preserving backward compatibility. Classic signatures still work with manually specified TypeScript generics (e.g.,
useSuspenseQuery<MyData>(...)). However, manually specifying generics has been discouraged for a long time—instead, we recommend usingTypedDocumentNodeto automatically infer types, which provides more accurate results without any manual annotations.Modern signatures automatically incorporate your declared
defaultOptionsinto return types, providing more accurate types. Modern signatures infer types from the document node and do not support manually passing generic type arguments; TypeScript will produce a type error if you attempt to do so.Methods and hooks automatically switch to modern signatures the moment any non-optional property is declared in
DeclareDefaultOptions. The switch happens across all methods and hooks globally:Users can also manually switch to modern signatures without declaring any
defaultOptions, for example when wanting accurate type inference without relying on globaldefaultOptions:Users can do a global
DeclareDefaultOptionstype augmentation and then manually switch back to "classic" for migration purposes:Note that this is not recommended for long-term use. When combined with
DeclareDefaultOptions, switching back to classic results in the same incorrect types as before Apollo Client 4.2—methods and hooks will not reflect thedefaultOptionsyou've declared.#13130
dd12231Thanks @jerelmiller! - Improve the accuracy ofclient.queryreturn type to better detect the currenterrorPolicy. Thedataproperty is no longer nullable when theerrorPolicyisnone. This makes it possible to remove theundefinedchecks or optional chaining in most cases.#13210
1f9a428Thanks @jerelmiller! - Add support for automatic event-based refetching, such as window focus.The
RefetchEventManagerclass handles automatic refetches in response to events. Apollo Client provides built-in sources for window focus and network reconnect aswindowFocusSourceandonlineSource.Event refetching is fully opt-in. Create and pass a
RefetchEventManagerinstance to theApolloClientconstructor to activate the event listeners.By default, all active queries refetch when the events fire. Queries can opt out per-event or disable all event refetches:
To enable per-query opt-in rather than opt-out, set
defaultOptions.watchQuery.refetchOntofalseand enable it per-query instead.When
defaultOptions.watchQuery.refetchOnand per-queryrefetchOnoptions are provided, the objects are merged together.Custom events
You can also add your own custom events that trigger refetches. Register your event name and payload type using TypeScript module augmentation, then provide a source function that returns an Observable. The source's emitted value becomes the event's
payload.Manually trigger an event refetch
Refetches can be triggered imperatively by calling
emitwith the event name and its payload (if any).Sourceless events
A source that has no automatic detection logic but still wants imperative
emitsupport can be declared astrue. Type the event asvoidto omit the payload argument.Note: Calling
emiton an event without a registered source will log a warning and result in a no-op.Custom handlers
When an event fires, the default handler calls
client.refetchQueries({ include: "active" })filtered by each query'srefetchOnsetting. You can override the handler for an event to add your own custom filtering. For example, to refetch all queries, includingstandbyqueries, define a handler for the event:Handlers must return either a
RefetchQueriesResultorvoid. Returningvoidskips refetching for the event.#13232
f1b541fThanks @jerelmiller! - Version bump torc.#13206
08fccabThanks @jerelmiller! - Extend thedefaultOptionstype-safety work toclient.mutateanduseMutation.The
errorPolicyoption now flows through to the result types for mutations in the same way it already does for queries:ApolloClient.MutateResult<TData, TErrorPolicy>mapserrorPolicyto the concrete shape ofdataanderror:"none"→{ data: TData; error?: never }"all"→{ data: TData | undefined; error?: ErrorLike }"ignore"→{ data: TData | undefined; error?: never }client.mutateanduseMutationpick up the declareddefaultOptions.mutate.errorPolicyand the expliciterrorPolicyon each call to narrow return types accordingly.useMutation.Result.erroris narrowed toundefinedwhenerrorPolicyis"ignore", sinceclient.mutatenever resolves with an error in that case.DeclareDefaultOptions.Mutatealready acceptederrorPolicy; the new behavior is that once you declare it, hook and method return types reflect it:Setting
errorPolicyon an individual call overrides the default for that call's return type.#13222
b93c172Thanks @jerelmiller! - Extend thedefaultOptionstype-safety work topreloadQuery(returned fromcreateQueryPreloader). Defaults declared inDeclareDefaultOptions.WatchQuerynow work withpreloadQueryto ensure thePreloadedQueryRef's data states are correctly set.#13132
f3ce805Thanks @phryneas! - Synchronize method and hook return types withdefaultOptions.Prior to this change, the following code snippet would always apply:
While these types are generally correct, if you were to set
errorPolicy: 'all'as a default option, the type ofresult.datafor the first query would remainTDatainstead of changing toTData | undefinedto match the runtime behavior.We are now enforcing that certain
defaultOptionstypes need to be registered globally. This means that if you want to useerrorPolicy: 'all'as a default option for a query, you will need to register its type like this:Once this type declaration is in place, the type of
result.datain the above example will correctly be changed toTData | undefined, reflecting the possibility that if an error occurs,datamight beundefined. Manually specifyinguseSuspenseQuery(MY_QUERY, { errorPolicy: "none" });changesresult.datatoTDatato reflect the local override.This change means that you will need to declare your default options types in order to use
defaultOptionswithApolloClient, otherwise you will see a TypeScript error.Without the type declaration, the following (previously valid) code will now error:
If you are creating multiple instances of Apollo Client with conflicting default options and you cannot register a single
defaultOptionsvalue as a result, you can relax the constraints by declaring those options as union types covering all values used by all clients. The properties can be required (to enforce them indefaultOptions) or optional (if some constructor calls won't pass a value):With this declaration, the
ApolloClientconstructor accepts any of those values indefaultOptions. The tradeoff is that hook and method return types become more generic. For example, callinguseSuspenseQuerywithout an expliciterrorPolicywill return a result typed as if all error policies are possible, since TypeScript can't know which specific value your instance uses at runtime.Note that making a property optional (
errorPolicy?:) is equivalent to adding the TypeScript default value ("none") to the union. SoerrorPolicy?: "all" | "ignore"has the same effect on return types aserrorPolicy: "none" | "all" | "ignore", because TypeScript assumes the option could also be absent (i.e.,"none").You can also use a partial union that only lists the values you actually use. For example, if you only ever use
"all"or"ignore", declareerrorPolicy: "all" | "ignore"(required) to keep the union narrow and avoid unused values broadening your signatures unnecessarily.Patch Changes
#13217
790f987Thanks @jerelmiller! - Fix the deprecation for the classic signatures for function overloads that rely on type inference from aTypedDocumentNode. The deprecation now only applies to classic signatures that provide explicit type arguments to encourage the use ofTypedDocumentNode.#13166
0537d97Thanks @jerelmiller! - Release changes in 4.1.5 and 4.1.6.#13215
54c9eb7Thanks @jerelmiller! - Ensure the options object for theuseQuery,useSuspenseQuery, anduseBackgroundQueryhooks provide proper IntelliSense suggestions.#13229
9a7f65aThanks @jerelmiller! - FixrefetchOnmerging whendefaultOptions.watchQuery.refetchOnis set to a non-object value (false,true, or a function) and the per-queryrefetchOnis an object. Previously the per-query object completely replaced the default so unspecified events fell back to "enabled" regardless of the default.The
defaultOptionsvalue now applies to any event the per-query object does not explicitly configure:false- unspecified events stay disabledtrue- unspecified events refetch#13230
b25b659Thanks @jerelmiller! - Add the ability to override the default event handler onRefetchEventManager. The default handler runs when no per-source handler is configured for an event. Provide a custom handler via thedefaultHandlerconstructor option or thesetDefaultEventHandlerinstance method.v4.1.9Compare Source
Patch Changes
099954bThanks @copilot-swe-agent! - Remove theworkspacesfield from the publishedpackage.jsonindistto avoid Yarn v1 warnings about workspaces requiring private packages.v4.1.8Compare Source
Patch Changes
8a51ea6Thanks @phryneas! - Ship agent skill for usage with @tanstack/intent — the skill is now bundled in the npm package underskills/apollo-client/and discoverable byintent list.For more context, see the TanStack Intent QuickStart.
v4.1.7Compare Source
Patch Changes
bb3fd9bThanks @jerelmiller! - Fix RxJS interop issue with the observable returned byWebSocketLink.v4.1.6Compare Source
Patch Changes
#13128
6c0b8e4Thanks @pavelivanov! - FixuseQueryhydration mismatch whenssr: falseandskip: trueare used togetherWhen both options were combined, the server would return
loading: false(becauseuseSSRQuerychecksskipfirst), but the client'sgetServerSnapshotwas returningssrDisabledResultwithloading: true, causing a hydration mismatch.v4.1.5Compare Source
Patch Changes
#13155
3ba1583Thanks @jerelmiller! - Fix an issue whereuseQuerywould poll withpollIntervalwhenskipwas initialized totrue.#13135
fd42142Thanks @jerelmiller! - Fix issue whereclient.querywould apply options fromdefaultOptions.watchQuery.v4.1.4Compare Source
Patch Changes
578081fThanks @Re-cool! - EnsurePersistedQueryLinkmergeshttpandfetchOptionscontext values instead of overwriting them.v4.1.3Compare Source
Patch Changes
#13111
bf46fe0Thanks @RogerHYang! - FixcreateFetchMultipartSubscriptionto support cancellation viaAbortControllerPreviously, calling
dispose()orunsubscribe()on a subscription created bycreateFetchMultipartSubscriptionhad no effect - the underlying fetch request would continue running until completion. This was because noAbortControllerwas created or passed tofetch(), and no cleanup function was returned from the Observable.v4.1.2Compare Source
Patch Changes
#13105
8b62263Thanks @phryneas! -ssrMode,ssrForceFetchDelayorprioritizeCacheValuesshould not overridefetchPolicy: 'cache-only',fetchPolicy: 'no-cache',fetchPolicy: 'standby',skip: true, orskipTokenwhen reading the initial value of anObservableQuery.#13105
8b62263Thanks @phryneas! - FixskipTokeninuseQuerywithprerenderStaticand related SSR functions.#13105
8b62263Thanks @phryneas! - Avoid fetches withfetchPolicy: no-cacheinuseQuerywithprerenderStaticand related SSR functions.v4.1.1Compare Source
Patch Changes
dee7dcfThanks @jerelmiller! - Ensure@clientfields that are children of aliased server fields are resolved correctly.v4.1.0Compare Source
Minor Changes
#13043
65e66caThanks @jerelmiller! - Supportheaderstransport for enhanced client awareness.#12927
785e223Thanks @jerelmiller! - You can now provide a callback function as thecontextoption on themutatefunction returned byuseMutation. The callback function is called with the value of thecontextoption provided to theuseMutationhook. This is useful if you'd like to merge the context object provided to theuseMutationhook with a value provided to themutatefunction.#12923
94ea3e3Thanks @jerelmiller! - Fix an issue where deferred payloads that returned arrays with fewer items than the original cached array would retain items from the cached array. This change includes@streamarrays where stream arrays replace the cached arrays.#12927
96b531fThanks @jerelmiller! - Don't set the fallback value of a@clientfield tonullwhen areadfunction is defined. Instead thereadfunction will be called with anexistingvalue ofundefinedto allow default arguments to be used to set the returned value.When a
readfunction is not defined nor is there a defined resolver for the field, warn and set the value tonullonly in that instance.#12927
45ebb52Thanks @jerelmiller! - Add support forfrom: nullinclient.watchFragmentandcache.watchFragment. Whenfromisnull, the emitted result is:#12926
2b7f2c1Thanks @jerelmiller! - Support the newer incremental delivery format for the@deferdirective implemented ingraphql@17.0.0-alpha.9. Import theGraphQL17Alpha9Handlerto use the newer incremental delivery format with@defer.#12927
45ebb52Thanks @jerelmiller! - Add support for arrays withuseFragment,useSuspenseFragment, andclient.watchFragment. This allows the ability to use a fragment to watch multiple entities in the cache. Passing an array tofromwill returndataas an array where each array index corresponds to the index in thefromarray.#12927
45ebb52Thanks @jerelmiller! - Add agetCurrentResultfunction to the observable returned byclient.watchFragmentandcache.watchFragmentthat returns the current value for the watched fragment.#13038
109efe7Thanks @jerelmiller! - Add thefromoption toreadFragment,watchFragment, andupdateFragment.#12918
2e224b9Thanks @jerelmiller! - Add support for the@streamdirective on both theDefer20220824Handlerand theGraphQL17Alpha2Handler.#13056
b224efcThanks @jerelmiller! -InMemoryCacheno longer filters out explicitly returnedundefineditems fromreadfunctions for array fields. This now makes it possible to createreadfunctions on array fields that return partial data and trigger a fetch for the full list.#13058
121a2cbThanks @jerelmiller! - Add anextensionsoption tocache.write,cache.writeQuery, andclient.writeQuery. This makesextensionsavailable in cachemergefunctions which can be accessed with the other merge function options.As a result of this change, any
extensionsreturned in GraphQL operations are now available inmergein the cache writes for these operations.#12927
96b531fThanks @jerelmiller! - Add an abstractresolvesClientFieldfunction toApolloCachethat can be used by caches to tellLocalStateif it can resolve a@clientfield when a local resolver is not defined.LocalStatewill emit a warning and set a fallback value ofnullwhen no local resolver is defined andresolvesClientFieldreturnsfalse, or isn't defined. ReturningtruefromresolvesClientFieldsignals that a mechanism in the cache will set the field value. In this case,LocalStatewon't set the field value.#13078
bf1e0dcThanks @phryneas! - Use the default stream merge function for@streamfields only if stream info is present. This change means that using the olderDefer20220824Handlerwill not use the default stream merge function and will instead truncate the streamed array on the first chunk.Patch Changes
#12884
d329790Thanks @phryneas! - Ensure thatPreloadedQueryRefinstances are unsubscribed when garbage collected#13086
1a1d408Thanks @phryneas! - Change the returned value fromnullto{}when all fields in a query were skipped.This also fixes a bug where
useSuspenseQuerywould suspend indefinitely when all fields were skipped.#13010
7627000Thanks @jerelmiller! - Fix an issue where errors parsed from incremental chunks inErrorLinkmight throw when using theGraphQL17Alpha9Handler.#12927
45ebb52Thanks @jerelmiller! - Deduplicate watches created byuseFragment,client.watchFragment, andcache.watchFragmentthat contain the same fragment, variables, and identifier. This should improve performance in situations where auseFragmentor aclient.watchFragmentis used to watch the same object in multiple places of an application.#12927
259ae9bThanks @jerelmiller! - AllowFragmentTypenot only to be called asFragmentType<TData>, but also asFragmentType<TypedDocumentNode>.#12925
5851800Thanks @jerelmiller! - Fix an issue where callingfetchMorewith@deferor@streamwould not rerender incremental results as they were streamed.#12927
9e55188Thanks @jerelmiller! - Truncate@streamarrays only on last chunk by default.#13083
f3c2be1Thanks @phryneas! - Expose theExtensionsWithStreamInfotype forextensionsinCache.writeQuery,Cache.writeandCache.updateso other cache implementations also can correctly access them.#12923
94ea3e3Thanks @jerelmiller! - Improve the cache data loss warning message whenexistingorincomingis an array.#12927
4631175Thanks @jerelmiller! - Ignore top-leveldatavalues on subsequent chunks in incremental responses.#12927
2be8de2Thanks @jerelmiller! - Create mechanism to add experimental features to Apollo Client#12927
96b531fThanks @jerelmiller! - EnsureLocalStatedoesn't try to read from the cache when using ano-cachefetch policy.#12927
bb8ed7bThanks @jerelmiller! - Ensure an error is thrown when@streamis detected and anincrementalDeliveryhandler is not configured.#13053
23ca0baThanks @phryneas! - Use memoized observable mapping when usingwatchFragment,useFragmentoruseSuspenseFragment.#12927
44706a2Thanks @jerelmiller! - Add helper typeQueryRef.ForQuery<TypedDocumentNode>#13082
c257418Thanks @phryneas! - PassstreamInfothrough result extensions as aWeakRef.#12927
4631175Thanks @jerelmiller! - Fix theDefer20220824Handler.SubsequentResulttype to match theFormattedSubsequentIncrementalExecutionResulttype ingraphql@17.0.0-alpha.2.#12927
96b531fThanks @jerelmiller! - Warn when using ano-cachefetch policy without a local resolver defined.no-cachequeries do not read or write to the cache which meantno-cachequeries are silently incomplete when the@clientfield value was handled by a cachereadfunction.#12927
5776ea0Thanks @jerelmiller! - Update theacceptheader used with theGraphQL17Alpha9Handlertomultipart/mixed;incrementalSpec=v0.2to ensure the newest incremental delivery format is requested.#12927
45ebb52Thanks @jerelmiller! -DeepPartial<Array<TData>>now returnsArray<DeepPartial<TData>>instead ofArray<DeepPartial<TData | undefined>>.#13071
99ffe9aThanks @phryneas! -prerenderStatic: Expose return value ofrenderFunctionto userland, fixabortedproperty.This enables usage of
resumeAndPrerenderwith React 19.2.#13026
05eee67Thanks @jerelmiller! - Reduce the number of observables created bywatchFragmentby reusing existing observables as much as possible. This should improve performance when watching the same item in the cache multiple times after a cache update occurs.#13010
7627000Thanks @jerelmiller! - Handle@streampayloads that send multiple items in the same chunk when using theDefer20220824Handler.#13010
7627000Thanks @jerelmiller! - Handle an edge case with theDefer20220824Handlerwhere an error for a@streamitem that bubbles to the@streamboundary (such as an item returningnullfor a non-null array item) would write items from future chunks to the wrong array index. In these cases, the@streamfield is no longer processed and future updates to the field are ignored. This prevents runtime errors that TypeScript would otherwise not be able to catch.#13081
1e06ad7Thanks @jerelmiller! - Avoid callingmergefunctions more than once for the same incremental chunk.v4.0.13Compare Source
Patch Changes
#13094
9cbe2c2Thanks @phryneas! - Ensure thatcompactandmergeOptionspreserve symbol keys.This fixes an issue where the change introduced in 4.0.11 via #13049 would not
be applied if
defaultOptionsforwatchQuerywere declared.Please note that
compactandmergeOptionsare considered internal utilitiesand they might have similar behavior changes in future releases.
Do not use them in your application code - a change like this is not considered
breaking and will not be announced as such.
v4.0.12Compare Source
Patch Changes
#12884
d329790Thanks @phryneas! - Ensure thatPreloadedQueryRefinstances are unsubscribed when garbage collected#13069
9cad04aThanks @jerelmiller! - Truncate @stream arrays only on last chunk by defaultv4.0.11Compare Source
Patch Changes
#13050
8020829Thanks @phryneas! - Replace usage offindLastwith more backwards-compatible methods.#13049
05638deThanks @phryneas! - Fixes an issue where queries starting withskipTokenor lazy queries fromuseLazyQuerywere included inclient.refetchQueries()before they had been executed for the first time. While generally queries with astandbyfetchPolicyshould be included in refetch, these queries never hadvariablespassed in, so they should be excluded until they have run once and received their actual variables.These queries are now properly excluded from refetch operations until after their initial execution.
This change adds a new hidden option to
client.watchQuery,[variablesUnknownSymbol], which may be settruefor queries starting with afetchPolicyofstandby. It will only be applied when creating theObservableQueryinstance and cannot be changed later. This flag indicates that the query's variables are not yet known, and thus it should be excluded from refetch operations until they are.This option is not meant for everyday use and is intended for framework integrations only.
v4.0.10Compare Source
Patch Changes
af4acdcThanks @phryneas! - Fix memory leak #13036v4.0.9Compare Source
Patch Changes
8f3bc9bThanks @jerelmiller! - Fix an issue where switching from options withvariablestoskipTokenwithuseSuspenseQueryanduseBackgroundQuerywould create a newObservableQuery. This could cause unintended refetches wherevariableswere absent in the request when the query was referenced withrefetchQueries.v4.0.8Compare Source
Patch Changes
f6d0efaThanks @CarsonF! - Fix cache.modify() mapping readonly arrays to singular referencev4.0.7Compare Source
Patch Changes
5b4f36aThanks @jerelmiller! - Don't sendoperationTypein the payload sent byGraphQLWsLink.v4.0.6Compare Source
Patch Changes
3b0d89bThanks @phryneas! - Fix a problem withfetchMorewhere the loading state wouldn't reset if the result wouldn't result in a data update.v4.0.5Compare Source
Patch Changes
e2fc385Thanks @phryneas! - Fix an invariance type error in theMockedResponsetype.v4.0.4Compare Source
Patch Changes
#12892
db8a04bThanks @jerelmiller! - Prevent unhandled rejections from the promise returned by calling themutatefunction from theuseMutationhook.#12899
5352c12Thanks @phryneas! - Fix an issue wheninvariantis called by external libraries when no dev error message handler is loaded.#12895
71f2517Thanks @jerelmiller! - SupportskipTokenwithuseQueryto provide a more type-safe way to skip query execution.Note: this change is provided as a patch within the 4.0 minor version because the changes to TypeScript validation with required variables in version 4.0 made using the
skipoption more difficult.#12900
c0d5be7Thanks @phryneas! - Use named exportequalinstead of default from"@wry/equality"v4.0.3Compare Source
Patch Changes
#12887
6f6ca47Thanks @phryneas! - Fix accidental deep re-export from/reactout of/react/internals#12890
019b422Thanks @jerelmiller! - Ensure thevariablesoption foruseMutationprovides proper IntelliSense suggestions.v4.0.2Compare Source
Patch Changes
56fac52Thanks @phryneas! - restoregetMemoryInternalsaccess in dev buildsv4.0.1Compare Source
Patch Changes
#12884
d329790Thanks @phryneas! - Ensure thatPreloadedQueryRefinstances are unsubscribed when garbage collected#13069
9cad04aThanks @jerelmiller! - Truncate @stream arrays only on last chunk by defaultv4.0.0Compare Source
Configuration
📅 Schedule: (UTC)
🚦 Automerge: Disabled by config. Please merge this manually once you are satisfied.
♻ Rebasing: Whenever PR becomes conflicted, or you tick the rebase/retry checkbox.
🔕 Ignore: Close this PR and you won't be reminded about this update again.
This PR has been generated by Mend Renovate CLI.
⚠️ Artifact update problem
Renovate failed to update an artifact related to this branch. You probably do not want to merge this PR as-is.
♻ Renovate will retry this branch, including artifacts, only when one of the following happens:
The artifact failure details are included below:
File name: package-lock.json
4425164628tof8455dde0cfix(deps): update apollo graphql packages to v4to fix(deps): update dependency @apollo/client to v4f8455dde0cto64548093506454809350to13b80651f413b80651f4to17c93475f717c93475f7to37fb6f31fd37fb6f31fdto8ce87063b08ce87063b0toab7f6b070dab7f6b070dtoe9d208489ae9d208489ato8bcbbca3578bcbbca357toec5b0a44ecec5b0a44ectob2fac985e8b2fac985e8to01a01b70c701a01b70c7to63ea603e2863ea603e28to6856bd555b6856bd555bto5e900e6c7b5e900e6c7btoaf182c8c80af182c8c80to710668731aView command line instructions
Checkout
From your project repository, check out a new branch and test the changes.