diff --git a/.api-reports/api-report-core.md b/.api-reports/api-report-core.md index 24cf06f5a60..4d86ebc77c6 100644 --- a/.api-reports/api-report-core.md +++ b/.api-reports/api-report-core.md @@ -2226,7 +2226,7 @@ interface WriteContext extends ReadMergeModifyContext { // src/core/ObservableQuery.ts:117:5 - (ae-forgotten-export) The symbol "QueryInfo" needs to be exported by the entry point index.d.ts // src/core/QueryManager.ts:124:5 - (ae-forgotten-export) The symbol "MutationStoreValue" needs to be exported by the entry point index.d.ts // src/core/QueryManager.ts:158:5 - (ae-forgotten-export) The symbol "LocalState" needs to be exported by the entry point index.d.ts -// src/core/QueryManager.ts:399:7 - (ae-forgotten-export) The symbol "UpdateQueries" needs to be exported by the entry point index.d.ts +// src/core/QueryManager.ts:390:7 - (ae-forgotten-export) The symbol "UpdateQueries" needs to be exported by the entry point index.d.ts // src/core/watchQueryOptions.ts:269:2 - (ae-forgotten-export) The symbol "IgnoreModifier" needs to be exported by the entry point index.d.ts // src/core/watchQueryOptions.ts:269:2 - (ae-forgotten-export) The symbol "UpdateQueryFn" needs to be exported by the entry point index.d.ts // src/link/http/selectHttpOptionsAndBody.ts:128:32 - (ae-forgotten-export) The symbol "HttpQueryOptions" needs to be exported by the entry point index.d.ts diff --git a/.api-reports/api-report-react.md b/.api-reports/api-report-react.md index 3489e1e54c3..a0c6572fe2e 100644 --- a/.api-reports/api-report-react.md +++ b/.api-reports/api-report-react.md @@ -2212,6 +2212,8 @@ export function useFragment(options: Us // @public (undocumented) export interface UseFragmentOptions extends Omit, NoInfer>, "id" | "query" | "optimistic" | "previousResult" | "returnPartialData">, Omit, "id" | "variables" | "returnPartialData"> { + // Warning: (ae-unresolved-link) The @link reference could not be resolved: The package "@apollo/client" does not have an export "ApolloClient" + client?: ApolloClient; // (undocumented) from: StoreObject | Reference | string; // (undocumented) @@ -2391,7 +2393,7 @@ interface WatchQueryOptions(options: Us // @public (undocumented) export interface UseFragmentOptions extends Omit, NoInfer>, "id" | "query" | "optimistic" | "previousResult" | "returnPartialData">, Omit, "id" | "variables" | "returnPartialData"> { + // Warning: (ae-unresolved-link) The @link reference could not be resolved: The package "@apollo/client" does not have an export "ApolloClient" + client?: ApolloClient; // (undocumented) from: StoreObject | Reference | string; // (undocumented) @@ -2227,7 +2229,7 @@ interface WatchQueryOptions(inter // src/core/ObservableQuery.ts:117:5 - (ae-forgotten-export) The symbol "QueryInfo" needs to be exported by the entry point index.d.ts // src/core/QueryManager.ts:124:5 - (ae-forgotten-export) The symbol "MutationStoreValue" needs to be exported by the entry point index.d.ts // src/core/QueryManager.ts:158:5 - (ae-forgotten-export) The symbol "LocalState" needs to be exported by the entry point index.d.ts -// src/core/QueryManager.ts:399:7 - (ae-forgotten-export) The symbol "UpdateQueries" needs to be exported by the entry point index.d.ts +// src/core/QueryManager.ts:390:7 - (ae-forgotten-export) The symbol "UpdateQueries" needs to be exported by the entry point index.d.ts // src/core/types.ts:174:3 - (ae-forgotten-export) The symbol "MutationQueryReducer" needs to be exported by the entry point index.d.ts // src/core/types.ts:203:5 - (ae-forgotten-export) The symbol "Resolver" needs to be exported by the entry point index.d.ts // src/core/watchQueryOptions.ts:269:2 - (ae-forgotten-export) The symbol "IgnoreModifier" needs to be exported by the entry point index.d.ts diff --git a/.api-reports/api-report-react_ssr.md b/.api-reports/api-report-react_ssr.md index a6057e4a7eb..477152f332d 100644 --- a/.api-reports/api-report-react_ssr.md +++ b/.api-reports/api-report-react_ssr.md @@ -1641,7 +1641,7 @@ interface WatchQueryOptions(it: (...args: TArgs // src/core/ObservableQuery.ts:117:5 - (ae-forgotten-export) The symbol "QueryInfo" needs to be exported by the entry point index.d.ts // src/core/QueryManager.ts:124:5 - (ae-forgotten-export) The symbol "MutationStoreValue" needs to be exported by the entry point index.d.ts // src/core/QueryManager.ts:158:5 - (ae-forgotten-export) The symbol "LocalState" needs to be exported by the entry point index.d.ts -// src/core/QueryManager.ts:399:7 - (ae-forgotten-export) The symbol "UpdateQueries" needs to be exported by the entry point index.d.ts +// src/core/QueryManager.ts:390:7 - (ae-forgotten-export) The symbol "UpdateQueries" needs to be exported by the entry point index.d.ts // src/core/types.ts:174:3 - (ae-forgotten-export) The symbol "MutationQueryReducer" needs to be exported by the entry point index.d.ts // src/core/types.ts:203:5 - (ae-forgotten-export) The symbol "Resolver" needs to be exported by the entry point index.d.ts // src/core/watchQueryOptions.ts:269:2 - (ae-forgotten-export) The symbol "IgnoreModifier" needs to be exported by the entry point index.d.ts diff --git a/.api-reports/api-report-testing_core.md b/.api-reports/api-report-testing_core.md index 202108f79c7..0243870d739 100644 --- a/.api-reports/api-report-testing_core.md +++ b/.api-reports/api-report-testing_core.md @@ -1660,7 +1660,7 @@ export function withWarningSpy(it: (...args: TArgs // src/core/ObservableQuery.ts:117:5 - (ae-forgotten-export) The symbol "QueryInfo" needs to be exported by the entry point index.d.ts // src/core/QueryManager.ts:124:5 - (ae-forgotten-export) The symbol "MutationStoreValue" needs to be exported by the entry point index.d.ts // src/core/QueryManager.ts:158:5 - (ae-forgotten-export) The symbol "LocalState" needs to be exported by the entry point index.d.ts -// src/core/QueryManager.ts:399:7 - (ae-forgotten-export) The symbol "UpdateQueries" needs to be exported by the entry point index.d.ts +// src/core/QueryManager.ts:390:7 - (ae-forgotten-export) The symbol "UpdateQueries" needs to be exported by the entry point index.d.ts // src/core/types.ts:174:3 - (ae-forgotten-export) The symbol "MutationQueryReducer" needs to be exported by the entry point index.d.ts // src/core/types.ts:203:5 - (ae-forgotten-export) The symbol "Resolver" needs to be exported by the entry point index.d.ts // src/core/watchQueryOptions.ts:269:2 - (ae-forgotten-export) The symbol "IgnoreModifier" needs to be exported by the entry point index.d.ts diff --git a/.api-reports/api-report-utilities.md b/.api-reports/api-report-utilities.md index 715d0827a56..24248cc6669 100644 --- a/.api-reports/api-report-utilities.md +++ b/.api-reports/api-report-utilities.md @@ -2635,7 +2635,7 @@ interface WriteContext extends ReadMergeModifyContext { // src/core/ObservableQuery.ts:117:5 - (ae-forgotten-export) The symbol "QueryInfo" needs to be exported by the entry point index.d.ts // src/core/QueryManager.ts:124:5 - (ae-forgotten-export) The symbol "MutationStoreValue" needs to be exported by the entry point index.d.ts // src/core/QueryManager.ts:158:5 - (ae-forgotten-export) The symbol "LocalState" needs to be exported by the entry point index.d.ts -// src/core/QueryManager.ts:399:7 - (ae-forgotten-export) The symbol "UpdateQueries" needs to be exported by the entry point index.d.ts +// src/core/QueryManager.ts:390:7 - (ae-forgotten-export) The symbol "UpdateQueries" needs to be exported by the entry point index.d.ts // src/core/types.ts:174:3 - (ae-forgotten-export) The symbol "MutationQueryReducer" needs to be exported by the entry point index.d.ts // src/core/types.ts:203:5 - (ae-forgotten-export) The symbol "Resolver" needs to be exported by the entry point index.d.ts // src/core/watchQueryOptions.ts:269:2 - (ae-forgotten-export) The symbol "IgnoreModifier" needs to be exported by the entry point index.d.ts diff --git a/.api-reports/api-report.md b/.api-reports/api-report.md index 9040bd40123..515845e2a26 100644 --- a/.api-reports/api-report.md +++ b/.api-reports/api-report.md @@ -2865,6 +2865,7 @@ export function useFragment(options: Us // @public (undocumented) export interface UseFragmentOptions extends Omit, NoInfer>, "id" | "query" | "optimistic" | "previousResult" | "returnPartialData">, Omit, "id" | "variables" | "returnPartialData"> { + client?: ApolloClient; // (undocumented) from: StoreObject | Reference | string; // (undocumented) @@ -3071,7 +3072,7 @@ interface WriteContext extends ReadMergeModifyContext { // src/core/ObservableQuery.ts:117:5 - (ae-forgotten-export) The symbol "QueryInfo" needs to be exported by the entry point index.d.ts // src/core/QueryManager.ts:124:5 - (ae-forgotten-export) The symbol "MutationStoreValue" needs to be exported by the entry point index.d.ts // src/core/QueryManager.ts:158:5 - (ae-forgotten-export) The symbol "LocalState" needs to be exported by the entry point index.d.ts -// src/core/QueryManager.ts:399:7 - (ae-forgotten-export) The symbol "UpdateQueries" needs to be exported by the entry point index.d.ts +// src/core/QueryManager.ts:390:7 - (ae-forgotten-export) The symbol "UpdateQueries" needs to be exported by the entry point index.d.ts // src/core/watchQueryOptions.ts:269:2 - (ae-forgotten-export) The symbol "IgnoreModifier" needs to be exported by the entry point index.d.ts // src/core/watchQueryOptions.ts:269:2 - (ae-forgotten-export) The symbol "UpdateQueryFn" needs to be exported by the entry point index.d.ts // src/link/http/selectHttpOptionsAndBody.ts:128:32 - (ae-forgotten-export) The symbol "HttpQueryOptions" needs to be exported by the entry point index.d.ts diff --git a/.changeset/brave-cougars-applaud.md b/.changeset/brave-cougars-applaud.md new file mode 100644 index 00000000000..fd319b6b64a --- /dev/null +++ b/.changeset/brave-cougars-applaud.md @@ -0,0 +1,5 @@ +--- +"@apollo/client": patch +--- + +Allows passing in client via options to useFragment diff --git a/.size-limits.json b/.size-limits.json index ca5d4c24594..f2fb4219418 100644 --- a/.size-limits.json +++ b/.size-limits.json @@ -1,4 +1,4 @@ { - "dist/apollo-client.min.cjs": 39149, - "import { ApolloClient, InMemoryCache, HttpLink } from \"dist/index.js\" (production)": 32647 + "dist/apollo-client.min.cjs": 39061, + "import { ApolloClient, InMemoryCache, HttpLink } from \"dist/index.js\" (production)": 32559 } diff --git a/CHANGELOG.md b/CHANGELOG.md index 399686ebdc5..98563a6ba4f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,21 @@ # @apollo/client +## 3.9.2 + +### Patch Changes + +- [#11552](https://github.com/apollographql/apollo-client/pull/11552) [`6ac2b0c`](https://github.com/apollographql/apollo-client/commit/6ac2b0ce4d999c63478d85b40ad56ccda9624797) Thanks [@jerelmiller](https://github.com/jerelmiller)! - Fix import in `useLazyRef` causing import issues in the nextjs package. + +## 3.9.1 + +### Patch Changes + +- [#11516](https://github.com/apollographql/apollo-client/pull/11516) [`8390fea`](https://github.com/apollographql/apollo-client/commit/8390fea13175bada8361ba5f0df2e43197085aba) Thanks [@phryneas](https://github.com/phryneas)! - Fix an incorrect string substitution in a warning message. + +- [#11515](https://github.com/apollographql/apollo-client/pull/11515) [`c9bf93b`](https://github.com/apollographql/apollo-client/commit/c9bf93bdc2816f7fdba96961e1435f463f440bd1) Thanks [@vladar](https://github.com/vladar)! - Avoid redundant refetchQueries call for mutation with no-cache policy (fixes #10238) + +- [#11545](https://github.com/apollographql/apollo-client/pull/11545) [`84a6bea`](https://github.com/apollographql/apollo-client/commit/84a6beaeae69acdffea49ba6b8242752cc188172) Thanks [@alessbell](https://github.com/alessbell)! - Remove error thrown by `inFlightLinkObservables` intended to be removed before 3.9 release. + ## 3.9.0 ### Minor Changes diff --git a/docs/shared/ApiDoc/EnumDetails.js b/docs/shared/ApiDoc/EnumDetails.js index a0f7966f55e..7c7587cc0cc 100644 --- a/docs/shared/ApiDoc/EnumDetails.js +++ b/docs/shared/ApiDoc/EnumDetails.js @@ -47,7 +47,6 @@ export function EnumDetails({ mr="1" as={Text} since - link id={`${item.displayName.toLowerCase()}-member-${member.displayName.toLowerCase()}`} /> { @@ -41,9 +41,16 @@ export function FunctionSignature({ paramSignature = "\n " + paramSignature + "\n"; } + const genericSignature = + typeParameters?.length ? + `<${typeParameters.map((p) => p.name).join(", ")}>` + : ""; + const signature = `${arrow ? "" : "function "}${ name ? displayName : "" - }(${paramSignature})${arrow ? " =>" : ":"} ${returnType}`; + }${genericSignature}(${paramSignature})${arrow ? " =>" : ":"} ${ + returnType.type + }`; return highlight ? @@ -65,24 +72,20 @@ export function ReturnType({ canonicalReference }) { const getItem = useApiDocContext(); const item = getItem(canonicalReference); - const interfaceReference = getInterfaceReference( - item.returnType, - item, - getItem - ); return ( <> {item.comment?.returns} - {item.returnType} + {item.returnType.type} - {interfaceReference ? + {item.returnType.primaryCanonicalReference?.endsWith(":interface") ?
Show/hide child attributes
@@ -153,7 +156,8 @@ export function FunctionDetails({ )} {( - result === false || (result === undefined && item.returnType === "void") + result === false || + (result === undefined && item.returnType.type === "void") ) ? null : <> diff --git a/docs/shared/ApiDoc/ParameterTable.js b/docs/shared/ApiDoc/ParameterTable.js index 44bd51feada..40be1a6f8f1 100644 --- a/docs/shared/ApiDoc/ParameterTable.js +++ b/docs/shared/ApiDoc/ParameterTable.js @@ -3,12 +3,7 @@ import { useMDXComponents } from "@mdx-js/react"; import PropTypes from "prop-types"; import React from "react"; import { GridItem, Text } from "@chakra-ui/react"; -import { - PropertySignatureTable, - SectionHeading, - getInterfaceReference, - useApiDocContext, -} from "."; +import { PropertySignatureTable, useApiDocContext } from "."; import { ResponsiveGrid } from "./ResponsiveGrid"; export function ParameterTable({ canonicalReference }) { @@ -25,11 +20,10 @@ export function ParameterTable({ canonicalReference }) { Description {item.parameters.map((parameter) => { - const interfaceReference = getInterfaceReference( - parameter.type, - item, - getItem - ); + const interfaceReference = + parameter.primaryCanonicalReference?.endsWith(":interface") ? + parameter.primaryCanonicalReference + : undefined; const id = `${item.displayName.toLowerCase()}-parameters-${parameter.name.toLowerCase()}`; return ( @@ -68,7 +62,8 @@ export function ParameterTable({ canonicalReference }) { Show/hide child attributes diff --git a/docs/shared/ApiDoc/PropertySignatureTable.js b/docs/shared/ApiDoc/PropertySignatureTable.js index 40fa53b3df6..e82675db695 100644 --- a/docs/shared/ApiDoc/PropertySignatureTable.js +++ b/docs/shared/ApiDoc/PropertySignatureTable.js @@ -19,6 +19,7 @@ export function PropertySignatureTable({ display = "parent", customOrder = [], idPrefix = "", + genericNames, }) { const MDX = useMDXComponents(); const getItem = useApiDocContext(); @@ -36,6 +37,28 @@ export function PropertySignatureTable({ ); } + const replaceGenericNames = React.useMemo(() => { + if (!genericNames) return (str) => str; + + const replacements = {}; + item.typeParameters.forEach((p, i) => { + if (genericNames[i] === p.name) return; + replacements[p.name] = genericNames[i]; + }); + if (!Object.values(replacements).length) return (str) => str; + + const genericReplacementRegex = new RegExp( + `\\b(${Object.keys(replacements).join("|")})\\b`, + "g" + ); + function replace(match) { + return replacements[match] || match; + } + return function replaceGenericNames(str) { + return str.replace(genericReplacementRegex, replace); + }; + }); + return ( <> {item.childrenIncomplete ? @@ -55,7 +78,7 @@ export function PropertySignatureTable({ : null} {Object.entries(groupedProperties).map( ([groupName, sortedProperties]) => ( - <> + {groupName ? {groupName} : null} @@ -79,7 +102,6 @@ export function PropertySignatureTable({ : null } suffix={property.optional ? (optional) : null} - link={!!idPrefix} id={ idPrefix ? `${idPrefix}-${property.displayName.toLowerCase()}` @@ -94,7 +116,7 @@ export function PropertySignatureTable({ parameterTypes arrow /> - : property.type} + : replaceGenericNames(property.type)} @@ -109,7 +131,7 @@ export function PropertySignatureTable({ ))} - + ) )} @@ -124,4 +146,5 @@ PropertySignatureTable.propTypes = { display: PropTypes.oneOf(["parent", "child"]), customOrder: PropTypes.arrayOf(PropTypes.string), idPrefix: PropTypes.string, + genericNames: PropTypes.arrayOf(PropTypes.string), }; diff --git a/docs/shared/ApiDoc/getInterfaceReference.js b/docs/shared/ApiDoc/getInterfaceReference.js deleted file mode 100644 index b9b9202ae92..00000000000 --- a/docs/shared/ApiDoc/getInterfaceReference.js +++ /dev/null @@ -1,8 +0,0 @@ -export function getInterfaceReference(type, item, getItem) { - const baseType = type.replace(/\b(Partial|Omit|Promise) r.text === baseType)?.canonicalReference, - false - ); - return reference?.kind === "Interface" ? reference : null; -} diff --git a/docs/shared/ApiDoc/index.js b/docs/shared/ApiDoc/index.js index 06728b10116..87e85357bbf 100644 --- a/docs/shared/ApiDoc/index.js +++ b/docs/shared/ApiDoc/index.js @@ -15,5 +15,4 @@ export { ParameterTable } from "./ParameterTable"; export { PropertyDetails } from "./PropertyDetails"; export { EnumDetails } from "./EnumDetails"; export { ManualTuple } from "./Tuple"; -export { getInterfaceReference } from "./getInterfaceReference"; export { SourceLink } from "./SourceLink"; diff --git a/integration-tests/next/package.json b/integration-tests/next/package.json index 9ec7bcdb050..8b87f47807a 100644 --- a/integration-tests/next/package.json +++ b/integration-tests/next/package.json @@ -12,7 +12,7 @@ }, "dependencies": { "@apollo/client": "^3.8.0-beta.4", - "@apollo/experimental-nextjs-app-support": "^0.3.1", + "@apollo/experimental-nextjs-app-support": "^0.7.0", "@graphql-tools/schema": "^10.0.0", "@types/node": "20.3.1", "@types/react": "18.2.14", diff --git a/integration-tests/package-lock.json b/integration-tests/package-lock.json index aec4d42433e..114a91c52b6 100644 --- a/integration-tests/package-lock.json +++ b/integration-tests/package-lock.json @@ -11422,7 +11422,7 @@ "version": "0.1.0", "dependencies": { "@apollo/client": "^3.8.0-beta.4", - "@apollo/experimental-nextjs-app-support": "^0.3.1", + "@apollo/experimental-nextjs-app-support": "^0.7.0", "@graphql-tools/schema": "^10.0.0", "@types/node": "20.3.1", "@types/react": "18.2.14", diff --git a/netlify.toml b/netlify.toml index 67879a8b0ba..510fb6a139b 100644 --- a/netlify.toml +++ b/netlify.toml @@ -7,7 +7,7 @@ [context.deploy-preview.build] base = "docs" - ignore = "git diff --quiet $CACHED_COMMIT_REF $COMMIT_REF ." + ignore = "git diff --quiet $CACHED_COMMIT_REF $COMMIT_REF . ../src" command = """\ npm i npm run docmodel diff --git a/package-lock.json b/package-lock.json index 3e36f50e536..0c2f3fcf301 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "@apollo/client", - "version": "3.9.0", + "version": "3.9.2", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "@apollo/client", - "version": "3.9.0", + "version": "3.9.2", "hasInstallScript": true, "license": "MIT", "dependencies": { diff --git a/package.json b/package.json index ea7d8df5a5a..bded6bc8259 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@apollo/client", - "version": "3.9.0", + "version": "3.9.2", "description": "A fully-featured caching GraphQL client.", "private": true, "keywords": [ diff --git a/src/__tests__/client.ts b/src/__tests__/client.ts index c435220e116..2b0e3fe74cf 100644 --- a/src/__tests__/client.ts +++ b/src/__tests__/client.ts @@ -2686,6 +2686,35 @@ describe("client", () => { spy.mockRestore(); }); + // See https://github.com/apollographql/apollo-client/issues/10238 + it("does not call QueryManager.refetchQueries for mutations with no-cache policy", async () => { + const mutation = gql` + mutation { + noop + } + `; + const link = mockSingleLink({ + request: { query: mutation }, + result: { data: { noop: false } }, + }); + + const client = new ApolloClient({ + link, + cache: new InMemoryCache(), + }); + + const spy = jest.spyOn(client["queryManager"], "refetchQueries"); + spy.mockImplementation(() => new Map()); + + await client.mutate({ + mutation, + fetchPolicy: "no-cache", + }); + + expect(spy).not.toHaveBeenCalled(); + spy.mockRestore(); + }); + it("has a getObservableQueries method which calls QueryManager", async () => { const client = new ApolloClient({ link: ApolloLink.empty(), diff --git a/src/__tests__/mutationResults.ts b/src/__tests__/mutationResults.ts index aa9a6183937..7f140dc17a0 100644 --- a/src/__tests__/mutationResults.ts +++ b/src/__tests__/mutationResults.ts @@ -2,7 +2,7 @@ import { cloneDeep } from "lodash"; import gql from "graphql-tag"; import { GraphQLError } from "graphql"; -import { ApolloClient } from "../core"; +import { ApolloClient, FetchResult } from "../core"; import { InMemoryCache } from "../cache"; import { ApolloLink } from "../link/core"; import { @@ -1819,5 +1819,40 @@ describe("mutation results", () => { }, reject); } ); + + itAsync( + "data might be undefined in case of failure with errorPolicy = ignore", + async (resolve, reject) => { + const client = new ApolloClient({ + cache: new InMemoryCache(), + link: new ApolloLink( + () => + new Observable>((observer) => { + observer.next({ + errors: [new GraphQLError("Oops")], + }); + observer.complete(); + }) + ).setOnError(reject), + }); + + const ignoreErrorsResult = await client.mutate({ + mutation: gql` + mutation Foo { + foo + } + `, + fetchPolicy: "no-cache", + errorPolicy: "ignore", + }); + + expect(ignoreErrorsResult).toEqual({ + data: undefined, + errors: undefined, + }); + + resolve(); + } + ); }); }); diff --git a/src/core/ApolloClient.ts b/src/core/ApolloClient.ts index 55bae5b11a9..e564a249c10 100644 --- a/src/core/ApolloClient.ts +++ b/src/core/ApolloClient.ts @@ -426,7 +426,8 @@ export class ApolloClient implements DataProxy { /** * This resolves a single mutation according to the options specified and returns a * Promise which is either resolved with the resulting data or rejected with an - * error. + * error. In some cases both `data` and `errors` might be undefined, for example + * when `errorPolicy` is set to `'ignore'`. * * It takes options as an object with the following keys and values: */ diff --git a/src/core/QueryManager.ts b/src/core/QueryManager.ts index c8403d1420f..d97d8f23153 100644 --- a/src/core/QueryManager.ts +++ b/src/core/QueryManager.ts @@ -188,15 +188,6 @@ export class QueryManager { if ((this.onBroadcast = onBroadcast)) { this.mutationStore = Object.create(null); } - - // TODO: remove before we release 3.9 - Object.defineProperty(this.inFlightLinkObservables, "get", { - value: () => { - throw new Error( - "This version of Apollo Client requires at least @apollo/experimental-nextjs-app-support version 0.5.2." - ); - }, - }); } /** @@ -492,7 +483,7 @@ export class QueryManager { if ( cacheWrites.length > 0 || - mutation.refetchQueries || + (mutation.refetchQueries || "").length > 0 || mutation.update || mutation.onQueryUpdated || mutation.removeOptimistic @@ -946,7 +937,7 @@ export class QueryManager { invariant.warn( typeof nameOrDoc === "string" ? `Unknown query named "%s" requested in refetchQueries options.include array` - : `Unknown query %s requested in refetchQueries options.include array`, + : `Unknown query %o requested in refetchQueries options.include array`, nameOrDoc ); } diff --git a/src/link/core/types.ts b/src/link/core/types.ts index 0e0e815e192..37fdae3cb57 100644 --- a/src/link/core/types.ts +++ b/src/link/core/types.ts @@ -85,6 +85,7 @@ export interface SingleExecutionResult< TContext = DefaultContext, TExtensions = Record, > extends ExecutionResult { + // data might be undefined if errorPolicy was set to 'ignore' data?: TData | null; context?: TContext; } diff --git a/src/react/hooks/__tests__/useFragment.test.tsx b/src/react/hooks/__tests__/useFragment.test.tsx index 9184f18d13f..27f4857edd6 100644 --- a/src/react/hooks/__tests__/useFragment.test.tsx +++ b/src/react/hooks/__tests__/useFragment.test.tsx @@ -333,6 +333,55 @@ describe("useFragment", () => { screen.getByText(/Item #1/); }); + it("allows the client to be overriden", () => { + const ItemFragment: TypedDocumentNode = gql` + fragment ItemFragment on Item { + id + text + } + `; + const cache = new InMemoryCache(); + const item = { __typename: "Item", id: 1, text: "Item #1" }; + cache.writeFragment({ + fragment: ItemFragment, + data: item, + }); + const client = new ApolloClient({ + cache, + }); + function Component() { + const { data } = useFragment({ + fragment: ItemFragment, + from: { __typename: "Item", id: 1 }, + client, + }); + return <>{data.text}; + } + + // Without a MockedProvider supplying the client via context, + // the client must be passed directly to the hook or an error is thrown + expect(() => render()).not.toThrow(/pass an ApolloClient/); + + // Item #1 is rendered + screen.getByText(/Item #1/); + }); + + it("throws if no client is provided", () => { + function Component() { + const { data } = useFragment({ + fragment: ItemFragment, + from: { __typename: "Item", id: 1 }, + }); + return <>{data.text}; + } + + // silence the console error + { + using _spy = spyOnConsole("error"); + expect(() => render()).toThrow(/pass an ApolloClient/); + } + }); + it.each>([ // This query uses a basic field-level @nonreactive directive. gql` @@ -1721,6 +1770,7 @@ describe.skip("Type Tests", () => { optimistic?: boolean; variables?: TVars; canonizeResults?: boolean; + client?: ApolloClient; }>(); }); }); diff --git a/src/react/hooks/internal/useLazyRef.ts b/src/react/hooks/internal/useLazyRef.ts index 645872aa9bd..2656a2773a4 100644 --- a/src/react/hooks/internal/useLazyRef.ts +++ b/src/react/hooks/internal/useLazyRef.ts @@ -1,4 +1,4 @@ -import * as React from "react"; +import * as React from "rehackt"; const INIT = {}; diff --git a/src/react/hooks/useFragment.ts b/src/react/hooks/useFragment.ts index f92bc8f42f1..80e59d0e49a 100644 --- a/src/react/hooks/useFragment.ts +++ b/src/react/hooks/useFragment.ts @@ -12,7 +12,7 @@ import type { import { useApolloClient } from "./useApolloClient.js"; import { useSyncExternalStore } from "./useSyncExternalStore.js"; -import type { OperationVariables } from "../../core/index.js"; +import type { ApolloClient, OperationVariables } from "../../core/index.js"; import type { NoInfer } from "../types/types.js"; import { useDeepMemo, useLazyRef } from "./internal/index.js"; @@ -28,6 +28,15 @@ export interface UseFragmentOptions from: StoreObject | Reference | string; // Override this field to make it optional (default: true). optimistic?: boolean; + /** + * The instance of {@link ApolloClient} to use to look up the fragment. + * + * By default, the instance that's passed down via context is used, but you + * can provide a different instance here. + * + * @docGroup 1. Operation options + */ + client?: ApolloClient; } export type UseFragmentResult = @@ -45,7 +54,7 @@ export type UseFragmentResult = export function useFragment( options: UseFragmentOptions ): UseFragmentResult { - const { cache } = useApolloClient(); + const { cache } = useApolloClient(options.client); const diffOptions = useDeepMemo>(() => { const {