UNPKG

@urql/core

Version:

The shared core for the highly customizable and versatile GraphQL client

974 lines (970 loc) 69.2 kB
import * as GraphQLWeb from '@0no-co/graphql.web'; import { GraphQLError as GraphQLError$1, ValueNode, TypeNode, Kind, DirectiveNode } from '@0no-co/graphql.web'; /*@ts-ignore*/ import * as GraphQL from 'graphql'; import { Source, Subscription } from 'wonka'; type OrNever<T> = void extends T ? never : T; type GraphQLError = GraphQLWeb.GraphQLError | OrNever<GraphQL.GraphQLError>; type DocumentNode = GraphQLWeb.DocumentNode | OrNever<GraphQL.DocumentNode>; type DefinitionNode = GraphQLWeb.DefinitionNode | OrNever<GraphQL.DefinitionNode>; /** Configuration options passed when creating a new {@link Client}. * * @remarks * The `ClientOptions` are passed when creating a new {@link Client}, and * are used to instantiate the pipeline of {@link Exchange | Exchanges}, configure * options used to initialize {@link OperationContext | OperationContexts}, or to * change the general behaviour of the {@link Client}. */ interface ClientOptions { /** Target URL used by fetch exchanges to make GraphQL API requests to. * * @remarks * This is the URL that fetch exchanges will call to make GraphQL API requests. * This value is copied to {@link OperationContext.url}. */ url: string; /** Additional options used by fetch exchanges that'll be passed to the `fetch` call on API requests. * * @remarks * The options in this object or an object returned by a callback function will be merged into the * {@link RequestInit} options passed to the `fetch` call. * * Hint: If you're trying to implement more complex changes per {@link Operation}, it's worth considering * to use the {@link mapExchange} instead, which allows you to change `Operation`s and `OperationResult`s. * * Hint: If you're trying to use this as a function for authentication, consider checking out * `@urql/exchange-auth` instead, which allows you to handle refresh auth flows, and more * complex auth flows. * * @see {@link https://developer.mozilla.org/en-US/docs/Web/API/fetch} for a description of this object. */ fetchOptions?: RequestInit | (() => RequestInit); /** A `fetch` function polyfill used by fetch exchanges to make API calls. * * @remarks * This is the fetch polyfill used by any fetch exchange to make an API request. By default, when this * option isn't set, any fetch exchange will attempt to use the globally available `fetch` function * to make a request instead. * * It's recommended to only pass a polyfill, if any of the environments you're running the {@link Client} * in don't support the Fetch API natively. * * Hint: If you're using the "Incremental Delivery" multipart spec, for instance with `@defer` directives, * you're better off using the native `fetch` function, or must ensure that your polyfill supports streamed * results. However, a "Streaming requests unsupported" error will be thrown, to let you know that your `fetch` * API doesn't support incrementally streamed responses, if this mode is used. * * @see {@link https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API} for the Fetch API spec. */ fetch?: typeof fetch; /** Allows a subscription to be executed using a `fetch` API request. * * @remarks * If your API supports the `text/event-stream` and/or `multipart/mixed` response protocol, and you use * this protocol to handle subscriptions, then you may switch this flag to `true`. * * This means you won’t have to create a {@link subscriptionExchange} to handle subscriptions with an * external transport, and will instead be able to use GraphQL over HTTP transports. */ fetchSubscriptions?: boolean; /** A list of `Exchange`s that will be used to create the `Client`'s execution pipeline. * * @remarks * The {@link Client} accepts and composes a list of {@link Exchange | Exchanges} into an “exchange pipeline” * which receive a stream of {@link Operation | Operations} the `Client` wishes to execute, and return a stream * of {@link OperationResult | OperationResults}. * * This is the basis for how `urql` handles GraphQL operations, and exchanges handle the creation, execution, * and control flow of exchanges for the `Client`. * * To easily get started you should consider using the {@link cacheExchange} and {@link fetchExchange} * these are all exported from the core package. * * @see {@link https://urql.dev/goto/docs/architecture/#the-client-and-exchanges} for more information * on what `Exchange`s are and how they work. */ exchanges: Exchange[]; /** A configuration flag indicating whether support for "Suspense" is activated. * * @remarks * This configuration flag is only relevant for using `urql` with the React or Preact bindings. * When activated it allows `useQuery` to "suspend" instead of returning a loading state, which * will stop updates in a querying component and instead cascade * to a higher suspense boundary for a loading state. * * Hint: While, when this option is enabled, by default all `useQuery` hooks will suspense, you can * disable Suspense selectively for each hook. * * @see {@link https://beta.reactjs.org/blog/2022/03/29/react-v18#new-suspense-features} for more information on React Suspense. */ suspense?: boolean; /** The request and caching strategy that all `Operation`s on this `Client` will use by default. * * @remarks * The {@link RequestPolicy} instructs cache exchanges how to use and treat their cached results. * By default `cache-first` is set and used, which will use cache results, and only make an API request * on a cache miss. * * The `requestPolicy` can be overriden per operation, since it's added to the {@link OperationContext}, * which allows you to change the policy per `Operation`, rather than changing it by default here. * * Hint: We don’t recommend changing this from the default `cache-first` option, unless you know what * you‘re doing. Setting this to `cache-and-network` is not recommend and may not lead to the behaviour * you expect. If you’re looking to always update your cache frequently, use `@urql/exchange-request-policy` * instead. */ requestPolicy?: RequestPolicy; /** Instructs fetch exchanges to use a GET request. * * @remarks * This changes the {@link OperationContext.preferGetMethod} option, which tells fetch exchanges * to use GET requests for queries instead of POST requests. * * When set to `true` or `'within-url-limit'`, built-in fetch exchanges will always attempt to send query * operations as GET requests, unless the resulting URL exceeds a length of 2,048 characters. * If you want to bypass this restriction, set this option to `'force'` instead, to always send GET. * requests for queries. */ preferGetMethod?: boolean | 'force' | 'within-url-limit'; } /** The `Client` is the central hub for your GraphQL operations and holds `urql`'s state. * * @remarks * The `Client` manages your active GraphQL operations and their state, and contains the * {@link Exchange} pipeline to execute your GraphQL operations. * * It contains methods that allow you to execute GraphQL operations manually, but the `Client` * is also interacted with by bindings (for React, Preact, Vue, Svelte, etc) to execute GraphQL * operations. * * While {@link Exchange | Exchanges} are ultimately responsible for the control flow of operations, * sending API requests, and caching, the `Client` still has the important responsibility for * creating operations, managing consumers of active operations, sharing results for operations, * and more tasks as a “central hub”. * * @see {@link https://urql.dev/goto/docs/architecture/#requests-and-operations-on-the-client} for more information * on what the `Client` is and does. */ interface Client { new (options: ClientOptions): Client; /** Exposes the stream of `Operation`s that is passed to the `Exchange` pipeline. * * @remarks * This is a Wonka {@link Source} that issues the {@link Operation | Operations} going into * the exchange pipeline. * @internal */ operations$: Source<Operation>; /** Flag indicating whether support for “Suspense” is activated. * * @remarks * This flag indicates whether support for “Suspense” has been activated via the * {@link ClientOptions.suspense} flag. * * When this is enabled, the {@link Client} itself doesn’t function any differently, and the flag * only serves as an instructions for the React/Preact bindings to change their behaviour. * * @see {@link ClientOptions.suspense} for more information. * @internal */ suspense: boolean; /** Dispatches an `Operation` to the `Exchange` pipeline, if this `Operation` is active. * * @remarks * This method is frequently used in {@link Exchange | Exchanges}, for instance caches, to reexecute * an operation. It’s often either called because an `Operation` will need to be queried against the * cache again, if a cache result has changed or been invalidated, or it’s called with an {@link Operation}'s * {@link RequestPolicy} set to `network-only` to issue a network request. * * This method will only dispatch an {@link Operation} if it has active consumers, meaning, * active subscribers to the sources of {@link OperationResult}. For instance, if no bindings * (e.g. `useQuery`) is subscribed to the `Operation`, then `reexecuteOperation` will do nothing. * * All operations are put onto a queue and executed after a micro-tick. The queue of operations is * emptied eagerly and synchronously, similar to a trampoline scheduler. */ reexecuteOperation(operation: Operation): void; /** Subscribe method to add an event listener to debug events. * * @param onEvent - A callback called with new debug events, each time an `Exchange` issues them. * @returns A Wonka {@link Subscription} which is used to optionally terminate the event listener. * * @remarks * This is a method that's only available in development, and allows the `urql-devtools` to receive * to debug events that are issued by exchanges, giving the devtools more information about the flow * and execution of {@link Operation | Operations}. * * @see {@link DebugEventTypes} for a description of all debug events. * @internal */ subscribeToDebugTarget?(onEvent: (event: DebugEvent) => void): Subscription; /** Creates an `Operation` from a `GraphQLRequest` and optionally, overriding `OperationContext` options. * * @param kind - The {@link OperationType} of GraphQL operation, i.e. `query`, `mutation`, or `subscription`. * @param request - A {@link GraphQLRequest} created prior to calling this method. * @param opts - {@link OperationContext} options that'll override and be merged with options from the {@link ClientOptions}. * @returns An {@link Operation} created from the parameters. * * @remarks * This method is expected to be called with a `kind` set to the `OperationType` of the GraphQL operation. * In development, this is enforced by checking that the GraphQL document's operation matches this `kind`. * * Hint: While bindings will use this method combined with {@link Client.executeRequestOperation}, if * you’re executing operations manually, you can use one of the other convenience methods instead. * * @see {@link Client.executeRequestOperation} for the method used to execute operations. * @see {@link createRequest} which creates a `GraphQLRequest` from a `DocumentNode` and variables. */ createRequestOperation<Data = any, Variables extends AnyVariables = AnyVariables>(kind: OperationType, request: GraphQLRequest<Data, Variables>, opts?: Partial<OperationContext> | undefined): Operation<Data, Variables>; /** Creates a `Source` that executes the `Operation` and issues `OperationResult`s for this `Operation`. * * @param operation - {@link Operation} that will be executed. * @returns A Wonka {@link Source} of {@link OperationResult | OperationResults} for the passed `Operation`. * * @remarks * The {@link Operation} will be dispatched to the pipeline of {@link Exchange | Exchanges} when * subscribing to the returned {@link Source}, which issues {@link OperationResult | OperationResults} * belonging to this `Operation`. * * Internally, {@link OperationResult | OperationResults} are filtered and deliverd to this source by * comparing the {@link Operation.key} on the operation and the {@link OperationResult.operation}. * For mutations, the {@link OperationContext._instance | `OperationContext._instance`} will additionally be compared, since two mutations * with, even given the same variables, will have two distinct results and will be executed separately. * * The {@link Client} dispatches the {@link Operation} when we subscribe to the returned {@link Source} * and will from then on consider the `Operation` as “active” until we unsubscribe. When all consumers unsubscribe * from an `Operation` and it becomes “inactive” a `teardown` signal will be dispatched to the * {@link Exchange | Exchanges}. * * Hint: While bindings will use this method, if you’re executing operations manually, you can use one * of the other convenience methods instead, like {@link Client.executeQuery} et al. */ executeRequestOperation<Data = any, Variables extends AnyVariables = AnyVariables>(operation: Operation<Data, Variables>): OperationResultSource<OperationResult<Data, Variables>>; /** Creates a `Source` that executes the GraphQL query operation created from the passed parameters. * * @param query - a GraphQL document containing the query operation that will be executed. * @param variables - the variables used to execute the operation. * @param opts - {@link OperationContext} options that'll override and be merged with options from the {@link ClientOptions}. * @returns A {@link OperationResultSource} issuing the {@link OperationResult | OperationResults} for the GraphQL operation. * * @remarks * The `Client.query` method is useful to programmatically create and issue a GraphQL query operation. * It automatically calls {@link createRequest}, {@link client.createRequestOperation}, and * {@link client.executeRequestOperation} for you, and is a convenience method. * * Since it returns a {@link OperationResultSource} it may be chained with a `toPromise()` call to only * await a single result in an async function. * * Hint: This is the recommended way to create queries programmatically when not using the bindings, * or when you’re trying to get a single, promisified result. * * @example * ```ts * const getBookQuery = gql` * query GetBook($id: ID!) { * book(id: $id) { * id * name * author { * name * } * } * } * `; * * async function getBook(id) { * const result = await client.query(getBookQuery, { id }).toPromise(); * if (result.error) { * throw result.error; * } * * return result.data.book; * } * ``` */ query<Data = any, Variables extends AnyVariables = AnyVariables>(query: DocumentInput<Data, Variables>, variables: Variables, context?: Partial<OperationContext>): OperationResultSource<OperationResult<Data, Variables>>; /** Returns the first synchronous result a `Client` provides for a given operation. * * @param query - a GraphQL document containing the query operation that will be executed. * @param variables - the variables used to execute the operation. * @param opts - {@link OperationContext} options that'll override and be merged with options from the {@link ClientOptions}. * @returns An {@link OperationResult} if one became available synchronously or `null`. * * @remarks * The `Client.readQuery` method returns a result synchronously or defaults to `null`. This is useful * as it limits the result for a query operation to whatever the cache {@link Exchange} of a {@link Client} * had stored and available at that moment. * * In `urql`, it's expected that cache exchanges return their results synchronously. The bindings * and this method exploit this by using synchronous results, like these, to check what data is already * in the cache. * * This method is similar to what all bindings do to synchronously provide the initial state for queries, * regardless of whether effects afterwards that subscribe to the query operation update this state synchronously * or asynchronously. */ readQuery<Data = any, Variables extends AnyVariables = AnyVariables>(query: DocumentInput<Data, Variables>, variables: Variables, context?: Partial<OperationContext>): OperationResult<Data, Variables> | null; /** Creates a `Source` that executes the GraphQL query operation for the passed `GraphQLRequest`. * * @param query - a {@link GraphQLRequest} * @param opts - {@link OperationContext} options that'll override and be merged with options from the {@link ClientOptions}. * @returns A {@link PromisifiedSource} issuing the {@link OperationResult | OperationResults} for the GraphQL operation. * * @remarks * The `Client.executeQuery` method is used to programmatically issue a GraphQL query operation. * It automatically calls {@link client.createRequestOperation} and {@link client.executeRequestOperation} for you, * but requires you to create a {@link GraphQLRequest} using {@link createRequest} yourself first. * * @see {@link Client.query} for a method that doesn't require calling {@link createRequest} yourself. */ executeQuery<Data = any, Variables extends AnyVariables = AnyVariables>(query: GraphQLRequest<Data, Variables>, opts?: Partial<OperationContext> | undefined): OperationResultSource<OperationResult<Data, Variables>>; /** Creates a `Source` that executes the GraphQL subscription operation created from the passed parameters. * * @param query - a GraphQL document containing the subscription operation that will be executed. * @param variables - the variables used to execute the operation. * @param opts - {@link OperationContext} options that'll override and be merged with options from the {@link ClientOptions}. * @returns A Wonka {@link Source} issuing the {@link OperationResult | OperationResults} for the GraphQL operation. * * @remarks * The `Client.subscription` method is useful to programmatically create and issue a GraphQL subscription operation. * It automatically calls {@link createRequest}, {@link client.createRequestOperation}, and * {@link client.executeRequestOperation} for you, and is a convenience method. * * Hint: This is the recommended way to create subscriptions programmatically when not using the bindings. * * @example * ```ts * import { pipe, subscribe } from 'wonka'; * * const getNewsSubscription = gql` * subscription GetNews { * breakingNews { * id * text * createdAt * } * } * `; * * function subscribeToBreakingNews() { * const subscription = pipe( * client.subscription(getNewsSubscription, {}), * subscribe(result => { * if (result.data) { * console.log(result.data.breakingNews.text); * } * }) * ); * * return subscription.unsubscribe; * } * ``` */ subscription<Data = any, Variables extends AnyVariables = AnyVariables>(query: DocumentInput<Data, Variables>, variables: Variables, context?: Partial<OperationContext>): OperationResultSource<OperationResult<Data, Variables>>; /** Creates a `Source` that executes the GraphQL subscription operation for the passed `GraphQLRequest`. * * @param query - a {@link GraphQLRequest} * @param opts - {@link OperationContext} options that'll override and be merged with options from the {@link ClientOptions}. * @returns A {@link PromisifiedSource} issuing the {@link OperationResult | OperationResults} for the GraphQL operation. * * @remarks * The `Client.executeSubscription` method is used to programmatically issue a GraphQL subscription operation. * It automatically calls {@link client.createRequestOperation} and {@link client.executeRequestOperation} for you, * but requires you to create a {@link GraphQLRequest} using {@link createRequest} yourself first. * * @see {@link Client.subscription} for a method that doesn't require calling {@link createRequest} yourself. */ executeSubscription<Data = any, Variables extends AnyVariables = AnyVariables>(query: GraphQLRequest<Data, Variables>, opts?: Partial<OperationContext> | undefined): OperationResultSource<OperationResult<Data, Variables>>; /** Creates a `Source` that executes the GraphQL mutation operation created from the passed parameters. * * @param query - a GraphQL document containing the mutation operation that will be executed. * @param variables - the variables used to execute the operation. * @param opts - {@link OperationContext} options that'll override and be merged with options from the {@link ClientOptions}. * @returns A {@link PromisifiedSource} issuing the {@link OperationResult | OperationResults} for the GraphQL operation. * * @remarks * The `Client.mutation` method is useful to programmatically create and issue a GraphQL mutation operation. * It automatically calls {@link createRequest}, {@link client.createRequestOperation}, and * {@link client.executeRequestOperation} for you, and is a convenience method. * * Since it returns a {@link PromisifiedSource} it may be chained with a `toPromise()` call to only * await a single result in an async function. Since mutations will only typically issue one result, * using this method is recommended. * * Hint: This is the recommended way to create mutations programmatically when not using the bindings, * or when you’re trying to get a single, promisified result. * * @example * ```ts * const createPostMutation = gql` * mutation CreatePost($text: String!) { * createPost(text: $text) { * id * text * } * } * `; * * async function createPost(text) { * const result = await client.mutation(createPostMutation, { * text, * }).toPromise(); * if (result.error) { * throw result.error; * } * * return result.data.createPost; * } * ``` */ mutation<Data = any, Variables extends AnyVariables = AnyVariables>(query: DocumentInput<Data, Variables>, variables: Variables, context?: Partial<OperationContext>): OperationResultSource<OperationResult<Data, Variables>>; /** Creates a `Source` that executes the GraphQL mutation operation for the passed `GraphQLRequest`. * * @param query - a {@link GraphQLRequest} * @param opts - {@link OperationContext} options that'll override and be merged with options from the {@link ClientOptions}. * @returns A {@link PromisifiedSource} issuing the {@link OperationResult | OperationResults} for the GraphQL operation. * * @remarks * The `Client.executeMutation` method is used to programmatically issue a GraphQL mutation operation. * It automatically calls {@link client.createRequestOperation} and {@link client.executeRequestOperation} for you, * but requires you to create a {@link GraphQLRequest} using {@link createRequest} yourself first. * * @see {@link Client.mutation} for a method that doesn't require calling {@link createRequest} yourself. */ executeMutation<Data = any, Variables extends AnyVariables = AnyVariables>(query: GraphQLRequest<Data, Variables>, opts?: Partial<OperationContext> | undefined): OperationResultSource<OperationResult<Data, Variables>>; } declare const Client: new (opts: ClientOptions) => Client; /** Accepts `ClientOptions` and creates a `Client`. * @param opts - A {@link ClientOptions} objects with options for the `Client`. * @returns A {@link Client} instantiated with `opts`. */ declare const createClient: (opts: ClientOptions) => Client; /** An abstracted `Error` that provides either a `networkError` or `graphQLErrors`. * * @remarks * During a GraphQL request, either the request can fail entirely, causing a network error, * or the GraphQL execution or fields can fail, which will cause an {@link ExecutionResult} * to contain an array of GraphQL errors. * * The `CombinedError` abstracts and normalizes both failure cases. When {@link OperationResult.error} * is set to this error, the `CombinedError` abstracts all errors, making it easier to handle only * a subset of error cases. * * @see {@link https://urql.dev/goto/docs/basics/errors} for more information on handling * GraphQL errors and the `CombinedError`. */ declare class CombinedError extends Error { name: string; message: string; /** A list of GraphQL errors rehydrated from a {@link ExecutionResult}. * * @remarks * If an {@link ExecutionResult} received from the API contains a list of errors, * the `CombinedError` will rehydrate them, normalize them to * {@link GraphQLError | GraphQLErrors} and list them here. * An empty list indicates that no GraphQL error has been sent by the API. */ graphQLErrors: GraphQLError$1[]; /** Set to an error, if a GraphQL request has failed outright. * * @remarks * A GraphQL over HTTP request may fail and not reach the API. Any error that * prevents a GraphQl request outright, will be considered a “network error” and * set here. */ networkError?: Error; /** Set to the {@link Response} object a fetch exchange received. * * @remarks * If a built-in fetch {@link Exchange} is used in `urql`, this may * be set to the {@link Response} object of the Fetch API response. * However, since `urql` doesn’t assume that all users will use HTTP * as the only or exclusive transport for GraphQL this property is * neither typed nor guaranteed and may be re-used for other purposes * by non-fetch exchanges. * * Hint: It can be useful to use `response.status` here, however, if * you plan on relying on this being a {@link Response} in your app, * which it is by default, then make sure you add some extra checks * before blindly assuming so! */ response?: any; constructor(input: { networkError?: Error; graphQLErrors?: Array<string | ErrorLike>; response?: any; }); toString(): string; } /** A GraphQL persisted document will contain `documentId` that replaces its definitions */ interface PersistedDocument extends DocumentNode { documentId?: string; } /** A GraphQL `DocumentNode` with attached generics for its result data and variables. * * @remarks * A GraphQL {@link DocumentNode} defines both the variables it accepts on request and the `data` * shape it delivers on a response in the GraphQL query language. * * To bridge the gap to TypeScript, tools may be used to generate TypeScript types that define the shape * of `data` and `variables` ahead of time. These types are then attached to GraphQL documents using this * `TypedDocumentNode` type. * * Using a `DocumentNode` that is typed like this will cause any `urql` API to type its input `variables` * and resulting `data` using the types provided. * * @privateRemarks * For compatibility reasons this type has been copied and internalized from: * https://github.com/dotansimha/graphql-typed-document-node/blob/3711b12/packages/core/src/index.ts#L3-L10 * * @see {@link https://github.com/dotansimha/graphql-typed-document-node} for more information. */ type TypedDocumentNode<Result = { [key: string]: any; }, Variables = { [key: string]: any; }> = DocumentNode & { /** Type to support `@graphql-typed-document-node/core` * @internal */ __apiType?: (variables: Variables) => Result; /** Type to support `TypedQueryDocumentNode` from `graphql` * @internal */ __ensureTypesOfVariablesAndResultMatching?: (variables: Variables) => Result; }; /** GraphQL nodes with added `_directives` dictionary on nodes with directives. * * @remarks * The {@link formatDocument} utility processes documents to add `__typename` * fields to them. It additionally provides additional directives processing * and outputs this type. * * When applied, every node with non-const directives, will have an additional * `_directives` dictionary added to it, and filter directives starting with * a leading `_` underscore from the directives array. */ type FormattedNode<Node> = Node extends readonly (infer Child)[] ? readonly FormattedNode<Child>[] : Node extends ValueNode | TypeNode ? Node : Node extends { kind: Kind; } ? { [K in Exclude<keyof Node, 'directives' | 'loc'>]: FormattedNode<Node[K]>; } extends infer Node ? Node extends { kind: Kind.FIELD | Kind.INLINE_FRAGMENT | Kind.FRAGMENT_SPREAD; } ? Node & { _generated?: boolean; _directives?: Record<string, DirectiveNode> | undefined; } : Node : Node : Node; /** Any GraphQL `DocumentNode` or query string input. * * @remarks * Wherever any `urql` bindings or API expect a query, it accepts either a query string, * a `DocumentNode`, or a {@link TypedDocumentNode}. */ type DocumentInput<Result = { [key: string]: any; }, Variables = { [key: string]: any; }> = string | DocumentNode | TypedDocumentNode<Result, Variables>; /** A list of errors on {@link ExecutionResult | ExecutionResults}. * @see {@link https://spec.graphql.org/draft/#sec-Errors.Error-Result-Format} for the GraphQL Error Result format spec. */ type ErrorLike = Partial<GraphQLError> | Error; /** Extensions which may be placed on {@link ExecutionResult | ExecutionResults}. * @see {@link https://spec.graphql.org/draft/#sel-EAPHJCAACCoGu9J} for the GraphQL Error Result format spec. */ type Extensions = Record<string, any>; /** Extensions sub-property on `persistedQuery` for Automatic Persisted Queries. * * @remarks * This is part of the Automatic Persisted Query defacto standard and allows an API * request to omit the `query`, instead sending this `sha256Hash`. */ interface PersistedRequestExtensions { version?: 1; sha256Hash: string; /** Set when a `sha256Hash` previously experienced a miss which will force `query` to be sent. */ miss?: boolean; } /** Extensions which may be palced on {@link GraphQLRequest | GraphQLRequests}. * @see {@link https://github.com/graphql/graphql-over-http/blob/1928447/spec/GraphQLOverHTTP.md#request-parameters} for the GraphQL over HTTP spec */ interface RequestExtensions { persistedQuery?: PersistedRequestExtensions; [extension: string]: any; } type Path = readonly (string | number)[]; /** Incremental Payloads sent as part of "Incremental Delivery" patching prior result data. * * @remarks * "Incremental Delivery" works by allowing APIs to stream patches to the client, whih update * prior results at the specified `path`. * * @see {@link https://github.com/graphql/graphql-spec/blob/94363c9/spec/Section%207%20--%20Response.md#incremental} for the incremental payload spec */ interface IncrementalPayload { /** Optional label for the incremental payload that corresponds to directives' labels. * * @remarks * All incremental payloads are labelled by the label that `@stream` or `@defer` directives * specified, to identify which directive they originally belonged to. */ label?: string | null; /** JSON patch at which to apply the `data` patch or append the `items`. * * @remarks * The `path` indicates the JSON path of a prior result’s `data` structure at which * to insert the patch’s data. * When `items` is set instead, which represents a list of items to insert, the last * entry of the `path` will be an index number at which to start setting the range of * items. */ path?: Path; /** An id pointing at an entry in the "pending" set of deferred results * * @remarks * When we resolve this id it will give us the path to the deferred Fragment, this * can be afterwards combined with the subPath to get the eventual location of the data. */ id?: string; /** A path array from the defer/stream fragment to the location of our data. */ subPath?: Path; /** Data to patch into the result data at the given `path`. * * @remarks * This `data`, when set, is merged into the object at the given `path` of the last * result that has been delivered. * This isn't set when `items` is set. */ data?: Record<string, unknown> | null; /** List of items to patch into the result data at the given `path`. * * @remarks * The `items`, when provided, is set onto a range in an array, at the given JSON * `path`. The start index is the last entry of the `path` and the end index is * the length of the `items` list added to this index. * This isn't set when `data` is set. */ items?: readonly unknown[] | null; /** Contains a list of errors raised by incremental payloads. * * @remarks * The list of `errors` on `incremental` payloads is merged into the list of prior * results’ errors. * * @see {@link https://spec.graphql.org/October2021/#sec-Errors} for the GraphQL Errors Response spec */ errors?: ErrorLike[] | readonly ErrorLike[]; /** Additional metadata that a GraphQL API may choose to send that is out of spec. * @see {@link https://spec.graphql.org/October2021/#sel-EAPHJCAACCoGu9J} for the GraphQL Response spec */ extensions?: Extensions; } type PendingIncrementalResult = { path: Path; id: string; label?: string; }; interface ExecutionResult { /** Payloads we are still waiting for from the server. * * @remarks * This was nely introduced in the defer/stream spec iteration of June 2023 https://github.com/graphql/defer-stream-wg/discussions/69 * Pending can be present on both Incremental as well as normal execution results, the presence of pending on an incremental * result points at a nested deferred/streamed fragment. */ pending?: readonly PendingIncrementalResult[]; /** Incremental patches to be applied to a previous result as part of "Incremental Delivery". * * @remarks * When this is set `data` and `errors` is typically not set on the result. Instead, the incremental payloads * are applied as patches to a prior result's `data`. * * @see {@link https://github.com/graphql/graphql-spec/blob/94363c9/spec/Section%207%20--%20Response.md#incremental} for the incremental payload spec */ incremental?: IncrementalPayload[]; /** The result of the execution of the GraphQL operation. * @see {@link https://spec.graphql.org/October2021/#sec-Data} for the GraphQL Data Response spec */ data?: null | Record<string, any>; /** Contains a list of errors raised by fields or the request itself. * @see {@link https://spec.graphql.org/October2021/#sec-Errors} for the GraphQL Errors Response spec */ errors?: ErrorLike[] | readonly ErrorLike[]; /** Additional metadata that a GraphQL API may choose to send that is out of spec. * @see {@link https://spec.graphql.org/October2021/#sel-EAPHJCAACCoGu9J} for the GraphQL Response spec */ extensions?: Extensions; /** Flag indicating whether a future, incremental response may update this response. * @see {@link https://github.com/graphql/graphql-wg/blob/main/rfcs/DeferStream.md#payload-format} for the DeferStream spec */ hasNext?: boolean; payload?: Omit<ExecutionResult, 'payload'>; } /** A source of {@link OperationResult | OperationResults}, convertable to a promise, subscribable, or Wonka Source. * * @remarks * The {@link Client} will often return a `OperationResultSource` to provide a more flexible Wonka {@link Source}. * * While a {@link Source} may require you to import helpers to convert it to a `Promise` for a single result, or * to subscribe to it, the `OperationResultSource` is a `PromiseLike` and has methods to convert it to a promise, * or to subscribe to it with a single method call. */ type OperationResultSource<T extends OperationResult> = Source<T> & PromiseLike<T> & { /** Returns the first non-stale, settled results of the source. * @remarks * The `toPromise` method gives you the first result of an `OperationResultSource` * that has `hasNext: false` and `stale: false` set as a `Promise`. * * Hint: If you're trying to get updates for your results, this won't work. * This gives you only a single, promisified result, so it won't receive * cache or other updates. */ toPromise(): Promise<T>; /** Alias for Wonka's `subscribe` and calls `onResult` when subscribed to for each new `OperationResult`. */ subscribe(onResult: (value: T) => void): Subscription; }; /** A type of Operation, either a GraphQL `query`, `mutation`, or `subscription`; or a `teardown` signal. * * @remarks * Internally, {@link Operation | Operations} instruct the {@link Client} to perform a certain action on its exchanges. * Any of the three GraphQL operations tell it to execute these operations, and the `teardown` signal instructs it that * the operations are cancelled and/or have ended. * * The `teardown` signal is sent when nothing is subscribed to an operation anymore and no longer interested in its results * or any updates. */ type OperationType = 'subscription' | 'query' | 'mutation' | 'teardown'; /** The request and caching strategy that is used by exchanges to retrive cached results. * * @remarks * The `RequestPolicy` is used by cache exchanges to decide how a query operation may be resolved with cached results.h * A cache exchange may behave differently depending on which policy is returned. * * - `cache-first` (the default) prefers cached results and falls back to sending an API request. * - `cache-and-network` returns cached results but also always sends an API request in the background. * - `network-only` will ignore any cached results and send an API request. * - `cache-only` will always return cached results and prevent API requests. */ type RequestPolicy = 'cache-first' | 'cache-and-network' | 'network-only' | 'cache-only'; /** A metadata flag set by cache exchanges to indicate whether a cache miss, a cache hit, or a partial cache hit has occurred. * * @remarks * A cache exchange may update {@link OperationDebugMeta.cacheOutcome} on {@link OperationContext.meta} to indicate whether * an operation has been resolved from the cache. * * A cache hit is considered a result that has fully come from a cache. A partial result is a result that has come from a cache * but is incomplete, which may trigger another API request. A cache miss means a result must be requested from the API as no * cache result has been delivered. */ type CacheOutcome = 'miss' | 'partial' | 'hit'; /** A default type for variables. * * @remarks * While {@link TypedDocumentNode} can be used by generators to add TypeScript types for a GraphQL operation’s * variables and result, when this isn’t the case this type is used as a fallback for the `Variables` generic. */ type AnyVariables = { [prop: string]: any; } | void | undefined; /** A GraphQL request representing a single execution in GraphQL. * * @remarks * A `GraphQLRequest` is a single executable request that may be used by a cache or a GraphQL API to deliver a result. * A request contains a `DocumentNode` for the query document of a GraphQL operation and the `variables` for the given * request. * * A unique `key` is generated to identify the request internally by `urql`. Two requests with the same query and * variables will share the same `key`. * * The `Data` and `Variables` generics may be provided by a {@link TypedDocumentNode}, adding TypeScript types for what * the result shape and variables shape are. * * @see {@link https://spec.graphql.org/October2021/#sec-Executing-Requests} for more information on GraphQL reuqests. */ interface GraphQLRequest<Data = any, Variables extends AnyVariables = AnyVariables> { /** Unique identifier for the `GraphQLRequest`. * * @remarks * This is a key that combines the unique key of the `query` and the `variables` into a unique * `key` for the `GraphQLRequest`. Any request with the same query and variables will have a unique * `key` by which results and requests can be identified as identical. * * Internally, a stable, cached `key` is generated for the `DocumentNode` and for the `variables` and * both will be combined into a combined `key` which is set here, based on a DJB2 hash, * * The `variables` will change the key even if they contain a non-JSON reference. If you pass a custom * class instance to `variables` that doesn't contain a `toString` or `toJSON` method, a stable but random * identifier will replace this class to generate a key. */ key: number; /** A GraphQL document to execute against a cache or API. * * @remarks * A `GraphQLRequest` is executed against an operation in a GraphQL document. * In `urql`, we expect a document to only contain a single operation that is executed rather than * multiple ones by convention. */ query: DocumentNode | PersistedDocument | TypedDocumentNode<Data, Variables>; /** Variables used to execute the `query` document. * * @remarks * The `variables`, based either on the {@link AnyVariables} type or the {@link TypedDocumentNode}'s provided * generic, are sent to the GraphQL API to execute a request. */ variables: Variables; /** Additional metadata that a GraphQL API may accept for spec extensions. * @see {@link https://github.com/graphql/graphql-over-http/blob/1928447/spec/GraphQLOverHTTP.md#request-parameters} for the GraphQL over HTTP spec */ extensions?: RequestExtensions | undefined; } /** Parameters from which {@link GraphQLRequest | GraphQLRequests} are created from. * * @remarks * A `GraphQLRequest` is a single executable request with a generated `key` to identify * their results, whereas `GraphQLRequestParams` is a utility type used to generate * inputs for `urql` to create requests from, i.e. it only contains a `query` and * `variables`. The type conditionally makes the `variables` property completely * optional. * * @privateRemarks * The wrapping union type is needed for passthrough or wrapper utilities that wrap * functions like `useQuery` with generics. */ type GraphQLRequestParams<Data = any, Variables extends AnyVariables = AnyVariables> = ({ query: DocumentInput<Data, Variables>; } & (Variables extends void ? { variables?: Variables; } : Variables extends { [P in keyof Variables]: Exclude<Variables[P], null | void>; } ? Variables extends { [P in keyof Variables]: never; } ? { variables?: Variables; } : { variables: Variables; } : { variables?: Variables; })) | { query: DocumentInput<Data, Variables>; variables: Variables; }; /** Metadata used to annotate an `Operation` in development for the `urql-devtools`. * * @remarks * The `OperationDebugMeta` is found on {@link OperationContext.meta} only in development, * and is used to send additional metadata to the `urql-devtools` about the {@link Operation}. * * In production, most of this metadata will be missing, and it must not be used outside * of development, and should only be used by the `urql-devtools`. */ interface OperationDebugMeta { /** A label for the source of the `Operation`. * * @remarks * The `source` string indicates a human readable originator for the `Operation`. * This may be set to a component name or function name to indicate what originally * triggered the `Operation`. */ source?: string; /** A type of caching outcome set by cache exchanges on `OperationResult`s. * * @remarks * The `cacheOutcome` flag is set to a {@link CacheOutcome} on {@link Operation | Operations} * after they passed through the cache exchange. This flag indicates whether a cache hit, miss, * or partial cache hit has occurred. */ cacheOutcome?: CacheOutcome; /** Reserved to indicate the time it took for a GraphQL request to receive a response from a GraphQL API. * * @remarks * The `networkLatency` may be set to the time it took (in ms) for a GraphQL API to respond to a request * and deliver a result. * @internal */ networkLatency?: number; /** Reserved to indicate the timestamp at which a GraphQL request was sent to a GraphQL API. * * @remarks * The `startTime` is set to an epoch timestamp (in ms) at which a GraphQL request was started * and sent to a GraphQL API. * @internal */ startTime?: number; } /** A unique identity for GraphQL mutations. * * @remarks * GraphQL mutations not only use {@link GraphQLRequest.key} to identify a result, but instead use * an identity to mark which result belongs to them. * * While two GraphQL queries and subscriptions sharing the same variables and the same operation * (i.e. `DocumentNode`) are considered identical, two mutations are not. * Two GraphQL queries or subscription results with the same {@link GraphQLRequest.key} can be used * to resolve any {@link GraphQLRequest} with this same `key`. * This is because identical queries and subscriptions are idempotent. * * However, two mutations with the same variables may receive different results from a GraphQL API, * since they may trigger side-effects. * This means that `urql` needs an additional identifier to differentiate between two mutations with * the same `DocumentNode`s and `variables`. */ type OperationInstance = number & { /** Marker to indicate that an `OperationInstance` may not be created by a user. * * @remarks * The {@link Client} creates `OperationInstance` indentities automatically and uses them internally * to identify mutations results as belonging to mutation operations. These are just integers (numbers), * however, they're used as if they are objects (e.g. `{}`). However, since instances of arrays and * objects are not serialisable numbers are used instead. * * Because these are internal, the TypeScript type is marked using a `unique symbol` because they're * created opaquely and privately. * * @internal */ readonly _opaque: unique symbol; }; /** Additional metadata for an `Operation` used to execute it. * * @remarks * The `OperationContext` is found on {@link Operation.context} and gives exchanges additional metadata * and options used to execute the operation. * * The context can often be changed on a per-operation basis, meaning, APIs on the {@link Client} or * bindings can pass a partial context that alters these options for a single operation. * * The `OperationContext` is populated mostly from the initial options passed to the `Client` at its * time of creation, but may also be modified by exchanges when an {@link Operation} is passed through * to the next exchange or when a result is returned. */ interface OperationContext { /** A unique identity for GraphQL mutations. * * @remarks * This is an internal property set by the `Client` to an identity of type {@link OperationInstance}. * An `OperationInstance` is an identifier that's used to tell two mutation operations with identical * `query` documents and `variables` apart from one another. * @internal */ readonly _instance?: OperationInstance | undefined; /** Additional cache tags for `@urql/core`'s document `cacheExchange`. * * @remarks * The built-in {@link cacheExchange} in `@urql/core` is a document cache that uses `__typename`s in * mutation results to invalidate past, cached queries. * The `additionalTypenames` array may be set to the list of custom typenames whenever a result may * not deliver `__typename` properties, e.g. when an empty array may be sent. * * By providing a list of custom typenames you may "tag" a result as containing a certain type, which * helps the document cache associate mutations with queries when either don't actually contain a * `__typename` in the JSON result. */ additionalTypenames?: string[]; /** The `fetch` function used to make API calls. * * @remarks * This is the fetch polyfill used by any fetch exchange to make an API request. By default, when this * option isn't set, any fetch exchange will attempt to use the globally available `fetch` function * to make a request instead. * * @see {@link https://developer.mozilla.org/en-US/d