UNPKG

@apollo/client

Version:

A fully-featured caching GraphQL client.

1 lines 102 kB
{"version":3,"file":"ApolloClient.cjs","sources":["../../../src/core/ApolloClient.ts"],"sourcesContent":["import type { DocumentNode } from \"graphql\";\nimport { OperationTypeNode } from \"graphql\";\nimport type { Observable } from \"rxjs\";\nimport { map } from \"rxjs\";\n\nimport type {\n ApolloCache,\n IgnoreModifier,\n Reference,\n} from \"@apollo/client/cache\";\nimport type { Incremental } from \"@apollo/client/incremental\";\nimport { NotImplementedHandler } from \"@apollo/client/incremental\";\nimport type { ApolloLink } from \"@apollo/client/link\";\nimport { execute } from \"@apollo/client/link\";\nimport type { ClientAwarenessLink } from \"@apollo/client/link/client-awareness\";\nimport type { LocalState } from \"@apollo/client/local-state\";\nimport type { MaybeMasked, Unmasked } from \"@apollo/client/masking\";\nimport { DocumentTransform } from \"@apollo/client/utilities\";\nimport { __DEV__ } from \"@apollo/client/utilities/environment\";\nimport type {\n VariablesOption,\n variablesUnknownSymbol,\n} from \"@apollo/client/utilities/internal\";\nimport {\n checkDocument,\n compact,\n getApolloClientMemoryInternals,\n mergeOptions,\n removeMaskedFragmentSpreads,\n} from \"@apollo/client/utilities/internal\";\nimport { invariant } from \"@apollo/client/utilities/invariant\";\n\nimport { version } from \"../version.js\";\n\nimport type { ObservableQuery } from \"./ObservableQuery.js\";\nimport { QueryManager } from \"./QueryManager.js\";\nimport type {\n DefaultContext,\n ErrorLike,\n InternalRefetchQueriesInclude,\n InternalRefetchQueriesResult,\n MutationQueryReducersMap,\n MutationUpdaterFunction,\n NormalizedExecutionResult,\n OnQueryUpdated,\n OperationVariables,\n RefetchQueriesInclude,\n RefetchQueriesPromiseResults,\n SubscriptionObservable,\n TypedDocumentNode,\n} from \"./types.js\";\nimport type {\n ErrorPolicy,\n FetchPolicy,\n MutationFetchPolicy,\n NextFetchPolicyContext,\n RefetchWritePolicy,\n WatchQueryFetchPolicy,\n} from \"./watchQueryOptions.js\";\n\nlet hasSuggestedDevtools = false;\n\nexport declare namespace ApolloClient {\n export interface DefaultOptions {\n watchQuery?: Partial<ApolloClient.WatchQueryOptions<any, any>>;\n query?: Partial<ApolloClient.QueryOptions<any, any>>;\n mutate?: Partial<ApolloClient.MutateOptions<any, any, any>>;\n }\n\n export interface Options {\n /**\n * An `ApolloLink` instance to serve as Apollo Client's network layer. For more information, see [Advanced HTTP networking](https://www.apollographql.com/docs/react/networking/advanced-http-networking/).\n */\n link: ApolloLink;\n /**\n * The cache that Apollo Client should use to store query results locally. The recommended cache is `InMemoryCache`, which is provided by the `@apollo/client` package.\n *\n * For more information, see [Configuring the cache](https://www.apollographql.com/docs/react/caching/cache-configuration/).\n */\n cache: ApolloCache;\n /**\n * The time interval (in milliseconds) before Apollo Client force-fetches queries after a server-side render.\n *\n * @defaultValue `0` (no delay)\n */\n ssrForceFetchDelay?: number;\n /**\n * When using Apollo Client for [server-side rendering](https://www.apollographql.com/docs/react/performance/server-side-rendering/), set this to `true` so that the [`getDataFromTree` function](../react/ssr/#getdatafromtree) can work effectively.\n *\n * @defaultValue `false`\n */\n ssrMode?: boolean;\n /**\n * If `false`, Apollo Client sends every created query to the server, even if a _completely_ identical query (identical in terms of query string, variable values, and operationName) is already in flight.\n *\n * @defaultValue `true`\n */\n queryDeduplication?: boolean;\n /**\n * Provide this object to set application-wide default values for options you can provide to the `watchQuery`, `query`, and `mutate` functions. See below for an example object.\n *\n * See this [example object](https://www.apollographql.com/docs/react/api/core/ApolloClient#example-defaultoptions-object).\n */\n defaultOptions?: ApolloClient.DefaultOptions;\n defaultContext?: Partial<DefaultContext>;\n /**\n * If `true`, Apollo Client will assume results read from the cache are never mutated by application code, which enables substantial performance optimizations.\n *\n * @defaultValue `false`\n */\n assumeImmutableResults?: boolean;\n localState?: LocalState;\n /** {@inheritDoc @apollo/client/link/client-awareness!ClientAwarenessLink.ClientAwarenessOptions:interface} */\n clientAwareness?: ClientAwarenessLink.ClientAwarenessOptions;\n /** {@inheritDoc @apollo/client/link/client-awareness!ClientAwarenessLink.EnhancedClientAwarenessOptions:interface} */\n enhancedClientAwareness?: ClientAwarenessLink.EnhancedClientAwarenessOptions;\n documentTransform?: DocumentTransform;\n\n /**\n * Configuration used by the [Apollo Client Devtools extension](https://www.apollographql.com/docs/react/development-testing/developer-tooling/#apollo-client-devtools) for this client.\n *\n * @since 3.11.0\n */\n devtools?: ApolloClient.DevtoolsOptions;\n\n /**\n * Determines if data masking is enabled for the client.\n *\n * @defaultValue false\n */\n dataMasking?: boolean;\n\n /**\n * Determines the strategy used to parse incremental chunks from `@defer`\n * queries.\n */\n incrementalHandler?: Incremental.Handler<any>;\n }\n\n interface DevtoolsOptions {\n /**\n * If `true`, the [Apollo Client Devtools](https://www.apollographql.com/docs/react/development-testing/developer-tooling/#apollo-client-devtools) browser extension can connect to this `ApolloClient` instance.\n *\n * The default value is `false` in production and `true` in development if there is a `window` object.\n */\n enabled?: boolean;\n\n /**\n * Optional name for this `ApolloClient` instance in the devtools. This is\n * useful when you instantiate multiple clients and want to be able to\n * identify them by name.\n */\n name?: string;\n }\n\n export type MutateOptions<\n TData = unknown,\n TVariables extends OperationVariables = OperationVariables,\n TCache extends ApolloCache = ApolloCache,\n > = {\n /** {@inheritDoc @apollo/client!MutationOptionsDocumentation#optimisticResponse:member} */\n optimisticResponse?:\n | Unmasked<NoInfer<TData>>\n | ((\n vars: TVariables,\n { IGNORE }: { IGNORE: IgnoreModifier }\n ) => Unmasked<NoInfer<TData>> | IgnoreModifier);\n\n /** {@inheritDoc @apollo/client!MutationOptionsDocumentation#updateQueries:member} */\n updateQueries?: MutationQueryReducersMap<TData>;\n\n /** {@inheritDoc @apollo/client!MutationOptionsDocumentation#refetchQueries:member} */\n refetchQueries?:\n | ((\n result: NormalizedExecutionResult<Unmasked<TData>>\n ) => InternalRefetchQueriesInclude)\n | InternalRefetchQueriesInclude;\n\n /** {@inheritDoc @apollo/client!MutationOptionsDocumentation#awaitRefetchQueries:member} */\n awaitRefetchQueries?: boolean;\n\n /** {@inheritDoc @apollo/client!MutationOptionsDocumentation#update:member} */\n update?: MutationUpdaterFunction<TData, TVariables, TCache>;\n\n /** {@inheritDoc @apollo/client!MutationOptionsDocumentation#onQueryUpdated:member} */\n onQueryUpdated?: OnQueryUpdated<any>;\n\n /** {@inheritDoc @apollo/client!MutationOptionsDocumentation#errorPolicy:member} */\n errorPolicy?: ErrorPolicy;\n\n /** {@inheritDoc @apollo/client!MutationOptionsDocumentation#context:member} */\n context?: DefaultContext;\n\n /** {@inheritDoc @apollo/client!MutationOptionsDocumentation#fetchPolicy:member} */\n fetchPolicy?: MutationFetchPolicy;\n\n /** {@inheritDoc @apollo/client!MutationOptionsDocumentation#keepRootFields:member} */\n keepRootFields?: boolean;\n\n /** {@inheritDoc @apollo/client!MutationOptionsDocumentation#mutation:member} */\n mutation: DocumentNode | TypedDocumentNode<TData, TVariables>;\n } & VariablesOption<NoInfer<TVariables>>;\n\n export interface MutateResult<TData = unknown> {\n /** {@inheritDoc @apollo/client!MutationResultDocumentation#data:member} */\n data: TData | undefined;\n\n /** {@inheritDoc @apollo/client!MutationResultDocumentation#error:member} */\n error?: ErrorLike;\n\n /** {@inheritDoc @apollo/client!MutationResultDocumentation#extensions:member} */\n extensions?: Record<string, unknown>;\n }\n\n /**\n * Query options.\n */\n export type QueryOptions<\n TData = unknown,\n TVariables extends OperationVariables = OperationVariables,\n > = {\n /** {@inheritDoc @apollo/client!QueryOptionsDocumentation#query:member} */\n query: DocumentNode | TypedDocumentNode<TData, TVariables>;\n\n /** {@inheritDoc @apollo/client!QueryOptionsDocumentation#errorPolicy:member} */\n errorPolicy?: ErrorPolicy;\n\n /** {@inheritDoc @apollo/client!QueryOptionsDocumentation#context:member} */\n context?: DefaultContext;\n\n /** {@inheritDoc @apollo/client!QueryOptionsDocumentation#fetchPolicy:member} */\n fetchPolicy?: FetchPolicy;\n } & VariablesOption<NoInfer<TVariables>>;\n\n export interface QueryResult<TData = unknown> {\n /** {@inheritDoc @apollo/client!QueryResultDocumentation#data:member} */\n data: TData | undefined;\n\n /** {@inheritDoc @apollo/client!QueryResultDocumentation#error:member} */\n error?: ErrorLike;\n }\n\n /**\n * Options object for the `client.refetchQueries` method.\n */\n export interface RefetchQueriesOptions<TCache extends ApolloCache, TResult> {\n /**\n * Optional function that updates cached fields to trigger refetches of queries that include those fields.\n */\n updateCache?: (cache: TCache) => void;\n\n /**\n * Optional array specifying queries to refetch. Each element can be either a query's string name or a `DocumentNode` object.\n *\n * Pass `\"active\"` as a shorthand to refetch all active queries, or `\"all\"` to refetch all active and inactive queries.\n *\n * Analogous to the [`options.refetchQueries`](https://www.apollographql.com/docs/react/data/mutations/#options) array for mutations.\n */\n include?: RefetchQueriesInclude;\n\n /**\n * If `true`, the `options.updateCache` function is executed on a temporary optimistic layer of `InMemoryCache`, so its modifications can be discarded from the cache after observing which fields it invalidated.\n *\n * Defaults to `false`, meaning `options.updateCache` updates the cache in a lasting way.\n */\n optimistic?: boolean;\n\n /**\n * Optional callback function that's called once for each `ObservableQuery` that's either affected by `options.updateCache` or listed in `options.include` (or both).\n *\n * If `onQueryUpdated` is not provided, the default implementation returns the result of calling `observableQuery.refetch()`. When `onQueryUpdated` is provided, it can dynamically decide whether (and how) each query should be refetched.\n *\n * Returning `false` from `onQueryUpdated` prevents the associated query from being refetched.\n */\n onQueryUpdated?: OnQueryUpdated<TResult> | null;\n }\n\n /**\n * The result of client.refetchQueries is thenable/awaitable, if you just want\n * an array of fully resolved results, but you can also access the raw results\n * immediately by examining the additional `queries` and `results` properties of\n * the `RefetchQueriesResult<TResult> object`.\n */\n export interface RefetchQueriesResult<TResult>\n extends Promise<RefetchQueriesPromiseResults<TResult>>,\n RefetchQueriesResult.AdditionalProperties<TResult> {}\n\n export namespace RefetchQueriesResult {\n export interface AdditionalProperties<TResult> {\n /**\n * An array of ObservableQuery objects corresponding 1:1 to TResult values\n * in the results arrays (both the `result` property and the resolved value).\n */\n queries: ObservableQuery<any>[];\n /**\n * An array of results that were either returned by `onQueryUpdated`, or provided by default in the absence of `onQueryUpdated`, including pending promises.\n *\n * If `onQueryUpdated` returns `false` for a given query, no result is provided for that query.\n *\n * If `onQueryUpdated` returns `true`, the resulting `Promise<ApolloQueryResult<any>>` is included in the `results` array instead of `true`.\n */\n results: InternalRefetchQueriesResult<TResult>[];\n }\n }\n\n export type SubscribeOptions<\n TData = unknown,\n TVariables extends OperationVariables = OperationVariables,\n > = {\n /** {@inheritDoc @apollo/client!SubscriptionOptionsDocumentation#query:member} */\n query: DocumentNode | TypedDocumentNode<TData, TVariables>;\n\n /** {@inheritDoc @apollo/client!SubscriptionOptionsDocumentation#fetchPolicy:member} */\n fetchPolicy?: FetchPolicy;\n\n /** {@inheritDoc @apollo/client!SubscriptionOptionsDocumentation#errorPolicy:member} */\n errorPolicy?: ErrorPolicy;\n\n /** {@inheritDoc @apollo/client!SubscriptionOptionsDocumentation#context:member} */\n context?: DefaultContext;\n\n /** {@inheritDoc @apollo/client!SubscriptionOptionsDocumentation#extensions:member} */\n extensions?: Record<string, any>;\n } & VariablesOption<NoInfer<TVariables>>;\n\n export interface SubscribeResult<TData = unknown> {\n /** {@inheritDoc @apollo/client!MutationResultDocumentation#data:member} */\n data: TData | undefined;\n\n /** {@inheritDoc @apollo/client!MutationResultDocumentation#error:member} */\n error?: ErrorLike;\n\n /** {@inheritDoc @apollo/client!MutationResultDocumentation#extensions:member} */\n extensions?: Record<string, unknown>;\n }\n\n export type WatchFragmentOptions<\n TData = unknown,\n TVariables extends OperationVariables = OperationVariables,\n > = ApolloCache.WatchFragmentOptions<TData, TVariables>;\n\n export type WatchFragmentResult<TData = unknown> =\n ApolloCache.WatchFragmentResult<TData>;\n\n /**\n * Watched query options.\n */\n export type WatchQueryOptions<\n TData = unknown,\n TVariables extends OperationVariables = OperationVariables,\n > = {\n /** {@inheritDoc @apollo/client!QueryOptionsDocumentation#fetchPolicy:member} */\n fetchPolicy?: WatchQueryFetchPolicy;\n\n /** {@inheritDoc @apollo/client!QueryOptionsDocumentation#nextFetchPolicy:member} */\n nextFetchPolicy?:\n | WatchQueryFetchPolicy\n | ((\n this: WatchQueryOptions<TData, TVariables>,\n currentFetchPolicy: WatchQueryFetchPolicy,\n context: NextFetchPolicyContext<TData, TVariables>\n ) => WatchQueryFetchPolicy);\n\n /** {@inheritDoc @apollo/client!QueryOptionsDocumentation#initialFetchPolicy:member} */\n initialFetchPolicy?: WatchQueryFetchPolicy;\n\n /** {@inheritDoc @apollo/client!QueryOptionsDocumentation#refetchWritePolicy:member} */\n refetchWritePolicy?: RefetchWritePolicy;\n\n /** {@inheritDoc @apollo/client!QueryOptionsDocumentation#errorPolicy:member} */\n errorPolicy?: ErrorPolicy;\n\n /** {@inheritDoc @apollo/client!QueryOptionsDocumentation#context:member} */\n context?: DefaultContext;\n\n /** {@inheritDoc @apollo/client!QueryOptionsDocumentation#pollInterval:member} */\n pollInterval?: number;\n\n /** {@inheritDoc @apollo/client!QueryOptionsDocumentation#notifyOnNetworkStatusChange:member} */\n notifyOnNetworkStatusChange?: boolean;\n\n /** {@inheritDoc @apollo/client!QueryOptionsDocumentation#returnPartialData:member} */\n returnPartialData?: boolean;\n\n /** {@inheritDoc @apollo/client!QueryOptionsDocumentation#skipPollAttempt:member} */\n skipPollAttempt?: () => boolean;\n\n /** {@inheritDoc @apollo/client!QueryOptionsDocumentation#query:member} */\n query: DocumentNode | TypedDocumentNode<TData, TVariables>;\n\n /**\n * @internal This API is meant for framework integrations only.\n * Do not use for everyday use.\n *\n * Indicates that the variables are unknown at the time of query creation.\n * This option can only be set when `fetchPolicy` is `'standby'`.\n * Setting this to `true` will prevent `client.refetchQueries` from refetching\n * this query before it has left the `'standby'` state, either by setting a\n * `fetchPolicy`, or by calling `observableQuery.refetch()` explicitly.\n *\n * Changing this option after the query has been created will have no effect.\n */\n [variablesUnknownSymbol]?: boolean;\n } & VariablesOption<NoInfer<TVariables>>;\n\n namespace Base {\n export interface ReadQueryOptions<\n TData,\n TVariables extends OperationVariables,\n > {\n /**\n * The GraphQL query shape to be used constructed using the `gql` template\n * string tag. The query will be used to determine the\n * shape of the data to be read.\n */\n query: DocumentNode | TypedDocumentNode<TData, TVariables>;\n\n /**\n * The root id to be used. Defaults to \"ROOT_QUERY\", which is the ID of the\n * root query object. This property makes `readQuery` capable of reading data\n * from any object in the cache.\n */\n id?: string;\n\n /**\n * Whether to return incomplete data rather than null.\n * @defaultValue false\n */\n returnPartialData?: boolean;\n\n /**\n * Whether to read from optimistic or non-optimistic cache data.\n * This option should be preferred over the `optimistic` parameter of the\n * `readQuery` method.\n * @defaultValue false\n */\n optimistic?: boolean;\n }\n }\n export type ReadQueryOptions<\n TData,\n TVariables extends OperationVariables,\n > = Base.ReadQueryOptions<TData, TVariables> & VariablesOption<TVariables>;\n\n export namespace DocumentationTypes {\n export interface ReadQueryOptions<\n TData,\n TVariables extends OperationVariables,\n > extends Base.ReadQueryOptions<TData, TVariables> {\n /**\n * Any variables that the GraphQL query may depend on.\n */\n variables?: TVariables;\n }\n }\n\n namespace Base {\n export interface ReadFragmentOptions<\n TData,\n TVariables extends OperationVariables,\n > {\n /**\n * The root id to be used. This id should take the same form as the\n * value returned by the `cache.identify` function. If a value with your\n * id does not exist in the store, `null` will be returned.\n */\n id?: string;\n\n /**\n * A GraphQL document created using the `gql` template string tag\n * with one or more fragments which will be used to determine\n * the shape of data to read. If you provide more than one fragment in this\n * document then you must also specify `fragmentName` to specify which\n * fragment is the root fragment.\n */\n fragment: DocumentNode | TypedDocumentNode<TData, TVariables>;\n\n /**\n * The name of the fragment in your GraphQL document to be used. If you do\n * not provide a `fragmentName` and there is only one fragment in your\n * `fragment` document then that fragment will be used.\n */\n fragmentName?: string;\n\n /**\n * Whether to return incomplete data rather than null.\n * @defaultValue false\n */\n returnPartialData?: boolean;\n /**\n * Whether to read from optimistic or non-optimistic cache data.\n * This option should be preferred over the `optimistic` parameter of the\n * `readFragment` method.\n * @defaultValue false\n */\n optimistic?: boolean;\n }\n }\n export type ReadFragmentOptions<\n TData,\n TVariables extends OperationVariables,\n > = Base.ReadFragmentOptions<TData, TVariables> & VariablesOption<TVariables>;\n\n export namespace DocumentationTypes {\n export interface WriteQueryOptions<\n TData,\n TVariables extends OperationVariables,\n > extends Base.WriteQueryOptions<TData, TVariables> {\n /**\n * Any variables that your GraphQL fragments depend on.\n */\n variables?: TVariables;\n }\n }\n\n namespace Base {\n export interface WriteQueryOptions<\n TData,\n TVariables extends OperationVariables,\n > {\n /**\n * The GraphQL query shape to be used constructed using the `gql` template\n * string tag. The query will be used to determine the\n * shape of the data to be read.\n */\n query: DocumentNode | TypedDocumentNode<TData, TVariables>;\n\n /**\n * The root id to be used. Defaults to \"ROOT_QUERY\", which is the ID of the\n * root query object. This property makes writeQuery capable of writing data\n * to any object in the cache.\n */\n id?: string;\n /**\n * The data to write to the store.\n */\n data: Unmasked<TData>;\n /**\n * Whether to notify query watchers.\n * @defaultValue true\n */\n broadcast?: boolean;\n /**\n * When true, ignore existing field data rather than merging it with\n * incoming data.\n * @defaultValue false\n */\n overwrite?: boolean;\n }\n }\n export type WriteQueryOptions<\n TData,\n TVariables extends OperationVariables,\n > = Base.WriteQueryOptions<TData, TVariables> & VariablesOption<TVariables>;\n\n export namespace DocumentationTypes {\n export interface WriteQueryOptions<\n TData,\n TVariables extends OperationVariables,\n > extends Base.WriteQueryOptions<TData, TVariables> {\n /**\n * Any variables that the GraphQL query may depend on.\n */\n variables?: TVariables;\n }\n }\n\n namespace Base {\n export interface WriteFragmentOptions<\n TData,\n TVariables extends OperationVariables,\n > {\n /**\n * The root id to be used. This id should take the same form as the\n * value returned by the `cache.identify` function. If a value with your\n * id does not exist in the store, `null` will be returned.\n */\n id?: string;\n\n /**\n * A GraphQL document created using the `gql` template string tag from\n * `graphql-tag` with one or more fragments which will be used to determine\n * the shape of data to read. If you provide more than one fragment in this\n * document then you must also specify `fragmentName` to specify which\n * fragment is the root fragment.\n */\n fragment: DocumentNode | TypedDocumentNode<TData, TVariables>;\n\n /**\n * The name of the fragment in your GraphQL document to be used. If you do\n * not provide a `fragmentName` and there is only one fragment in your\n * `fragment` document then that fragment will be used.\n */\n fragmentName?: string;\n\n /**\n * The data to write to the store.\n */\n data: Unmasked<TData>;\n /**\n * Whether to notify query watchers.\n * @defaultValue true\n */\n broadcast?: boolean;\n /**\n * When true, ignore existing field data rather than merging it with\n * incoming data.\n * @defaultValue false\n */\n overwrite?: boolean;\n }\n }\n export type WriteFragmentOptions<\n TData,\n TVariables extends OperationVariables,\n > = Base.WriteFragmentOptions<TData, TVariables> &\n VariablesOption<TVariables>;\n\n export namespace DocumentationTypes {\n export interface WriteFragmentOptions<\n TData,\n TVariables extends OperationVariables,\n > extends Base.WriteFragmentOptions<TData, TVariables> {\n /**\n * Any variables that your GraphQL fragments depend on.\n */\n variables?: TVariables;\n }\n }\n}\n\n/**\n * This is the primary Apollo Client class. It is used to send GraphQL documents (i.e. queries\n * and mutations) to a GraphQL spec-compliant server over an `ApolloLink` instance,\n * receive results from the server and cache the results in a store. It also delivers updates\n * to GraphQL queries through `Observable` instances.\n */\nexport class ApolloClient {\n public link: ApolloLink;\n public cache: ApolloCache;\n /**\n * @deprecated `disableNetworkFetches` has been renamed to `prioritizeCacheValues`.\n */\n public disableNetworkFetches!: never;\n\n public set prioritizeCacheValues(value: boolean) {\n this.queryManager.prioritizeCacheValues = value;\n }\n\n /**\n * Whether to prioritize cache values over network results when `query` or `watchQuery` is called.\n * This will essentially turn a `\"network-only\"` or `\"cache-and-network\"` fetchPolicy into a `\"cache-first\"` fetchPolicy,\n * but without influencing the `fetchPolicy` of the created `ObservableQuery` long-term.\n *\n * This can e.g. be used to prioritize the cache during the first render after SSR.\n */\n public get prioritizeCacheValues() {\n return this.queryManager.prioritizeCacheValues;\n }\n public version: string;\n public queryDeduplication: boolean;\n public defaultOptions: ApolloClient.DefaultOptions;\n public readonly devtoolsConfig: ApolloClient.DevtoolsOptions;\n\n private queryManager: QueryManager;\n private devToolsHookCb?: Function;\n private resetStoreCallbacks: Array<() => Promise<any>> = [];\n private clearStoreCallbacks: Array<() => Promise<any>> = [];\n\n /**\n * Constructs an instance of `ApolloClient`.\n *\n * @example\n *\n * ```js\n * import { ApolloClient, InMemoryCache } from \"@apollo/client\";\n *\n * const cache = new InMemoryCache();\n *\n * const client = new ApolloClient({\n * // Provide required constructor fields\n * cache: cache,\n * uri: \"http://localhost:4000/\",\n *\n * // Provide some optional constructor fields\n * name: \"react-web-client\",\n * version: \"1.3\",\n * queryDeduplication: false,\n * defaultOptions: {\n * watchQuery: {\n * fetchPolicy: \"cache-and-network\",\n * },\n * },\n * });\n * ```\n */\n constructor(options: ApolloClient.Options) {\n if (__DEV__) {\n invariant(\n options.cache,\n \"To initialize Apollo Client, you must specify a 'cache' property \" +\n \"in the options object. \\n\" +\n \"For more information, please visit: https://go.apollo.dev/c/docs\"\n );\n\n invariant(\n options.link,\n \"To initialize Apollo Client, you must specify a 'link' property \" +\n \"in the options object. \\n\" +\n \"For more information, please visit: https://go.apollo.dev/c/docs\"\n );\n }\n\n const {\n cache,\n documentTransform,\n ssrMode = false,\n ssrForceFetchDelay = 0,\n queryDeduplication = true,\n defaultOptions,\n defaultContext,\n assumeImmutableResults = cache.assumeImmutableResults,\n localState,\n devtools,\n dataMasking,\n link,\n incrementalHandler = new NotImplementedHandler(),\n } = options;\n\n this.link = link;\n this.cache = cache;\n this.queryDeduplication = queryDeduplication;\n this.defaultOptions = defaultOptions || {};\n this.devtoolsConfig = {\n ...devtools,\n enabled: devtools?.enabled ?? __DEV__,\n };\n\n this.watchQuery = this.watchQuery.bind(this);\n this.query = this.query.bind(this);\n this.mutate = this.mutate.bind(this);\n this.watchFragment = this.watchFragment.bind(this);\n this.resetStore = this.resetStore.bind(this);\n this.reFetchObservableQueries = this.refetchObservableQueries =\n this.refetchObservableQueries.bind(this);\n\n this.version = version;\n\n this.queryManager = new QueryManager({\n client: this,\n defaultOptions: this.defaultOptions,\n defaultContext,\n documentTransform,\n queryDeduplication,\n ssrMode,\n dataMasking: !!dataMasking,\n clientOptions: options,\n incrementalHandler,\n assumeImmutableResults,\n onBroadcast:\n this.devtoolsConfig.enabled ?\n () => {\n if (this.devToolsHookCb) {\n this.devToolsHookCb();\n }\n }\n : void 0,\n localState,\n });\n\n this.prioritizeCacheValues = ssrMode || ssrForceFetchDelay > 0;\n if (ssrForceFetchDelay) {\n setTimeout(() => {\n this.prioritizeCacheValues = false;\n }, ssrForceFetchDelay);\n }\n\n if (this.devtoolsConfig.enabled) this.connectToDevTools();\n }\n\n private connectToDevTools() {\n if (typeof window === \"undefined\") {\n return;\n }\n\n type DevToolsConnector = {\n push(client: ApolloClient): void;\n };\n const windowWithDevTools = window as Window & {\n [devtoolsSymbol]?: DevToolsConnector;\n __APOLLO_CLIENT__?: ApolloClient;\n };\n const devtoolsSymbol = Symbol.for(\"apollo.devtools\");\n (windowWithDevTools[devtoolsSymbol] =\n windowWithDevTools[devtoolsSymbol] || ([] as DevToolsConnector)).push(\n this\n );\n windowWithDevTools.__APOLLO_CLIENT__ = this;\n\n /**\n * Suggest installing the devtools for developers who don't have them\n */\n if (!hasSuggestedDevtools && __DEV__) {\n hasSuggestedDevtools = true;\n if (\n window.document &&\n window.top === window.self &&\n /^(https?|file):$/.test(window.location.protocol)\n ) {\n setTimeout(() => {\n if (!(window as any).__APOLLO_DEVTOOLS_GLOBAL_HOOK__) {\n const nav = window.navigator;\n const ua = nav && nav.userAgent;\n let url: string | undefined;\n if (typeof ua === \"string\") {\n if (ua.indexOf(\"Chrome/\") > -1) {\n url =\n \"https://chrome.google.com/webstore/detail/\" +\n \"apollo-client-developer-t/jdkknkkbebbapilgoeccciglkfbmbnfm\";\n } else if (ua.indexOf(\"Firefox/\") > -1) {\n url =\n \"https://addons.mozilla.org/en-US/firefox/addon/apollo-developer-tools/\";\n }\n }\n if (url) {\n invariant.log(\n \"Download the Apollo DevTools for a better development \" +\n \"experience: %s\",\n url\n );\n }\n }\n }, 10000);\n }\n }\n }\n\n /**\n * The `DocumentTransform` used to modify GraphQL documents before a request\n * is made. If a custom `DocumentTransform` is not provided, this will be the\n * default document transform.\n */\n get documentTransform() {\n return this.queryManager.documentTransform;\n }\n\n /**\n * The configured `LocalState` instance used to enable the use of `@client`\n * fields.\n */\n get localState(): LocalState | undefined {\n return this.queryManager.localState;\n }\n\n set localState(localState: LocalState) {\n this.queryManager.localState = localState;\n }\n\n /**\n * Call this method to terminate any active client processes, making it safe\n * to dispose of this `ApolloClient` instance.\n *\n * This method performs aggressive cleanup to prevent memory leaks:\n *\n * - Unsubscribes all active `ObservableQuery` instances by emitting a `completed` event\n * - Rejects all currently running queries with \"QueryManager stopped while query was in flight\"\n * - Removes all queryRefs from the suspense cache\n */\n public stop() {\n this.queryManager.stop();\n }\n\n /**\n * This watches the cache store of the query according to the options specified and\n * returns an `ObservableQuery`. We can subscribe to this `ObservableQuery` and\n * receive updated results through an observer when the cache store changes.\n *\n * Note that this method is not an implementation of GraphQL subscriptions. Rather,\n * it uses Apollo's store in order to reactively deliver updates to your query results.\n *\n * For example, suppose you call watchQuery on a GraphQL query that fetches a person's\n * first and last name and this person has a particular object identifier, provided by\n * `cache.identify`. Later, a different query fetches that same person's\n * first and last name and the first name has now changed. Then, any observers associated\n * with the results of the first query will be updated with a new result object.\n *\n * Note that if the cache does not change, the subscriber will _not_ be notified.\n *\n * See [here](https://medium.com/apollo-stack/the-concepts-of-graphql-bc68bd819be3#.3mb0cbcmc) for\n * a description of store reactivity.\n */\n public watchQuery<\n TData = unknown,\n TVariables extends OperationVariables = OperationVariables,\n >(\n options: ApolloClient.WatchQueryOptions<TData, TVariables>\n ): ObservableQuery<TData, TVariables> {\n if (this.defaultOptions.watchQuery) {\n options = mergeOptions(\n this.defaultOptions.watchQuery as Partial<\n ApolloClient.WatchQueryOptions<TData, TVariables>\n >,\n options\n );\n }\n\n return this.queryManager.watchQuery<TData, TVariables>(options);\n }\n\n /**\n * This resolves a single query according to the options specified and\n * returns a `Promise` which is either resolved with the resulting data\n * or rejected with an error.\n *\n * @param options - An object of type `QueryOptions` that allows us to\n * describe how this query should be treated e.g. whether it should hit the\n * server at all or just resolve from the cache, etc.\n */\n public query<\n TData = unknown,\n TVariables extends OperationVariables = OperationVariables,\n >(\n options: ApolloClient.QueryOptions<TData, TVariables>\n ): Promise<ApolloClient.QueryResult<MaybeMasked<TData>>> {\n if (this.defaultOptions.query) {\n options = mergeOptions(this.defaultOptions.query, options);\n }\n\n if (__DEV__) {\n invariant(\n (options.fetchPolicy as WatchQueryFetchPolicy) !== \"cache-and-network\",\n \"The cache-and-network fetchPolicy does not work with client.query, because \" +\n \"client.query can only return a single result. Please use client.watchQuery \" +\n \"to receive multiple results from the cache and the network, or consider \" +\n \"using a different fetchPolicy, such as cache-first or network-only.\"\n );\n\n invariant(\n (options.fetchPolicy as WatchQueryFetchPolicy) !== \"standby\",\n \"The standby fetchPolicy does not work with client.query, because \" +\n \"standby does not fetch. Consider using a different fetchPolicy, such \" +\n \"as cache-first or network-only.\"\n );\n\n invariant(\n options.query,\n \"query option is required. You must specify your GraphQL document \" +\n \"in the query option.\"\n );\n\n invariant(\n options.query.kind === \"Document\",\n 'You must wrap the query string in a \"gql\" tag.'\n );\n\n invariant(\n !(options as any).returnPartialData,\n \"returnPartialData option only supported on watchQuery.\"\n );\n\n invariant(\n !(options as any).pollInterval,\n \"pollInterval option only supported on watchQuery.\"\n );\n\n invariant(\n !(options as any).notifyOnNetworkStatusChange,\n \"notifyOnNetworkStatusChange option only supported on watchQuery.\"\n );\n }\n\n return this.queryManager.query<TData, TVariables>(options);\n }\n\n /**\n * This resolves a single mutation according to the options specified and returns a\n * Promise which is either resolved with the resulting data or rejected with an\n * error. In some cases both `data` and `errors` might be undefined, for example\n * when `errorPolicy` is set to `'ignore'`.\n *\n * It takes options as an object with the following keys and values:\n */\n public mutate<\n TData = unknown,\n TVariables extends OperationVariables = OperationVariables,\n TCache extends ApolloCache = ApolloCache,\n >(\n options: ApolloClient.MutateOptions<TData, TVariables, TCache>\n ): Promise<ApolloClient.MutateResult<MaybeMasked<TData>>> {\n const optionsWithDefaults = mergeOptions(\n compact(\n {\n fetchPolicy: \"network-only\" as MutationFetchPolicy,\n errorPolicy: \"none\" as ErrorPolicy,\n },\n this.defaultOptions.mutate\n ),\n options\n ) as ApolloClient.MutateOptions<TData, TVariables, TCache> & {\n fetchPolicy: MutationFetchPolicy;\n errorPolicy: ErrorPolicy;\n };\n\n if (__DEV__) {\n invariant(\n optionsWithDefaults.mutation,\n \"The `mutation` option is required. Please provide a GraphQL document in the `mutation` option.\"\n );\n\n invariant(\n optionsWithDefaults.fetchPolicy === \"network-only\" ||\n optionsWithDefaults.fetchPolicy === \"no-cache\",\n \"Mutations only support 'network-only' or 'no-cache' fetch policies. The default 'network-only' behavior automatically writes mutation results to the cache. Passing 'no-cache' skips the cache write.\"\n );\n }\n\n checkDocument(optionsWithDefaults.mutation, OperationTypeNode.MUTATION);\n\n return this.queryManager.mutate<TData, TVariables, TCache>(\n optionsWithDefaults\n );\n }\n\n /**\n * This subscribes to a graphql subscription according to the options specified and returns an\n * `Observable` which either emits received data or an error.\n */\n public subscribe<\n TData = unknown,\n TVariables extends OperationVariables = OperationVariables,\n >(\n options: ApolloClient.SubscribeOptions<TData, TVariables>\n ): SubscriptionObservable<ApolloClient.SubscribeResult<MaybeMasked<TData>>> {\n const cause = {};\n\n const observable =\n this.queryManager.startGraphQLSubscription<TData>(options);\n\n const mapped = observable.pipe(\n map((result) => ({\n ...result,\n data: this.queryManager.maskOperation({\n document: options.query,\n data: result.data,\n fetchPolicy: options.fetchPolicy,\n cause,\n }),\n }))\n );\n\n return Object.assign(mapped, { restart: observable.restart });\n }\n\n /**\n * Tries to read some data from the store in the shape of the provided\n * GraphQL query without making a network request. This method will start at\n * the root query. To start at a specific id returned by `cache.identify`\n * use `readFragment`.\n *\n * @param optimistic - Set to `true` to allow `readQuery` to return\n * optimistic results. Is `false` by default.\n */\n public readQuery<\n TData = unknown,\n TVariables extends OperationVariables = OperationVariables,\n >(\n options: ApolloClient.ReadQueryOptions<TData, TVariables>\n ): Unmasked<TData> | null;\n\n /**\n * {@inheritDoc @apollo/client!ApolloClient#readQuery:member(1)}\n *\n * @deprecated Pass the `optimistic` argument as part of the first argument\n * instead of passing it as a separate option.\n */\n public readQuery<\n TData = unknown,\n TVariables extends OperationVariables = OperationVariables,\n >(\n options: ApolloClient.ReadQueryOptions<TData, TVariables>,\n /**\n * @deprecated Pass the `optimistic` argument as part of the first argument\n * instead of passing it as a separate option.\n */\n optimistic: boolean\n ): Unmasked<TData> | null;\n\n public readQuery<\n TData = unknown,\n TVariables extends OperationVariables = OperationVariables,\n >(\n options: ApolloClient.ReadQueryOptions<TData, TVariables>,\n optimistic: boolean = false\n ): Unmasked<TData> | null {\n return this.cache.readQuery<TData, TVariables>(\n { ...options, query: this.transform(options.query) },\n optimistic\n );\n }\n\n /**\n * Watches the cache store of the fragment according to the options specified\n * and returns an `Observable`. We can subscribe to this\n * `Observable` and receive updated results through an\n * observer when the cache store changes.\n *\n * You must pass in a GraphQL document with a single fragment or a document\n * with multiple fragments that represent what you are reading. If you pass\n * in a document with multiple fragments then you must also specify a\n * `fragmentName`.\n *\n * @since 3.10.0\n * @param options - An object of type `WatchFragmentOptions` that allows\n * the cache to identify the fragment and optionally specify whether to react\n * to optimistic updates.\n */\n\n public watchFragment<\n TData = unknown,\n TVariables extends OperationVariables = OperationVariables,\n >(\n options: ApolloClient.WatchFragmentOptions<TData, TVariables>\n ): Observable<ApolloClient.WatchFragmentResult<MaybeMasked<TData>>> {\n const dataMasking = this.queryManager.dataMasking;\n\n return this.cache\n .watchFragment({\n ...options,\n fragment: this.transform(options.fragment, dataMasking),\n })\n .pipe(\n map((result) => {\n // The transform will remove fragment spreads from the fragment\n // document when dataMasking is enabled. The `maskFragment` function\n // remains to apply warnings to fragments marked as\n // `@unmask(mode: \"migrate\")`. Since these warnings are only applied\n // in dev, we can skip the masking algorithm entirely for production.\n if (__DEV__) {\n if (dataMasking) {\n const data = this.queryManager.maskFragment({\n ...options,\n data: result.data,\n });\n return { ...result, data } as ApolloClient.WatchFragmentResult<\n MaybeMasked<TData>\n >;\n }\n }\n\n return result as ApolloClient.WatchFragmentResult<MaybeMasked<TData>>;\n })\n );\n }\n\n /**\n * Tries to read some data from the store in the shape of the provided\n * GraphQL fragment without making a network request. This method will read a\n * GraphQL fragment from any arbitrary id that is currently cached, unlike\n * `readQuery` which will only read from the root query.\n *\n * You must pass in a GraphQL document with a single fragment or a document\n * with multiple fragments that represent what you are reading. If you pass\n * in a document with multiple fragments then you must also specify a\n * `fragmentName`.\n *\n * @param optimistic - Set to `true` to allow `readFragment` to return\n * optimistic results. Is `false` by default.\n */\n public readFragment<\n TData = unknown,\n TVariables extends OperationVariables = OperationVariables,\n >(\n options: ApolloClient.ReadFragmentOptions<TData, TVariables>\n ): Unmasked<TData> | null;\n /**\n * {@inheritDoc @apollo/client!ApolloClient#readFragment:member(1)}\n *\n * @deprecated Pass the `optimistic` argument as part of the first argument\n * instead of passing it as a separate option.\n */\n public readFragment<\n TData = unknown,\n TVariables extends OperationVariables = OperationVariables,\n >(\n options: ApolloClient.ReadFragmentOptions<TData, TVariables>,\n optimistic: boolean\n ): Unmasked<TData> | null;\n\n public readFragment<\n TData = unknown,\n TVariables extends OperationVariables = OperationVariables,\n >(\n options: ApolloClient.ReadFragmentOptions<TData, TVariables>,\n optimistic: boolean = false\n ): Unmasked<TData> | null {\n return this.cache.readFragment<TData, TVariables>(\n { ...options, fragment: this.transform(options.fragment) },\n optimistic\n );\n }\n\n /**\n * Writes some data in the shape of the provided GraphQL query directly to\n * the store. This method will start at the root query. To start at a\n * specific id returned by `cache.identify` then use `writeFragment`.\n */\n public writeQuery<\n TData = unknown,\n TVariables extends OperationVariables = OperationVariables,\n >(\n options: ApolloClient.WriteQueryOptions<TData, TVariables>\n ): Reference | undefined {\n const ref = this.cache.writeQuery<TData, TVariables>(options);\n\n if (options.broadcast !== false) {\n this.queryManager.broadcastQueries();\n }\n\n return ref;\n }\n\n /**\n * Writes some data in the shape of the provided GraphQL fragment directly to\n * the store. This method will write to a GraphQL fragment from any arbitrary\n * id that is currently cached, unlike `writeQuery` which will only write\n * from the root query.\n *\n * You must pass in a GraphQL document with a single fragment or a document\n * with multiple fragments that represent what you are writing. If you pass\n * in a document with multiple fragments then you must also specify a\n * `fragmentName`.\n */\n public writeFragment<\n TData = unknown,\n TVariables extends OperationVariables = OperationVariables,\n >(\n options: ApolloClient.WriteFragmentOptions<TData, TVariables>\n ): Reference | undefined {\n const ref = this.cache.writeFragment<TData, TVariables>(options);\n\n if (options.broadcast !== false) {\n this.queryManager.broadcastQueries();\n }\n\n return ref;\n }\n\n public __actionHookForDevTools(cb: () => any) {\n this.devToolsHookCb = cb;\n }\n\n public __requestRaw(\n request: ApolloLink.Request\n ): Observable<ApolloLink.Result<unknown>> {\n return execute(this.link, request, { client: this });\n }\n\n /**\n * Resets your entire store by clearing out your cache and then re-executing\n * all of your active queries. This makes it so that you may guarantee that\n * there is no data left in your store from a time before you called this\n * method.\n *\n * `resetStore()` is useful when your user just logged out. You’ve removed the\n * user session, and you now want to make sure that any references to data you\n * might have fetched while the user session was active is gone.\n *\n * It is important to remember that `resetStore()` _will_ refetch any active\n * queries. This means that any components that might be mounted will execute\n * their queries again using your network interface. If you do not want to\n * re-execute any queries then you should make sure to stop watching any\n * active queries.\n */\n public resetStore(): Promise<ApolloClient.QueryResult<any>[] | null> {\n return Promise.resolve()\n .then(() =>\n this.queryManager.clearStore({\n discardWatches: false,\n })\n )\n .then(() => Promise.all(this.resetStoreCallbacks.map((fn) => fn())))\n .then(() => this.refetchObservableQueries());\n }\n\n /**\n * Remove all data from the store. Unlike `resetStore`, `clearStore` will\n * not refetch any active queries.\n */\n public clearStore(): Promise<any[]> {\n return Promise.resolve()\n .then(() =>\n this.queryManager.clearStore({\n discardWatches: true,\n })\n )\n .then(() => Promise.all(this.clearStoreCallbacks.map((fn) => fn())));\n }\n\n /**\n * Allows callbacks to be registered that are executed when the store is\n * reset. `onResetStore` returns an unsubscribe function that can be used\n * to remove registered callbacks.\n */\n public onResetStore(cb: () => Promise<any>): () => void {\n this.resetStoreCallbacks.push(cb);\n return () => {\n this.resetStoreCallbacks = this.resetStoreCallbacks.filter(\n (c) => c !== cb\n );\n };\n }\n\n /**\n * Allows callbacks to be registered that are executed when the store is\n * cleared. `onClearStore` returns an unsubscribe function that can be used\n * to remove registered callbacks.\n */\n public onClearStore(cb: () => Promise<any>): () => void {\n this.clearStoreCallbacks.push(cb);\n return () => {\n this.clearStoreCallbacks = this.clearStoreCallbacks.filter(\n (c) => c !== cb\n );\n };\n }\n\n /**\n * Refetches all of your active queries.\n *\n * `reFetchObservableQueries()` is useful if you want to bring the client back to proper state in case of a network outage\n *\n * It is important to remember that `reFetchObservableQueries()` _will_ refetch any active\n * queries. This means that any components that might be mounted will execute\n * their queries again using your network interface. If you do not want to\n * re-execute any queries then you should make sure to stop watching any\n * active queries.\n * Takes optional parameter `includeStandby` which will include queries in standby-mode when refetching.\n *\n * Note: `cache-only` queries are not refetched by this function.\n *\n * @deprecated Please use `refetchObservableQueries` instead.\n */\n public reFetchObservableQueries: (\n includeStandby?: boolean\n ) => Promise<ApolloClient.QueryResult<any>[]>;\n\n /**\n * Refetches all of your active queries.\n *\n * `refetchObservableQueries()` is useful if you want to bring the client back to proper state in case of a network outage\n *\n * It is important to remember that `refetchObservableQueries()` _will_ refetch any active\n * queries. This means that any components that might be mounted will execute\n * their queries again using your network interface. If you do not want to\n * re-execute any queries then you should make sure to stop watching any\n * active queries.\n * Tak