Mirror: The highly customizable and versatile GraphQL client with which you add on features like normalized caching as you grow.
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

docs(packages): Add TSDocs to all remaining packages (#3079)

authored by

Phil Pluckthun and committed by
GitHub
47c34c41 f6b39ab4

+2389 -159
+5
.changeset/lucky-months-fail.md
··· 1 + --- 2 + '@urql/core': patch 3 + --- 4 + 5 + Add missing type exports of SSR-related types (`SerializedResult`, `SSRExchangeParams`, `SSRExchange`, and `SSRData`) to `@urql/core`'s type exports.
+7
.changeset/strong-shirts-hear.md
··· 1 + --- 2 + '@urql/introspection': patch 3 + '@urql/storage-rn': patch 4 + 'next-urql': patch 5 + --- 6 + 7 + Add TSDocs to `@urql/*` packages.
+8
.changeset/tricky-cherries-glow.md
··· 1 + --- 2 + '@urql/preact': patch 3 + '@urql/svelte': patch 4 + 'urql': patch 5 + '@urql/vue': patch 6 + --- 7 + 8 + Add TSDocs to all `urql` bindings packages.
+7
packages/core/src/exchanges/index.ts
··· 7 7 export { composeExchanges } from './compose'; 8 8 9 9 export type { 10 + SerializedResult, 11 + SSRExchangeParams, 12 + SSRExchange, 13 + SSRData, 14 + } from './ssr'; 15 + 16 + export type { 10 17 SubscriptionOperation, 11 18 SubscriptionForwarder, 12 19 SubscriptionExchangeOpts,
+15
packages/introspection/src/getIntrospectedSchema.ts
··· 7 7 getIntrospectionQuery, 8 8 } from 'graphql'; 9 9 10 + /** Returns an {@link IntrospectionQuery} result for a given GraphQL schema. 11 + * 12 + * @param input - A GraphQL schema, either as an SDL string, or a {@link GraphQLSchema} object. 13 + * @returns an {@link IntrospectionQuery} result. 14 + * 15 + * @remarks 16 + * `getIntrospectedSchema` can be used to get a Schema Introspection result from 17 + * a given GraphQL schema. The schema can be passed as an SDL string or a 18 + * {@link GraphQLSchema} object. If an {@link IntrospectionQuery} object is 19 + * passed, it'll be passed through. 20 + * 21 + * @throws 22 + * If `input` cannot be parsed or converted into a {@link GraphQLSchema} then 23 + * a {@link TypeError} will be thrown. 24 + */ 10 25 export const getIntrospectedSchema = ( 11 26 input: string | IntrospectionQuery | GraphQLSchema 12 27 ): IntrospectionQuery => {
+39 -5
packages/introspection/src/minifyIntrospectionQuery.ts
··· 156 156 } 157 157 }; 158 158 159 + /** Input parameters for the {@link minifyIntrospectionQuery} function. */ 159 160 export interface MinifySchemaOptions { 160 - /** Includes scalar names (instead of an `Any` replacement) in the output when enabled. */ 161 + /** Includes scalars instead of removing them. 162 + * 163 + * @remarks 164 + * By default, all scalars will be replaced by a single scalar called `Any` 165 + * in the output, unless this option is set to `true`. 166 + */ 161 167 includeScalars?: boolean; 162 - /** Includes enums (instead of an `Any` replacement) in the output when enabled. */ 168 + /** Includes enums instead of removing them. 169 + * 170 + * @remarks 171 + * By default, all enums will be replaced by a single scalar called `Any` 172 + * in the output, unless this option is set to `true`. 173 + */ 163 174 includeEnums?: boolean; 164 - /** Includes all input objects (instead of an `Any` replacement) in the output when enabled. */ 175 + /** Includes inputs instead of removing them. 176 + * 177 + * @remarks 178 + * By default, all inputs will be replaced by a single scalar called `Any` 179 + * in the output, unless this option is set to `true`. 180 + */ 165 181 includeInputs?: boolean; 166 - /** Includes all directives in the output when enabled. */ 182 + /** Includes directives instead of removing them. */ 167 183 includeDirectives?: boolean; 168 184 } 169 185 170 - /** Removes extraneous information from introspected schema data to minify it and prepare it for use on the client-side. */ 186 + /** Minifies an {@link IntrospectionQuery} for use with Graphcache or the `populateExchange`. 187 + * 188 + * @param schema - An {@link IntrospectionQuery} object to be minified. 189 + * @param opts - An optional {@link MinifySchemaOptions} configuration object. 190 + * @returns the minified {@link IntrospectionQuery} object. 191 + * 192 + * @remarks 193 + * `minifyIntrospectionQuery` reduces the size of an {@link IntrospectionQuery} by 194 + * removing data and information that a client-side consumer, like Graphcache or the 195 + * `populateExchange`, may not require. 196 + * 197 + * At the very least, it will remove system types, descriptions, depreactions, 198 + * and source locations. Unless disabled via the options passed, it will also 199 + * by default remove all scalars, enums, inputs, and directives. 200 + * 201 + * @throws 202 + * If `schema` receives an object that isn’t an {@link IntrospectionQuery}, a 203 + * {@link TypeError} will be thrown. 204 + */ 171 205 export const minifyIntrospectionQuery = ( 172 206 schema: IntrospectionQuery, 173 207 opts: MinifySchemaOptions = {}
+25 -1
packages/next-urql/src/init-urql-client.ts
··· 2 2 3 3 let urqlClient: Client | null = null; 4 4 5 + /** Resets the `Client` that {@link initUrqlClient} returns. 6 + * 7 + * @remarks 8 + * `resetClient` will force {@link initUrqlClient} to create a new 9 + * {@link Client}, rather than reusing the same `Client` it already 10 + * created on the client-side. 11 + * 12 + * This may be used to force the cache and any state in the `Client` 13 + * to be cleared and reset. 14 + */ 5 15 export function resetClient() { 6 16 urqlClient = null; 7 17 } 8 18 19 + /** Creates a {@link Client} the given options. 20 + * 21 + * @param clientOptions - {@link ClientOptions} to create the `Client` with. 22 + * @param canEnableSuspense - Enables React Suspense on the server-side for `react-ssr-prepass`. 23 + * @returns the created {@link Client} 24 + * 25 + * @remarks 26 + * `initUrqlClient` creates a {@link Client} with the given options, 27 + * like {@link createClient} does, but reuses the same client when 28 + * run on the client-side. 29 + * 30 + * As long as `canEnableSuspense` is set to `true`, it enables React Suspense 31 + * mode on the server-side for `react-ssr-prepass`. 32 + */ 9 33 export function initUrqlClient( 10 34 clientOptions: ClientOptions, 11 35 canEnableSuspense: boolean 12 - ): Client | null { 36 + ): Client { 13 37 // Create a new Client for every server-side rendered request. 14 38 // This ensures we reset the state for each rendered page. 15 39 // If there is an exising client instance on the client-side, use it.
+76 -32
packages/next-urql/src/types.ts
··· 1 - import { GraphQLError } from 'graphql'; 2 - import { ClientOptions, Exchange, Client } from 'urql'; 3 - import { NextPageContext } from 'next'; 4 - import { AppContext } from 'next/app'; 1 + import type { ClientOptions, Client, SSRExchange, SSRData } from '@urql/core'; 2 + import type { NextPageContext } from 'next'; 3 + import type { AppContext } from 'next/app'; 5 4 5 + /** The Next.js {@link NextPageContext}, as modified by `next-urql`. */ 6 6 export interface NextUrqlPageContext extends NextPageContext { 7 7 urqlClient: Client; 8 8 } 9 9 10 + /** The Next.js {@link AppContext}, as modified by `next-urql`. */ 10 11 export interface NextUrqlAppContext extends AppContext { 11 12 urqlClient: Client; 12 13 } 13 14 14 15 export type NextUrqlContext = NextUrqlPageContext | NextUrqlAppContext; 15 16 17 + /** Passed to {@link withUrqlClient} returning the options a {@link Client} is created with. 18 + * 19 + * @param ssrExchange - the `ssrExchange` you must use in your `exchanges` array. 20 + * @param ctx - Passed when `getInitialProps` is used and set to Next.js’ {@link NextPageContext}. 21 + * @returns a {@link ClientOptions} configuration object to create a {@link Client} with. 22 + * 23 + * @remarks 24 + * You must define a `getClientConfig` function and pass it to {@link withUrqlClient}. 25 + * 26 + * This function defines the options passed to {@link initUrqlClient}. 27 + * It passes you an `ssrExchange` that you must use in your `exchanges` array. 28 + * 29 + * @example 30 + * ```ts 31 + * import { cacheExchange, fetchExchange } from '@urql/core'; 32 + * import { withUrqlClient } from 'next-urql'; 33 + * 34 + * const WrappedPage = withUrqlClient( 35 + * (ssrExchange) => ({ 36 + * url: 'https://YOUR_API', 37 + * exchanges: [cacheExchange, ssrExchange, fetchExchange], 38 + * }) 39 + * )(Page); 40 + * ``` 41 + */ 16 42 export type NextUrqlClientConfig = ( 17 43 ssrExchange: SSRExchange, 18 44 ctx?: NextPageContext 19 45 ) => ClientOptions; 20 46 21 - export interface WithUrqlState { 22 - urqlState?: SSRData; 23 - } 24 - 25 - export interface WithUrqlClient { 47 + /** Props that {@link withUrqlClient} components pass on to your component. */ 48 + export interface WithUrqlProps { 49 + /** The {@link Client} that {@link withUrqlClient} created for your component. */ 26 50 urqlClient?: Client; 27 - } 28 - 29 - export interface WithUrqlProps extends WithUrqlClient, WithUrqlState { 30 - resetUrqlClient?: () => void; 51 + /** Next.js’ `pageProps` prop, as passed to it by Next.js. */ 31 52 pageProps: any; 53 + /** The SSR data that {@link withUrqlClient} created for your component. */ 54 + urqlState?: SSRData; 55 + /** Resets the `Client` that on the client-side. 56 + * 57 + * @remarks 58 + * `resetUrqlClient` will force a new {@link Client} to be created 59 + * on the client-side, rather than the same `Client` with the same 60 + * server-side data to be reused. 61 + * 62 + * This may be used to force the cache and any state in the `Client` 63 + * to be cleared and reset. 64 + */ 65 + resetUrqlClient?(): void; 32 66 [key: string]: any; 33 67 } 34 68 35 - export interface SerializedResult { 36 - data?: any; 37 - error?: { 38 - graphQLErrors: Array<Partial<GraphQLError> | string>; 39 - networkError?: string; 40 - }; 41 - } 42 - 43 - export interface SSRData { 44 - [key: string]: SerializedResult; 45 - } 46 - 47 - export interface SSRExchange extends Exchange { 48 - /** Rehydrates cached data */ 49 - restoreData(data: SSRData): void; 50 - /** Extracts cached data */ 51 - extractData(): SSRData; 52 - } 53 - 69 + /** Options that may be passed to the {@link withUrqlClient} wrapper function. */ 54 70 export interface WithUrqlClientOptions { 71 + /** Enables automatic server-side rendering mode. 72 + * 73 + * @remarks 74 + * When enabled, {@link withUrqlClient} will add a `getInitialProps` 75 + * function to the resulting component, even if you haven't defined 76 + * one. 77 + * 78 + * This function will automatically capture `urql`'s SSR state on the 79 + * server-side and rehydrate it on the client-side, unless 80 + * {@link WithUrqlClientOptions.neverSuspend} is `true`. 81 + */ 55 82 ssr?: boolean; 83 + /** Disables automatic server-side rendering, even if a `getInitialProps` function is defined. 84 + * 85 + * @remarks 86 + * When enabled, {@link withUrqlClient} will never execute queries 87 + * on the server-side automatically, and will instead rely on you 88 + * to do so manually. 89 + */ 56 90 neverSuspend?: boolean; 91 + /** Enables reexecuting operations on the client-side after rehydration. 92 + * 93 + * @remarks 94 + * When enabled, `staleWhileRevalidate` will reexecute GraphQL queries on 95 + * the client-side, if they’ve been rehydrated from SSR state. 96 + * 97 + * This is useful if you, for instance, cache your server-side rendered 98 + * pages, or if you use `getStaticProps` and wish to get this data 99 + * updated. 100 + */ 57 101 staleWhileRevalidate?: boolean; 58 102 }
+40 -17
packages/next-urql/src/with-urql-client.ts
··· 6 6 ReactNode, 7 7 ReactElement, 8 8 } from 'react'; 9 - import ssrPrepass from 'react-ssr-prepass'; 10 - import { NextComponentType, NextPage, NextPageContext } from 'next'; 11 - import NextApp, { AppContext } from 'next/app'; 12 9 13 10 import { 14 11 Provider, 12 + SSRExchange, 15 13 ssrExchange, 16 - dedupExchange, 17 14 cacheExchange, 18 15 fetchExchange, 19 16 } from 'urql'; 20 17 18 + import ssrPrepass from 'react-ssr-prepass'; 19 + import { NextComponentType, NextPage, NextPageContext } from 'next'; 20 + import NextApp, { AppContext } from 'next/app'; 21 + 21 22 import { initUrqlClient, resetClient } from './init-urql-client'; 22 23 23 24 import { ··· 25 26 NextUrqlContext, 26 27 WithUrqlProps, 27 28 WithUrqlClientOptions, 28 - SSRExchange, 29 29 } from './types'; 30 30 31 31 let ssr: SSRExchange; ··· 33 33 getLayout?: (page: ReactElement) => ReactNode; 34 34 }; 35 35 36 + /** Creates a wrapper for Next.js Page, App, or Document components that rehydrates `urql` state. 37 + * 38 + * @param getClientConfig - function used to create the {@link Client} 39 + * @param options - optional {@link WithUrqlClientOptions} configuration options 40 + * @returns a higher-order component function, which you can pass a Next.js page or app component. 41 + * 42 + * @remarks 43 + * Used to wrap a Next.js page or app component. It will create a {@link Client} and passes 44 + * it on to the child component and adds a React Provider for it. 45 + * 46 + * It will restore any page’s `pageProps.urqlState` with the {@link SSRExchange} and also 47 + * supports doing this automatically when the {@link WithUrqlClientOptions.ssr} option 48 + * is enabled. 49 + * 50 + * If you don’t define the above option, you will have to write `getServerSideProps` or 51 + * `getStaticProps` methods on your component manually. 52 + * 53 + * @see {@link https://urql.dev/goto/docs/advanced/server-side-rendering/#nextjs} for more documentation. 54 + * 55 + * @example 56 + * ```ts 57 + * import { cacheExchange, fetchExchange } from '@urql/core'; 58 + * import { withUrqlClient } from 'next-urql'; 59 + * 60 + * const WrappedPage = withUrqlClient( 61 + * (ssrExchange) => ({ 62 + * url: 'https://YOUR_API', 63 + * exchanges: [cacheExchange, ssrExchange, fetchExchange], 64 + * }), 65 + * { ssr: true }, 66 + * )(Page); 67 + * ``` 68 + */ 36 69 export function withUrqlClient( 37 70 getClientConfig: NextUrqlClientConfig, 38 71 options?: WithUrqlClientOptions ··· 77 110 const clientConfig = getClientConfig(ssr); 78 111 if (!clientConfig.exchanges) { 79 112 // When the user does not provide exchanges we make the default assumption. 80 - clientConfig.exchanges = [ 81 - dedupExchange, 82 - cacheExchange, 83 - ssr, 84 - fetchExchange, 85 - ]; 113 + clientConfig.exchanges = [cacheExchange, ssr, fetchExchange]; 86 114 } 87 115 88 116 return initUrqlClient(clientConfig, shouldEnableSuspense)!; ··· 129 157 const clientConfig = getClientConfig(ssrCache, ctx); 130 158 if (!clientConfig.exchanges) { 131 159 // When the user does not provide exchanges we make the default assumption. 132 - clientConfig.exchanges = [ 133 - dedupExchange, 134 - cacheExchange, 135 - ssrCache, 136 - fetchExchange, 137 - ]; 160 + clientConfig.exchanges = [cacheExchange, ssrCache, fetchExchange]; 138 161 } 139 162 140 163 const urqlClient = initUrqlClient(clientConfig, !options!.neverSuspend);
+30 -12
packages/preact-urql/src/components/Mutation.ts
··· 1 1 import { VNode } from 'preact'; 2 2 import { DocumentNode } from 'graphql'; 3 - import { 4 - AnyVariables, 5 - TypedDocumentNode, 6 - OperationResult, 7 - OperationContext, 8 - } from '@urql/core'; 9 - import { useMutation, UseMutationState } from '../hooks'; 3 + import { AnyVariables, TypedDocumentNode } from '@urql/core'; 4 + 5 + import { useMutation, UseMutationState, UseMutationExecute } from '../hooks'; 10 6 7 + /** Props accepted by {@link Mutation}. 8 + * 9 + * @remarks 10 + * `MutationProps` are the props accepted by the {@link Mutation} component. 11 + * 12 + * The result, the {@link MutationState} object, will be passed to 13 + * a {@link MutationProps.children} function, passed as children 14 + * to the `Mutation` component. 15 + */ 11 16 export interface MutationProps< 12 17 Data = any, 13 18 Variables extends AnyVariables = AnyVariables 14 19 > { 20 + /* The GraphQL mutation document that {@link useMutation} will execute. */ 15 21 query: DocumentNode | TypedDocumentNode<Data, Variables> | string; 16 - children: (arg: MutationState<Data, Variables>) => VNode<any>; 22 + children(arg: MutationState<Data, Variables>): VNode<any>; 17 23 } 18 24 25 + /** Object that {@link MutationProps.children} is called with. 26 + * 27 + * @remarks 28 + * This is an extented {@link UseMutationstate} with an added 29 + * {@link MutationState.executeMutation} method, which is usually 30 + * part of a tuple returned by {@link useMutation}. 31 + */ 19 32 export interface MutationState< 20 33 Data = any, 21 34 Variables extends AnyVariables = AnyVariables 22 35 > extends UseMutationState<Data, Variables> { 23 - executeMutation: ( 24 - variables: Variables, 25 - context?: Partial<OperationContext> 26 - ) => Promise<OperationResult<Data, Variables>>; 36 + /** Alias to {@link useMutation}’s `executeMutation` function. */ 37 + executeMutation: UseMutationExecute<Data, Variables>; 27 38 } 28 39 40 + /** Component Wrapper around {@link useMutation} to run a GraphQL query. 41 + * 42 + * @remarks 43 + * `Mutation` is a component wrapper around the {@link useMutation} hook 44 + * that calls the {@link MutationProps.children} prop, as a function, 45 + * with the {@link MutationState} object. 46 + */ 29 47 export function Mutation< 30 48 Data = any, 31 49 Variables extends AnyVariables = AnyVariables
+35 -4
packages/preact-urql/src/components/Query.ts
··· 1 1 import { VNode } from 'preact'; 2 - import { AnyVariables, OperationContext } from '@urql/core'; 3 - import { useQuery, UseQueryArgs, UseQueryState } from '../hooks'; 2 + import { AnyVariables } from '@urql/core'; 3 + 4 + import { 5 + useQuery, 6 + UseQueryArgs, 7 + UseQueryState, 8 + UseQueryExecute, 9 + } from '../hooks'; 4 10 11 + /** Props accepted by {@link Query}. 12 + * 13 + * @remarks 14 + * `QueryProps` are the props accepted by the {@link Query} component, 15 + * which is identical to {@link UseQueryArgs}. 16 + * 17 + * The result, the {@link QueryState} object, will be passed to 18 + * a {@link QueryProps.children} function, passed as children 19 + * to the `Query` component. 20 + */ 5 21 export type QueryProps< 6 22 Data = any, 7 23 Variables extends AnyVariables = AnyVariables 8 24 > = UseQueryArgs<Variables, Data> & { 9 - children: (arg: QueryState<Data, Variables>) => VNode<any>; 25 + children(arg: QueryState<Data, Variables>): VNode<any>; 10 26 }; 11 27 28 + /** Object that {@link QueryProps.children} is called with. 29 + * 30 + * @remarks 31 + * This is an extented {@link UseQueryState} with an added 32 + * {@link QueryState.executeQuery} method, which is usually 33 + * part of a tuple returned by {@link useQuery}. 34 + */ 12 35 export interface QueryState< 13 36 Data = any, 14 37 Variables extends AnyVariables = AnyVariables 15 38 > extends UseQueryState<Data, Variables> { 16 - executeQuery: (opts?: Partial<OperationContext>) => void; 39 + /** Alias to {@link useQuery}’s `executeQuery` function. */ 40 + executeQuery: UseQueryExecute; 17 41 } 18 42 43 + /** Component Wrapper around {@link useQuery} to run a GraphQL query. 44 + * 45 + * @remarks 46 + * `Query` is a component wrapper around the {@link useQuery} hook 47 + * that calls the {@link QueryProps.children} prop, as a function, 48 + * with the {@link QueryState} object. 49 + */ 19 50 export function Query< 20 51 Data = any, 21 52 Variables extends AnyVariables = AnyVariables
+32 -3
packages/preact-urql/src/components/Subscription.ts
··· 1 1 import { VNode } from 'preact'; 2 - import { AnyVariables, OperationContext } from '@urql/core'; 2 + import { AnyVariables } from '@urql/core'; 3 3 4 4 import { 5 5 useSubscription, 6 6 UseSubscriptionArgs, 7 7 UseSubscriptionState, 8 + UseSubscriptionExecute, 8 9 SubscriptionHandler, 9 10 } from '../hooks'; 10 11 12 + /** Props accepted by {@link Subscription}. 13 + * 14 + * @remarks 15 + * `SubscriptionProps` are the props accepted by the {@link Subscription} component, 16 + * which is identical to {@link UseSubscriptionArgs} with an added 17 + * {@link SubscriptionProps.handler} prop, which {@link useSubscription} usually 18 + * accepts as an additional argument. 19 + * 20 + * The result, the {@link SubscriptionState} object, will be passed to 21 + * a {@link SubscriptionProps.children} function, passed as children 22 + * to the `Subscription` component. 23 + */ 11 24 export type SubscriptionProps< 12 25 Data = any, 13 26 Result = Data, 14 27 Variables extends AnyVariables = AnyVariables 15 28 > = UseSubscriptionArgs<Variables, Data> & { 29 + /** Accepts the {@link SubscriptionHandler} as a prop. */ 16 30 handler?: SubscriptionHandler<Data, Result>; 17 - children: (arg: SubscriptionState<Result, Variables>) => VNode<any>; 31 + children(arg: SubscriptionState<Result, Variables>): VNode<any>; 18 32 }; 19 33 34 + /** Object that {@link SubscriptionProps.children} is called with. 35 + * 36 + * @remarks 37 + * This is an extented {@link UseSubscriptionState} with an added 38 + * {@link SubscriptionState.executeSubscription} method, which is usually 39 + * part of a tuple returned by {@link useSubscription}. 40 + */ 20 41 export interface SubscriptionState< 21 42 Data = any, 22 43 Variables extends AnyVariables = AnyVariables 23 44 > extends UseSubscriptionState<Data, Variables> { 24 - executeSubscription: (opts?: Partial<OperationContext>) => void; 45 + /** Alias to {@link useSubscription}’s `executeMutation` function. */ 46 + executeSubscription: UseSubscriptionExecute; 25 47 } 26 48 49 + /** Component Wrapper around {@link useSubscription} to run a GraphQL subscription. 50 + * 51 + * @remarks 52 + * `Subscription` is a component wrapper around the {@link useSubscription} hook 53 + * that calls the {@link SubscriptionProps.children} prop, as a function, 54 + * with the {@link SubscriptionState} object. 55 + */ 27 56 export function Subscription< 28 57 Data = any, 29 58 Result = Data,
+54
packages/preact-urql/src/context.ts
··· 3 3 import { Client } from '@urql/core'; 4 4 5 5 const OBJ = {}; 6 + 7 + /** `@urql/preact`'s Preact Context. 8 + * 9 + * @remarks 10 + * The Preact Context that `urql`’s {@link Client} will be provided with. 11 + * You may use the reexported {@link Provider} to provide a `Client` as well. 12 + */ 6 13 export const Context: import('preact').Context<Client | object> = 7 14 createContext(OBJ); 15 + 16 + /** Provider for `urql`’s {@link Client} to GraphQL hooks. 17 + * 18 + * @remarks 19 + * `Provider` accepts a {@link Client} and provides it to all GraphQL hooks, 20 + * and {@link useClient}. 21 + * 22 + * You should make sure to create a {@link Client} and provide it with the 23 + * `Provider` to parts of your component tree that use GraphQL hooks. 24 + * 25 + * @example 26 + * ```tsx 27 + * import { Provider } from '@urql/preact'; 28 + * // All of `@urql/core` is also re-exported by `@urql/preact`: 29 + * import { Client, cacheExchange, fetchExchange } from '@urql/core'; 30 + * 31 + * const client = new Client({ 32 + * url: 'https://API', 33 + * exchanges: [cacheExchange, fetchExchange], 34 + * }); 35 + * 36 + * const App = () => ( 37 + * <Provider value={client}> 38 + * <Component /> 39 + * </Provider> 40 + * ); 41 + * ``` 42 + */ 43 + 8 44 export const Provider: import('preact').Provider<Client | object> = 9 45 Context.Provider; 46 + 47 + /** Preact Consumer component, providing the {@link Client} provided on a parent component. 48 + * @remarks 49 + * This is an alias for {@link Context.Consumer}. 50 + */ 10 51 export const Consumer: import('preact').Consumer<Client | object> = 11 52 Context.Consumer; 12 53 13 54 Context.displayName = 'UrqlContext'; 14 55 56 + /** Hook returning a {@link Client} from {@link Context}. 57 + * 58 + * @remarks 59 + * `useClient` is a convenience hook, which accesses `@urql/preact`'s {@link Context} 60 + * and returns the {@link Client} defined on it. 61 + * 62 + * This will be the {@link Client} you passed to a {@link Provider} 63 + * you wrapped your elements containing this hook with. 64 + * 65 + * @throws 66 + * In development, if the component you call `useClient()` in is 67 + * not wrapped in a {@link Provider}, an error is thrown. 68 + */ 15 69 export const useClient = (): Client => { 16 70 const client = useContext(Context); 17 71
+110 -7
packages/preact-urql/src/hooks/useMutation.ts
··· 15 15 import { useClient } from '../context'; 16 16 import { initialState } from './constants'; 17 17 18 + /** State of the last mutation executed by your {@link useMutation} hook. 19 + * 20 + * @remarks 21 + * `UseMutationState` is returned (in a tuple) by {@link useMutation} and 22 + * gives you the {@link OperationResult} of the last mutation executed 23 + * with {@link UseMutationExecute}. 24 + * 25 + * Even if the mutation document passed to {@link useMutation} changes, 26 + * the state isn’t reset, so you can keep displaying the previous result. 27 + */ 18 28 export interface UseMutationState< 19 29 Data = any, 20 30 Variables extends AnyVariables = AnyVariables 21 31 > { 32 + /** Indicates whether `useMutation` is currently executing a mutation. */ 22 33 fetching: boolean; 34 + /** Indicates that the mutation result is not fresh. 35 + * 36 + * @remarks 37 + * The `stale` flag is set to `true` when a new result for the mutation 38 + * is expected. 39 + * This is mostly unused for mutations and will rarely affect you, and 40 + * is more relevant for queries. 41 + * 42 + * @see {@link OperationResult.stale} for the source of this value. 43 + */ 23 44 stale: boolean; 45 + /** The {@link OperationResult.data} for the executed mutation. */ 24 46 data?: Data; 47 + /** The {@link OperationResult.error} for the executed mutation. */ 25 48 error?: CombinedError; 49 + /** The {@link OperationResult.extensions} for the executed mutation. */ 26 50 extensions?: Record<string, any>; 51 + /** The {@link Operation} that the current state is for. 52 + * 53 + * @remarks 54 + * This is the mutation {@link Operation} that has last been executed. 55 + * When {@link UseQueryState.fetching} is `true`, this is the 56 + * last `Operation` that the current state was for. 57 + */ 27 58 operation?: Operation<Data, Variables>; 28 59 } 29 60 61 + /** Triggers {@link useMutation} to execute its GraphQL mutation operation. 62 + * 63 + * @param variables - variables using which the mutation will be executed. 64 + * @param context - optionally, context options that will be merged with the hook's 65 + * {@link UseQueryArgs.context} options and the `Client`’s options. 66 + * @returns the {@link OperationResult} of the mutation. 67 + * 68 + * @remarks 69 + * When called, {@link useMutation} will start the GraphQL mutation 70 + * it currently holds and use the `variables` passed to it. 71 + * 72 + * Once the mutation response comes back from the API, its 73 + * returned promise will resolve to the mutation’s {@link OperationResult} 74 + * and the {@link UseMutationState} will be updated with the result. 75 + * 76 + * @example 77 + * ```ts 78 + * const [result, executeMutation] = useMutation(UpdateTodo); 79 + * const start = async ({ id, title }) => { 80 + * const result = await executeMutation({ id, title }); 81 + * }; 82 + */ 83 + export type UseMutationExecute< 84 + Data = any, 85 + Variables extends AnyVariables = AnyVariables 86 + > = ( 87 + variables: Variables, 88 + context?: Partial<OperationContext> 89 + ) => Promise<OperationResult<Data, Variables>>; 90 + 91 + /** Result tuple returned by the {@link useMutation} hook. 92 + * 93 + * @remarks 94 + * Similarly to a `useState` hook’s return value, 95 + * the first element is the {@link useMutation}’s state, updated 96 + * as mutations are executed with the second value, which is 97 + * used to start mutations and is a {@link UseMutationExecute} 98 + * function. 99 + */ 30 100 export type UseMutationResponse< 31 101 Data = any, 32 102 Variables extends AnyVariables = AnyVariables 33 - > = [ 34 - UseMutationState<Data, Variables>, 35 - ( 36 - variables: Variables, 37 - context?: Partial<OperationContext> 38 - ) => Promise<OperationResult<Data, Variables>> 39 - ]; 103 + > = [UseMutationState<Data, Variables>, UseMutationExecute<Data, Variables>]; 40 104 105 + /** Hook to create a GraphQL mutation, run by passing variables to the returned execute function. 106 + * 107 + * @param query - a GraphQL mutation document which `useMutation` will execute. 108 + * @returns a {@link UseMutationResponse} tuple of a {@link UseMutationState} result, 109 + * and an execute function to start the mutation. 110 + * 111 + * @remarks 112 + * `useMutation` allows GraphQL mutations to be defined and keeps its state 113 + * after the mutation is started with the returned execute function. 114 + * 115 + * Given a GraphQL mutation document it returns state to keep track of the 116 + * mutation state and a {@link UseMutationExecute} function, which accepts 117 + * variables for the mutation to be executed. 118 + * Once called, the mutation executes and the state will be updated with 119 + * the mutation’s result. 120 + * 121 + * @see {@link https://urql.dev/goto/docs/basics/react-preact/#mutations} for `useMutation` docs. 122 + * 123 + * @example 124 + * ```ts 125 + * import { gql, useMutation } from '@urql/preact'; 126 + * 127 + * const UpdateTodo = gql` 128 + * mutation ($id: ID!, $title: String!) { 129 + * updateTodo(id: $id, title: $title) { 130 + * id, title 131 + * } 132 + * } 133 + * `; 134 + * 135 + * const UpdateTodo = () => { 136 + * const [result, executeMutation] = useMutation(UpdateTodo); 137 + * const start = async ({ id, title }) => { 138 + * const result = await executeMutation({ id, title }); 139 + * }; 140 + * // ... 141 + * }; 142 + * ``` 143 + */ 41 144 export function useMutation< 42 145 Data = any, 43 146 Variables extends AnyVariables = AnyVariables
+159 -5
packages/preact-urql/src/hooks/useQuery.ts
··· 28 28 import { useRequest } from './useRequest'; 29 29 import { initialState } from './constants'; 30 30 31 + /** Input arguments for the {@link useQuery} hook. 32 + * 33 + * @param query - The GraphQL query that `useQuery` executes. 34 + * @param variables - The variables for the GraphQL query that `useQuery` executes. 35 + */ 31 36 export type UseQueryArgs< 32 37 Variables extends AnyVariables = AnyVariables, 33 38 Data = any 34 39 > = { 40 + /** Updates the {@link RequestPolicy} for the executed GraphQL query operation. 41 + * 42 + * @remarks 43 + * `requestPolicy` modifies the {@link RequestPolicy} of the GraphQL query operation 44 + * that `useQuery` executes, and indicates a caching strategy for cache exchanges. 45 + * 46 + * For example, when set to `'cache-and-network'`, {@link useQuery} will 47 + * receive a cached result with `stale: true` and an API request will be 48 + * sent in the background. 49 + * 50 + * @see {@link OperationContext.requestPolicy} for where this value is set. 51 + */ 35 52 requestPolicy?: RequestPolicy; 53 + /** Updates the {@link OperationContext} for the executed GraphQL query operation. 54 + * 55 + * @remarks 56 + * `context` may be passed to {@link useQuery}, to update the {@link OperationContext} 57 + * of a query operation. This may be used to update the `context` that exchanges 58 + * will receive for a single hook. 59 + * 60 + * Hint: This should be wrapped in a `useMemo` hook, to make sure that your 61 + * component doesn’t infinitely update. 62 + * 63 + * @example 64 + * ```ts 65 + * const [result, reexecute] = useQuery({ 66 + * query, 67 + * context: useMemo(() => ({ 68 + * additionalTypenames: ['Item'], 69 + * }), []) 70 + * }); 71 + * ``` 72 + */ 36 73 context?: Partial<OperationContext>; 74 + /** Prevents {@link useQuery} from automatically executing GraphQL query operations. 75 + * 76 + * @remarks 77 + * `pause` may be set to `true` to stop {@link useQuery} from executing 78 + * automatically. The hook will stop receiving updates from the {@link Client} 79 + * and won’t execute the query operation, until either it’s set to `false` 80 + * or the {@link UseQueryExecute} function is called. 81 + * 82 + * @see {@link https://urql.dev/goto/docs/basics/react-preact/#pausing-usequery} for 83 + * documentation on the `pause` option. 84 + */ 37 85 pause?: boolean; 38 86 } & GraphQLRequestParams<Data, Variables>; 39 87 88 + /** State of the current query, your {@link useQuery} hook is executing. 89 + * 90 + * @remarks 91 + * `UseQueryState` is returned (in a tuple) by {@link useQuery} and 92 + * gives you the updating {@link OperationResult} of GraphQL queries. 93 + * 94 + * Even when the query and variables passed to {@link useQuery} change, 95 + * this state preserves the prior state and sets the `fetching` flag to 96 + * `true`. 97 + * This allows you to display the previous state, while implementing 98 + * a separate loading indicator separately. 99 + */ 40 100 export interface UseQueryState< 41 101 Data = any, 42 102 Variables extends AnyVariables = AnyVariables 43 103 > { 104 + /** Indicates whether `useQuery` is waiting for a new result. 105 + * 106 + * @remarks 107 + * When `useQuery` is passed a new query and/or variables, it will 108 + * start executing the new query operation and `fetching` is set to 109 + * `true` until a result arrives. 110 + * 111 + * Hint: This is subtly different than whether the query is actually 112 + * fetching, and doesn’t indicate whether a query is being re-executed 113 + * in the background. For this, see {@link UseQueryState.stale}. 114 + */ 44 115 fetching: boolean; 116 + /** Indicates that the state is not fresh and a new result will follow. 117 + * 118 + * @remarks 119 + * The `stale` flag is set to `true` when a new result for the query 120 + * is expected and `useQuery` is waiting for it. This may indicate that 121 + * a new request is being requested in the background. 122 + * 123 + * @see {@link OperationResult.stale} for the source of this value. 124 + */ 45 125 stale: boolean; 126 + /** The {@link OperationResult.data} for the executed query. */ 46 127 data?: Data; 128 + /** The {@link OperationResult.error} for the executed query. */ 47 129 error?: CombinedError; 130 + /** The {@link OperationResult.extensions} for the executed query. */ 48 131 extensions?: Record<string, any>; 132 + /** The {@link Operation} that the current state is for. 133 + * 134 + * @remarks 135 + * This is the {@link Operation} that is currently being executed. 136 + * When {@link UseQueryState.fetching} is `true`, this is the 137 + * last `Operation` that the current state was for. 138 + */ 49 139 operation?: Operation<Data, Variables>; 50 140 } 51 141 142 + /** Triggers {@link useQuery} to execute a new GraphQL query operation. 143 + * 144 + * @remarks 145 + * When called, {@link useQuery} will re-execute the GraphQL query operation 146 + * it currently holds, even if {@link UseQueryArgs.pause} is set to `true`. 147 + * 148 + * This is useful for executing a paused query or re-executing a query 149 + * and get a new network result, by passing a new request policy. 150 + * 151 + * ```ts 152 + * const [result, reexecuteQuery] = useQuery({ query }); 153 + * 154 + * const refresh = () => { 155 + * // Re-execute the query with a network-only policy, skipping the cache 156 + * reexecuteQuery({ requestPolicy: 'network-only' }); 157 + * }; 158 + * ``` 159 + */ 160 + export type UseQueryExecute = (opts?: Partial<OperationContext>) => void; 161 + 162 + /** Result tuple returned by the {@link useQuery} hook. 163 + * 164 + * @remarks 165 + * Similarly to a `useState` hook’s return value, 166 + * the first element is the {@link useQuery}’s result and state, 167 + * a {@link UseQueryState} object, 168 + * and the second is used to imperatively re-execute the query 169 + * via a {@link UseQueryExecute} function. 170 + */ 52 171 export type UseQueryResponse< 53 172 Data = any, 54 173 Variables extends AnyVariables = AnyVariables 55 - > = [ 56 - UseQueryState<Data, Variables>, 57 - (opts?: Partial<OperationContext>) => void 58 - ]; 174 + > = [UseQueryState<Data, Variables>, UseQueryExecute]; 59 175 60 - /** Convert the Source to a React Suspense source on demand */ 176 + /** Convert the Source to a React Suspense source on demand 177 + * @internal 178 + */ 61 179 function toSuspenseSource<T>(source: Source<T>): Source<T> { 62 180 const shared = share(source); 63 181 let cache: T | void; ··· 98 216 99 217 const sources = new Map<number, Source<OperationResult>>(); 100 218 219 + /** Hook to run a GraphQL query and get updated GraphQL results. 220 + * 221 + * @param args - a {@link UseQueryArgs} object, to pass a `query`, `variables`, and options. 222 + * @returns a {@link UseQueryResponse} tuple of a {@link UseQueryState} result, and re-execute function. 223 + * 224 + * @remarks 225 + * `useQuery` allows GraphQL queries to be defined and executed. 226 + * Given {@link UseQueryArgs.query}, it executes the GraphQL query with the 227 + * context’s {@link Client}. 228 + * 229 + * The returned result updates when the `Client` has new results 230 + * for the query, and changes when your input `args` change. 231 + * 232 + * Additionally, if the `suspense` option is enabled on the `Client`, 233 + * the `useQuery` hook will suspend instead of indicating that it’s 234 + * waiting for a result via {@link UseQueryState.fetching}. 235 + * 236 + * @see {@link https://urql.dev/goto/docs/basics/react-preact/#queries} for `useQuery` docs. 237 + * 238 + * @example 239 + * ```ts 240 + * import { gql, useQuery } from '@urql/preact'; 241 + * 242 + * const TodosQuery = gql` 243 + * query { todos { id, title } } 244 + * `; 245 + * 246 + * const Todos = () => { 247 + * const [result, reexecuteQuery] = useQuery({ 248 + * query: TodosQuery, 249 + * variables: {}, 250 + * }); 251 + * // ... 252 + * }; 253 + * ``` 254 + */ 101 255 export function useQuery< 102 256 Data = any, 103 257 Variables extends AnyVariables = AnyVariables
+3 -1
packages/preact-urql/src/hooks/useRequest.ts
··· 7 7 createRequest, 8 8 } from '@urql/core'; 9 9 10 - /** Creates a request from a query and variables but preserves reference equality if the key isn't changing */ 10 + /** Creates a request from a query and variables but preserves reference equality if the key isn't changing 11 + * @internal 12 + */ 11 13 export function useRequest< 12 14 Data = any, 13 15 Variables extends AnyVariables = AnyVariables
+175 -4
packages/preact-urql/src/hooks/useSubscription.ts
··· 14 14 import { useRequest } from './useRequest'; 15 15 import { initialState } from './constants'; 16 16 17 + /** Input arguments for the {@link useSubscription} hook. 18 + * 19 + * @param query - The GraphQL subscription document that `useSubscription` executes. 20 + * @param variables - The variables for the GraphQL subscription that `useSubscription` executes. 21 + */ 17 22 export type UseSubscriptionArgs< 18 23 Variables extends AnyVariables = AnyVariables, 19 24 Data = any 20 25 > = { 26 + /** Prevents {@link useSubscription} from automatically starting GraphQL subscriptions. 27 + * 28 + * @remarks 29 + * `pause` may be set to `true` to stop {@link useSubscription} from starting its subscription 30 + * automatically. The hook will stop receiving updates from the {@link Client} 31 + * and won’t start the subscription operation, until either it’s set to `false` 32 + * or the {@link UseSubscriptionExecute} function is called. 33 + */ 21 34 pause?: boolean; 35 + /** Updates the {@link OperationContext} for the executed GraphQL subscription operation. 36 + * 37 + * @remarks 38 + * `context` may be passed to {@link useSubscription}, to update the {@link OperationContext} 39 + * of a subscription operation. This may be used to update the `context` that exchanges 40 + * will receive for a single hook. 41 + * 42 + * Hint: This should be wrapped in a `useMemo` hook, to make sure that your 43 + * component doesn’t infinitely update. 44 + * 45 + * @example 46 + * ```ts 47 + * const [result, reexecute] = useSubscription({ 48 + * query, 49 + * context: useMemo(() => ({ 50 + * additionalTypenames: ['Item'], 51 + * }), []) 52 + * }); 53 + * ``` 54 + */ 22 55 context?: Partial<OperationContext>; 23 56 } & GraphQLRequestParams<Data, Variables>; 24 57 58 + /** Combines previous data with an incoming subscription result’s data. 59 + * 60 + * @remarks 61 + * A `SubscriptionHandler` may be passed to {@link useSubscription} to 62 + * aggregate subscription results into a combined {@link UseSubscriptionState.data} 63 + * value. 64 + * 65 + * This is useful when a subscription event delivers a single item, while 66 + * you’d like to display a list of events. 67 + * 68 + * @example 69 + * ```ts 70 + * const NotificationsSubscription = gql` 71 + * subscription { newNotification { id, text } } 72 + * `; 73 + * 74 + * const combineNotifications = (notifications = [], data) => { 75 + * return [...notifications, data.newNotification]; 76 + * }; 77 + * 78 + * const [result, executeSubscription] = useSubscription( 79 + * { query: NotificationsSubscription }, 80 + * combineNotifications, 81 + * ); 82 + * ``` 83 + */ 25 84 export type SubscriptionHandler<T, R> = (prev: R | undefined, data: T) => R; 26 85 86 + /** State of the current subscription, your {@link useSubscription} hook is executing. 87 + * 88 + * @remarks 89 + * `UseSubscriptionState` is returned (in a tuple) by {@link useSubscription} and 90 + * gives you the updating {@link OperationResult} of GraphQL subscriptions. 91 + * 92 + * If a {@link SubscriptionHandler} has been passed to `useSubscription` then 93 + * {@link UseSubscriptionState.data} is instead the updated data as returned 94 + * by the handler, otherwise it’s the latest result’s data. 95 + * 96 + * Hint: Even when the query and variables passed to {@link useSubscription} change, 97 + * this state preserves the prior state. 98 + */ 27 99 export interface UseSubscriptionState< 28 100 Data = any, 29 101 Variables extends AnyVariables = AnyVariables 30 102 > { 103 + /** Indicates whether `useSubscription`’s subscription is active. 104 + * 105 + * @remarks 106 + * When `useSubscription` starts a subscription, the `fetching` flag 107 + * is set to `true` and will remain `true` until the subscription 108 + * completes on the API, or the {@link UseSubscriptionArgs.pause} 109 + * flag is set to `true`. 110 + */ 31 111 fetching: boolean; 112 + /** Indicates that the subscription result is not fresh. 113 + * 114 + * @remarks 115 + * This is mostly unused for subscriptions and will rarely affect you, and 116 + * is more relevant for queries. 117 + * 118 + * @see {@link OperationResult.stale} for the source of this value. 119 + */ 32 120 stale: boolean; 121 + /** The {@link OperationResult.data} for the executed subscription, or data returned by a handler. 122 + * 123 + * @remarks 124 + * `data` will be set to the last {@link OperationResult.data} value 125 + * received for the subscription. 126 + * 127 + * It will instead be set to the values that {@link SubscriptionHandler} 128 + * returned, if a handler has been passed to {@link useSubscription}. 129 + */ 33 130 data?: Data; 131 + /** The {@link OperationResult.error} for the executed subscription. */ 34 132 error?: CombinedError; 133 + /** The {@link OperationResult.extensions} for the executed mutation. */ 35 134 extensions?: Record<string, any>; 135 + /** The {@link Operation} that the current state is for. 136 + * 137 + * @remarks 138 + * This is the subscription {@link Operation} that is currently active. 139 + * When {@link UseSubscriptionState.fetching} is `true`, this is the 140 + * last `Operation` that the current state was for. 141 + */ 36 142 operation?: Operation<Data, Variables>; 37 143 } 38 144 145 + /** Triggers {@link useSubscription} to reexecute a GraphQL subscription operation. 146 + * 147 + * @param opts - optionally, context options that will be merged with the hook's 148 + * {@link UseSubscriptionArgs.context} options and the `Client`’s options. 149 + * 150 + * @remarks 151 + * When called, {@link useSubscription} will restart the GraphQL subscription 152 + * operation it currently holds. If {@link UseSubscriptionArgs.pause} is set 153 + * to `true`, it will start executing the subscription. 154 + * 155 + * ```ts 156 + * const [result, executeSubscription] = useSubscription({ 157 + * query, 158 + * pause: true, 159 + * }); 160 + * 161 + * const start = () => { 162 + * executeSubscription(); 163 + * }; 164 + * ``` 165 + */ 166 + export type UseSubscriptionExecute = (opts?: Partial<OperationContext>) => void; 167 + 168 + /** Result tuple returned by the {@link useSubscription} hook. 169 + * 170 + * @remarks 171 + * Similarly to a `useState` hook’s return value, 172 + * the first element is the {@link useSubscription}’s state, 173 + * a {@link UseSubscriptionState} object, 174 + * and the second is used to imperatively re-execute or start the subscription 175 + * via a {@link UseMutationExecute} function. 176 + */ 39 177 export type UseSubscriptionResponse< 40 178 Data = any, 41 179 Variables extends AnyVariables = AnyVariables 42 - > = [ 43 - UseSubscriptionState<Data, Variables>, 44 - (opts?: Partial<OperationContext>) => void 45 - ]; 180 + > = [UseSubscriptionState<Data, Variables>, UseSubscriptionExecute]; 46 181 182 + /** Hook to run a GraphQL subscription and get updated GraphQL results. 183 + * 184 + * @param args - a {@link UseSubscriptionArgs} object, to pass a `query`, `variables`, and options. 185 + * @param handler - optionally, a {@link SubscriptionHandler} function to combine multiple subscription results. 186 + * @returns a {@link UseSubscriptionResponse} tuple of a {@link UseSubscriptionState} result, and an execute function. 187 + * 188 + * @remarks 189 + * `useSubscription` allows GraphQL subscriptions to be defined and executed. 190 + * Given {@link UseSubscriptionArgs.query}, it executes the GraphQL subscription with the 191 + * context’s {@link Client}. 192 + * 193 + * The returned result updates when the `Client` has new results 194 + * for the subscription, and `data` is updated with the result’s data 195 + * or with the `data` that a `handler` returns. 196 + * 197 + * @example 198 + * ```ts 199 + * import { gql, useSubscription } from '@urql/preact'; 200 + * 201 + * const NotificationsSubscription = gql` 202 + * subscription { newNotification { id, text } } 203 + * `; 204 + * 205 + * const combineNotifications = (notifications = [], data) => { 206 + * return [...notifications, data.newNotification]; 207 + * }; 208 + * 209 + * const Notifications = () => { 210 + * const [result, executeSubscription] = useSubscription( 211 + * { query: NotificationsSubscription }, 212 + * combineNotifications, 213 + * ); 214 + * // ... 215 + * }; 216 + * ``` 217 + */ 47 218 export function useSubscription< 48 219 Data = any, 49 220 Result = Data,
+30 -12
packages/react-urql/src/components/Mutation.ts
··· 1 1 import { DocumentNode } from 'graphql'; 2 2 import { ReactElement } from 'react'; 3 - import { 4 - AnyVariables, 5 - TypedDocumentNode, 6 - OperationResult, 7 - OperationContext, 8 - } from '@urql/core'; 9 - import { useMutation, UseMutationState } from '../hooks'; 3 + import { AnyVariables, TypedDocumentNode } from '@urql/core'; 4 + 5 + import { useMutation, UseMutationState, UseMutationExecute } from '../hooks'; 10 6 7 + /** Props accepted by {@link Mutation}. 8 + * 9 + * @remarks 10 + * `MutationProps` are the props accepted by the {@link Mutation} component. 11 + * 12 + * The result, the {@link MutationState} object, will be passed to 13 + * a {@link MutationProps.children} function, passed as children 14 + * to the `Mutation` component. 15 + */ 11 16 export interface MutationProps< 12 17 Data = any, 13 18 Variables extends AnyVariables = AnyVariables 14 19 > { 20 + /* The GraphQL mutation document that {@link useMutation} will execute. */ 15 21 query: DocumentNode | TypedDocumentNode<Data, Variables> | string; 16 - children: (arg: MutationState<Data, Variables>) => ReactElement<any>; 22 + children(arg: MutationState<Data, Variables>): ReactElement<any>; 17 23 } 18 24 25 + /** Object that {@link MutationProps.children} is called with. 26 + * 27 + * @remarks 28 + * This is an extented {@link UseMutationstate} with an added 29 + * {@link MutationState.executeMutation} method, which is usually 30 + * part of a tuple returned by {@link useMutation}. 31 + */ 19 32 export interface MutationState< 20 33 Data = any, 21 34 Variables extends AnyVariables = AnyVariables 22 35 > extends UseMutationState<Data, Variables> { 23 - executeMutation: ( 24 - variables: Variables, 25 - context?: Partial<OperationContext> 26 - ) => Promise<OperationResult<Data, Variables>>; 36 + /** Alias to {@link useMutation}’s `executeMutation` function. */ 37 + executeMutation: UseMutationExecute<Data, Variables>; 27 38 } 28 39 40 + /** Component Wrapper around {@link useMutation} to run a GraphQL query. 41 + * 42 + * @remarks 43 + * `Mutation` is a component wrapper around the {@link useMutation} hook 44 + * that calls the {@link MutationProps.children} prop, as a function, 45 + * with the {@link MutationState} object. 46 + */ 29 47 export function Mutation< 30 48 Data = any, 31 49 Variables extends AnyVariables = AnyVariables
+35 -4
packages/react-urql/src/components/Query.ts
··· 1 1 import { ReactElement } from 'react'; 2 - import { AnyVariables, OperationContext } from '@urql/core'; 3 - import { useQuery, UseQueryArgs, UseQueryState } from '../hooks'; 2 + import { AnyVariables } from '@urql/core'; 3 + 4 + import { 5 + useQuery, 6 + UseQueryArgs, 7 + UseQueryState, 8 + UseQueryExecute, 9 + } from '../hooks'; 4 10 11 + /** Props accepted by {@link Query}. 12 + * 13 + * @remarks 14 + * `QueryProps` are the props accepted by the {@link Query} component, 15 + * which is identical to {@link UseQueryArgs}. 16 + * 17 + * The result, the {@link QueryState} object, will be passed to 18 + * a {@link QueryProps.children} function, passed as children 19 + * to the `Query` component. 20 + */ 5 21 export type QueryProps< 6 22 Data = any, 7 23 Variables extends AnyVariables = AnyVariables 8 24 > = UseQueryArgs<Variables, Data> & { 9 - children: (arg: QueryState<Data, Variables>) => ReactElement<any>; 25 + children(arg: QueryState<Data, Variables>): ReactElement<any>; 10 26 }; 11 27 28 + /** Object that {@link QueryProps.children} is called with. 29 + * 30 + * @remarks 31 + * This is an extented {@link UseQueryState} with an added 32 + * {@link QueryState.executeQuery} method, which is usually 33 + * part of a tuple returned by {@link useQuery}. 34 + */ 12 35 export interface QueryState< 13 36 Data = any, 14 37 Variables extends AnyVariables = AnyVariables 15 38 > extends UseQueryState<Data, Variables> { 16 - executeQuery: (opts?: Partial<OperationContext>) => void; 39 + /** Alias to {@link useQuery}’s `executeQuery` function. */ 40 + executeQuery: UseQueryExecute; 17 41 } 18 42 43 + /** Component Wrapper around {@link useQuery} to run a GraphQL query. 44 + * 45 + * @remarks 46 + * `Query` is a component wrapper around the {@link useQuery} hook 47 + * that calls the {@link QueryProps.children} prop, as a function, 48 + * with the {@link QueryState} object. 49 + */ 19 50 export function Query< 20 51 Data = any, 21 52 Variables extends AnyVariables = AnyVariables
+31 -3
packages/react-urql/src/components/Subscription.ts
··· 1 1 import { ReactElement } from 'react'; 2 - import { AnyVariables, OperationContext } from '@urql/core'; 2 + import { AnyVariables } from '@urql/core'; 3 3 4 4 import { 5 5 useSubscription, 6 6 UseSubscriptionArgs, 7 7 UseSubscriptionState, 8 + UseSubscriptionExecute, 8 9 SubscriptionHandler, 9 10 } from '../hooks'; 10 11 12 + /** Props accepted by {@link Subscription}. 13 + * 14 + * @remarks 15 + * `SubscriptionProps` are the props accepted by the {@link Subscription} component, 16 + * which is identical to {@link UseSubscriptionArgs} with an added 17 + * {@link SubscriptionProps.handler} prop, which {@link useSubscription} usually 18 + * accepts as an additional argument. 19 + * 20 + * The result, the {@link SubscriptionState} object, will be passed to 21 + * a {@link SubscriptionProps.children} function, passed as children 22 + * to the `Subscription` component. 23 + */ 11 24 export type SubscriptionProps< 12 25 Data = any, 13 26 Result = Data, 14 27 Variables extends AnyVariables = AnyVariables 15 28 > = UseSubscriptionArgs<Variables, Data> & { 16 29 handler?: SubscriptionHandler<Data, Result>; 17 - children: (arg: SubscriptionState<Result, Variables>) => ReactElement<any>; 30 + children(arg: SubscriptionState<Result, Variables>): ReactElement<any>; 18 31 }; 19 32 33 + /** Object that {@link SubscriptionProps.children} is called with. 34 + * 35 + * @remarks 36 + * This is an extented {@link UseSubscriptionState} with an added 37 + * {@link SubscriptionState.executeSubscription} method, which is usually 38 + * part of a tuple returned by {@link useSubscription}. 39 + */ 20 40 export interface SubscriptionState< 21 41 Data = any, 22 42 Variables extends AnyVariables = AnyVariables 23 43 > extends UseSubscriptionState<Data, Variables> { 24 - executeSubscription: (opts?: Partial<OperationContext>) => void; 44 + /** Alias to {@link useSubscription}’s `executeMutation` function. */ 45 + executeSubscription: UseSubscriptionExecute; 25 46 } 26 47 48 + /** Component Wrapper around {@link useSubscription} to run a GraphQL subscription. 49 + * 50 + * @remarks 51 + * `Subscription` is a component wrapper around the {@link useSubscription} hook 52 + * that calls the {@link SubscriptionProps.children} prop, as a function, 53 + * with the {@link SubscriptionState} object. 54 + */ 27 55 export function Subscription< 28 56 Data = any, 29 57 Result = Data,
+53
packages/react-urql/src/context.ts
··· 2 2 import { Client } from '@urql/core'; 3 3 4 4 const OBJ = {}; 5 + 6 + /** `urql`'s React Context. 7 + * 8 + * @remarks 9 + * The React Context that `urql`’s {@link Client} will be provided with. 10 + * You may use the reexported {@link Provider} to provide a `Client` as well. 11 + */ 5 12 export const Context: import('react').Context<Client | object> = 6 13 createContext(OBJ); 14 + 15 + /** Provider for `urql`'s {@link Client} to GraphQL hooks. 16 + * 17 + * @remarks 18 + * `Provider` accepts a {@link Client} and provides it to all GraphQL hooks, 19 + * and {@link useClient}. 20 + * 21 + * You should make sure to create a {@link Client} and provide it with the 22 + * `Provider` to parts of your component tree that use GraphQL hooks. 23 + * 24 + * @example 25 + * ```tsx 26 + * import { Provider } from 'urql'; 27 + * // All of `@urql/core` is also re-exported by `urql`: 28 + * import { Client, cacheExchange, fetchExchange } from '@urql/core'; 29 + * 30 + * const client = new Client({ 31 + * url: 'https://API', 32 + * exchanges: [cacheExchange, fetchExchange], 33 + * }); 34 + * 35 + * const App = () => ( 36 + * <Provider value={client}> 37 + * <Component /> 38 + * </Provider> 39 + * ); 40 + * ``` 41 + */ 7 42 export const Provider: import('react').Provider<Client | object> = 8 43 Context.Provider; 44 + 45 + /** React Consumer component, providing the {@link Client} provided on a parent component. 46 + * @remarks 47 + * This is an alias for {@link Context.Consumer}. 48 + */ 9 49 export const Consumer: import('react').Consumer<Client | object> = 10 50 Context.Consumer; 11 51 12 52 Context.displayName = 'UrqlContext'; 13 53 54 + /** Hook returning a {@link Client} from {@link Context}. 55 + * 56 + * @remarks 57 + * `useClient` is a convenience hook, which accesses `urql`'s {@link Context} 58 + * and returns the {@link Client} defined on it. 59 + * 60 + * This will be the {@link Client} you passed to a {@link Provider} 61 + * you wrapped your elements containing this hook with. 62 + * 63 + * @throws 64 + * In development, if the component you call `useClient()` in is 65 + * not wrapped in a {@link Provider}, an error is thrown. 66 + */ 14 67 export const useClient = (): Client => { 15 68 const client = useContext(Context); 16 69
+110 -7
packages/react-urql/src/hooks/useMutation.ts
··· 15 15 import { useClient } from '../context'; 16 16 import { initialState } from './state'; 17 17 18 + /** State of the last mutation executed by your {@link useMutation} hook. 19 + * 20 + * @remarks 21 + * `UseMutationState` is returned (in a tuple) by {@link useMutation} and 22 + * gives you the {@link OperationResult} of the last mutation executed 23 + * with {@link UseMutationExecute}. 24 + * 25 + * Even if the mutation document passed to {@link useMutation} changes, 26 + * the state isn’t reset, so you can keep displaying the previous result. 27 + */ 18 28 export interface UseMutationState< 19 29 Data = any, 20 30 Variables extends AnyVariables = AnyVariables 21 31 > { 32 + /** Indicates whether `useMutation` is currently executing a mutation. */ 22 33 fetching: boolean; 34 + /** Indicates that the mutation result is not fresh. 35 + * 36 + * @remarks 37 + * The `stale` flag is set to `true` when a new result for the mutation 38 + * is expected. 39 + * This is mostly unused for mutations and will rarely affect you, and 40 + * is more relevant for queries. 41 + * 42 + * @see {@link OperationResult.stale} for the source of this value. 43 + */ 23 44 stale: boolean; 45 + /** The {@link OperationResult.data} for the executed mutation. */ 24 46 data?: Data; 47 + /** The {@link OperationResult.error} for the executed mutation. */ 25 48 error?: CombinedError; 49 + /** The {@link OperationResult.extensions} for the executed mutation. */ 26 50 extensions?: Record<string, any>; 51 + /** The {@link Operation} that the current state is for. 52 + * 53 + * @remarks 54 + * This is the mutation {@link Operation} that has last been executed. 55 + * When {@link UseQueryState.fetching} is `true`, this is the 56 + * last `Operation` that the current state was for. 57 + */ 27 58 operation?: Operation<Data, Variables>; 28 59 } 29 60 61 + /** Triggers {@link useMutation} to execute its GraphQL mutation operation. 62 + * 63 + * @param variables - variables using which the mutation will be executed. 64 + * @param context - optionally, context options that will be merged with the hook's 65 + * {@link UseQueryArgs.context} options and the `Client`’s options. 66 + * @returns the {@link OperationResult} of the mutation. 67 + * 68 + * @remarks 69 + * When called, {@link useMutation} will start the GraphQL mutation 70 + * it currently holds and use the `variables` passed to it. 71 + * 72 + * Once the mutation response comes back from the API, its 73 + * returned promise will resolve to the mutation’s {@link OperationResult} 74 + * and the {@link UseMutationState} will be updated with the result. 75 + * 76 + * @example 77 + * ```ts 78 + * const [result, executeMutation] = useMutation(UpdateTodo); 79 + * const start = async ({ id, title }) => { 80 + * const result = await executeMutation({ id, title }); 81 + * }; 82 + */ 83 + export type UseMutationExecute< 84 + Data = any, 85 + Variables extends AnyVariables = AnyVariables 86 + > = ( 87 + variables: Variables, 88 + context?: Partial<OperationContext> 89 + ) => Promise<OperationResult<Data, Variables>>; 90 + 91 + /** Result tuple returned by the {@link useMutation} hook. 92 + * 93 + * @remarks 94 + * Similarly to a `useState` hook’s return value, 95 + * the first element is the {@link useMutation}’s state, updated 96 + * as mutations are executed with the second value, which is 97 + * used to start mutations and is a {@link UseMutationExecute} 98 + * function. 99 + */ 30 100 export type UseMutationResponse< 31 101 Data = any, 32 102 Variables extends AnyVariables = AnyVariables 33 - > = [ 34 - UseMutationState<Data, Variables>, 35 - ( 36 - variables: Variables, 37 - context?: Partial<OperationContext> 38 - ) => Promise<OperationResult<Data, Variables>> 39 - ]; 103 + > = [UseMutationState<Data, Variables>, UseMutationExecute<Data, Variables>]; 40 104 105 + /** Hook to create a GraphQL mutation, run by passing variables to the returned execute function. 106 + * 107 + * @param query - a GraphQL mutation document which `useMutation` will execute. 108 + * @returns a {@link UseMutationResponse} tuple of a {@link UseMutationState} result, 109 + * and an execute function to start the mutation. 110 + * 111 + * @remarks 112 + * `useMutation` allows GraphQL mutations to be defined and keeps its state 113 + * after the mutation is started with the returned execute function. 114 + * 115 + * Given a GraphQL mutation document it returns state to keep track of the 116 + * mutation state and a {@link UseMutationExecute} function, which accepts 117 + * variables for the mutation to be executed. 118 + * Once called, the mutation executes and the state will be updated with 119 + * the mutation’s result. 120 + * 121 + * @see {@link https://urql.dev/goto/urql/docs/basics/react-preact/#mutations} for `useMutation` docs. 122 + * 123 + * @example 124 + * ```ts 125 + * import { gql, useMutation } from 'urql'; 126 + * 127 + * const UpdateTodo = gql` 128 + * mutation ($id: ID!, $title: String!) { 129 + * updateTodo(id: $id, title: $title) { 130 + * id, title 131 + * } 132 + * } 133 + * `; 134 + * 135 + * const UpdateTodo = () => { 136 + * const [result, executeMutation] = useMutation(UpdateTodo); 137 + * const start = async ({ id, title }) => { 138 + * const result = await executeMutation({ id, title }); 139 + * }; 140 + * // ... 141 + * }; 142 + * ``` 143 + */ 41 144 export function useMutation< 42 145 Data = any, 43 146 Variables extends AnyVariables = AnyVariables
+159 -4
packages/react-urql/src/hooks/useQuery.ts
··· 19 19 import { getCacheForClient } from './cache'; 20 20 import { initialState, computeNextState, hasDepsChanged } from './state'; 21 21 22 + /** Input arguments for the {@link useQuery} hook. 23 + * 24 + * @param query - The GraphQL query that `useQuery` executes. 25 + * @param variables - The variables for the GraphQL query that `useQuery` executes. 26 + */ 22 27 export type UseQueryArgs< 23 28 Variables extends AnyVariables = AnyVariables, 24 29 Data = any 25 30 > = { 31 + /** Updates the {@link RequestPolicy} for the executed GraphQL query operation. 32 + * 33 + * @remarks 34 + * `requestPolicy` modifies the {@link RequestPolicy} of the GraphQL query operation 35 + * that `useQuery` executes, and indicates a caching strategy for cache exchanges. 36 + * 37 + * For example, when set to `'cache-and-network'`, {@link useQuery} will 38 + * receive a cached result with `stale: true` and an API request will be 39 + * sent in the background. 40 + * 41 + * @see {@link OperationContext.requestPolicy} for where this value is set. 42 + */ 26 43 requestPolicy?: RequestPolicy; 44 + /** Updates the {@link OperationContext} for the executed GraphQL query operation. 45 + * 46 + * @remarks 47 + * `context` may be passed to {@link useQuery}, to update the {@link OperationContext} 48 + * of a query operation. This may be used to update the `context` that exchanges 49 + * will receive for a single hook. 50 + * 51 + * Hint: This should be wrapped in a `useMemo` hook, to make sure that your 52 + * component doesn’t infinitely update. 53 + * 54 + * @example 55 + * ```ts 56 + * const [result, reexecute] = useQuery({ 57 + * query, 58 + * context: useMemo(() => ({ 59 + * additionalTypenames: ['Item'], 60 + * }), []) 61 + * }); 62 + * ``` 63 + */ 27 64 context?: Partial<OperationContext>; 65 + /** Prevents {@link useQuery} from automatically executing GraphQL query operations. 66 + * 67 + * @remarks 68 + * `pause` may be set to `true` to stop {@link useQuery} from executing 69 + * automatically. The hook will stop receiving updates from the {@link Client} 70 + * and won’t execute the query operation, until either it’s set to `false` 71 + * or the {@link UseQueryExecute} function is called. 72 + * 73 + * @see {@link https://urql.dev/goto/docs/basics/react-preact/#pausing-usequery} for 74 + * documentation on the `pause` option. 75 + */ 28 76 pause?: boolean; 29 77 } & GraphQLRequestParams<Data, Variables>; 30 78 79 + /** State of the current query, your {@link useQuery} hook is executing. 80 + * 81 + * @remarks 82 + * `UseQueryState` is returned (in a tuple) by {@link useQuery} and 83 + * gives you the updating {@link OperationResult} of GraphQL queries. 84 + * 85 + * Even when the query and variables passed to {@link useQuery} change, 86 + * this state preserves the prior state and sets the `fetching` flag to 87 + * `true`. 88 + * This allows you to display the previous state, while implementing 89 + * a separate loading indicator separately. 90 + */ 31 91 export interface UseQueryState< 32 92 Data = any, 33 93 Variables extends AnyVariables = AnyVariables 34 94 > { 95 + /** Indicates whether `useQuery` is waiting for a new result. 96 + * 97 + * @remarks 98 + * When `useQuery` is passed a new query and/or variables, it will 99 + * start executing the new query operation and `fetching` is set to 100 + * `true` until a result arrives. 101 + * 102 + * Hint: This is subtly different than whether the query is actually 103 + * fetching, and doesn’t indicate whether a query is being re-executed 104 + * in the background. For this, see {@link UseQueryState.stale}. 105 + */ 35 106 fetching: boolean; 107 + /** Indicates that the state is not fresh and a new result will follow. 108 + * 109 + * @remarks 110 + * The `stale` flag is set to `true` when a new result for the query 111 + * is expected and `useQuery` is waiting for it. This may indicate that 112 + * a new request is being requested in the background. 113 + * 114 + * @see {@link OperationResult.stale} for the source of this value. 115 + */ 36 116 stale: boolean; 117 + /** The {@link OperationResult.data} for the executed query. */ 37 118 data?: Data; 119 + /** The {@link OperationResult.error} for the executed query. */ 38 120 error?: CombinedError; 121 + /** The {@link OperationResult.extensions} for the executed query. */ 39 122 extensions?: Record<string, any>; 123 + /** The {@link Operation} that the current state is for. 124 + * 125 + * @remarks 126 + * This is the {@link Operation} that is currently being executed. 127 + * When {@link UseQueryState.fetching} is `true`, this is the 128 + * last `Operation` that the current state was for. 129 + */ 40 130 operation?: Operation<Data, Variables>; 41 131 } 42 132 133 + /** Triggers {@link useQuery} to execute a new GraphQL query operation. 134 + * 135 + * @param opts - optionally, context options that will be merged with the hook's 136 + * {@link UseQueryArgs.context} options and the `Client`’s options. 137 + * 138 + * @remarks 139 + * When called, {@link useQuery} will re-execute the GraphQL query operation 140 + * it currently holds, even if {@link UseQueryArgs.pause} is set to `true`. 141 + * 142 + * This is useful for executing a paused query or re-executing a query 143 + * and get a new network result, by passing a new request policy. 144 + * 145 + * ```ts 146 + * const [result, reexecuteQuery] = useQuery({ query }); 147 + * 148 + * const refresh = () => { 149 + * // Re-execute the query with a network-only policy, skipping the cache 150 + * reexecuteQuery({ requestPolicy: 'network-only' }); 151 + * }; 152 + * ``` 153 + */ 154 + export type UseQueryExecute = (opts?: Partial<OperationContext>) => void; 155 + 156 + /** Result tuple returned by the {@link useQuery} hook. 157 + * 158 + * @remarks 159 + * Similarly to a `useState` hook’s return value, 160 + * the first element is the {@link useQuery}’s result and state, 161 + * a {@link UseQueryState} object, 162 + * and the second is used to imperatively re-execute the query 163 + * via a {@link UseQueryExecute} function. 164 + */ 43 165 export type UseQueryResponse< 44 166 Data = any, 45 167 Variables extends AnyVariables = AnyVariables 46 - > = [ 47 - UseQueryState<Data, Variables>, 48 - (opts?: Partial<OperationContext>) => void 49 - ]; 168 + > = [UseQueryState<Data, Variables>, UseQueryExecute]; 50 169 51 170 const isSuspense = (client: Client, context?: Partial<OperationContext>) => 52 171 client.suspense && (!context || context.suspense !== false); 53 172 173 + /** Hook to run a GraphQL query and get updated GraphQL results. 174 + * 175 + * @param args - a {@link UseQueryArgs} object, to pass a `query`, `variables`, and options. 176 + * @returns a {@link UseQueryResponse} tuple of a {@link UseQueryState} result, and re-execute function. 177 + * 178 + * @remarks 179 + * `useQuery` allows GraphQL queries to be defined and executed. 180 + * Given {@link UseQueryArgs.query}, it executes the GraphQL query with the 181 + * context’s {@link Client}. 182 + * 183 + * The returned result updates when the `Client` has new results 184 + * for the query, and changes when your input `args` change. 185 + * 186 + * Additionally, if the `suspense` option is enabled on the `Client`, 187 + * the `useQuery` hook will suspend instead of indicating that it’s 188 + * waiting for a result via {@link UseQueryState.fetching}. 189 + * 190 + * @see {@link https://urql.dev/goto/urql/docs/basics/react-preact/#queries} for `useQuery` docs. 191 + * 192 + * @example 193 + * ```ts 194 + * import { gql, useQuery } from 'urql'; 195 + * 196 + * const TodosQuery = gql` 197 + * query { todos { id, title } } 198 + * `; 199 + * 200 + * const Todos = () => { 201 + * const [result, reexecuteQuery] = useQuery({ 202 + * query: TodosQuery, 203 + * variables: {}, 204 + * }); 205 + * // ... 206 + * }; 207 + * ``` 208 + */ 54 209 export function useQuery< 55 210 Data = any, 56 211 Variables extends AnyVariables = AnyVariables
+3 -1
packages/react-urql/src/hooks/useRequest.ts
··· 7 7 createRequest, 8 8 } from '@urql/core'; 9 9 10 - /** Creates a request from a query and variables but preserves reference equality if the key isn't changing */ 10 + /** Creates a request from a query and variables but preserves reference equality if the key isn't changing 11 + * @internal 12 + */ 11 13 export function useRequest< 12 14 Data = any, 13 15 Variables extends AnyVariables = AnyVariables
+175 -4
packages/react-urql/src/hooks/useSubscription.ts
··· 15 15 import { useRequest } from './useRequest'; 16 16 import { initialState, computeNextState, hasDepsChanged } from './state'; 17 17 18 + /** Input arguments for the {@link useSubscription} hook. 19 + * 20 + * @param query - The GraphQL subscription document that `useSubscription` executes. 21 + * @param variables - The variables for the GraphQL subscription that `useSubscription` executes. 22 + */ 18 23 export type UseSubscriptionArgs< 19 24 Variables extends AnyVariables = AnyVariables, 20 25 Data = any 21 26 > = { 27 + /** Prevents {@link useSubscription} from automatically starting GraphQL subscriptions. 28 + * 29 + * @remarks 30 + * `pause` may be set to `true` to stop {@link useSubscription} from starting its subscription 31 + * automatically. The hook will stop receiving updates from the {@link Client} 32 + * and won’t start the subscription operation, until either it’s set to `false` 33 + * or the {@link UseSubscriptionExecute} function is called. 34 + */ 22 35 pause?: boolean; 36 + /** Updates the {@link OperationContext} for the executed GraphQL subscription operation. 37 + * 38 + * @remarks 39 + * `context` may be passed to {@link useSubscription}, to update the {@link OperationContext} 40 + * of a subscription operation. This may be used to update the `context` that exchanges 41 + * will receive for a single hook. 42 + * 43 + * Hint: This should be wrapped in a `useMemo` hook, to make sure that your 44 + * component doesn’t infinitely update. 45 + * 46 + * @example 47 + * ```ts 48 + * const [result, reexecute] = useSubscription({ 49 + * query, 50 + * context: useMemo(() => ({ 51 + * additionalTypenames: ['Item'], 52 + * }), []) 53 + * }); 54 + * ``` 55 + */ 23 56 context?: Partial<OperationContext>; 24 57 } & GraphQLRequestParams<Data, Variables>; 25 58 59 + /** Combines previous data with an incoming subscription result’s data. 60 + * 61 + * @remarks 62 + * A `SubscriptionHandler` may be passed to {@link useSubscription} to 63 + * aggregate subscription results into a combined {@link UseSubscriptionState.data} 64 + * value. 65 + * 66 + * This is useful when a subscription event delivers a single item, while 67 + * you’d like to display a list of events. 68 + * 69 + * @example 70 + * ```ts 71 + * const NotificationsSubscription = gql` 72 + * subscription { newNotification { id, text } } 73 + * `; 74 + * 75 + * const combineNotifications = (notifications = [], data) => { 76 + * return [...notifications, data.newNotification]; 77 + * }; 78 + * 79 + * const [result, executeSubscription] = useSubscription( 80 + * { query: NotificationsSubscription }, 81 + * combineNotifications, 82 + * ); 83 + * ``` 84 + */ 26 85 export type SubscriptionHandler<T, R> = (prev: R | undefined, data: T) => R; 27 86 87 + /** State of the current subscription, your {@link useSubscription} hook is executing. 88 + * 89 + * @remarks 90 + * `UseSubscriptionState` is returned (in a tuple) by {@link useSubscription} and 91 + * gives you the updating {@link OperationResult} of GraphQL subscriptions. 92 + * 93 + * If a {@link SubscriptionHandler} has been passed to `useSubscription` then 94 + * {@link UseSubscriptionState.data} is instead the updated data as returned 95 + * by the handler, otherwise it’s the latest result’s data. 96 + * 97 + * Hint: Even when the query and variables passed to {@link useSubscription} change, 98 + * this state preserves the prior state. 99 + */ 28 100 export interface UseSubscriptionState< 29 101 Data = any, 30 102 Variables extends AnyVariables = AnyVariables 31 103 > { 104 + /** Indicates whether `useSubscription`’s subscription is active. 105 + * 106 + * @remarks 107 + * When `useSubscription` starts a subscription, the `fetching` flag 108 + * is set to `true` and will remain `true` until the subscription 109 + * completes on the API, or the {@link UseSubscriptionArgs.pause} 110 + * flag is set to `true`. 111 + */ 32 112 fetching: boolean; 113 + /** Indicates that the subscription result is not fresh. 114 + * 115 + * @remarks 116 + * This is mostly unused for subscriptions and will rarely affect you, and 117 + * is more relevant for queries. 118 + * 119 + * @see {@link OperationResult.stale} for the source of this value. 120 + */ 33 121 stale: boolean; 122 + /** The {@link OperationResult.data} for the executed subscription, or data returned by a handler. 123 + * 124 + * @remarks 125 + * `data` will be set to the last {@link OperationResult.data} value 126 + * received for the subscription. 127 + * 128 + * It will instead be set to the values that {@link SubscriptionHandler} 129 + * returned, if a handler has been passed to {@link useSubscription}. 130 + */ 34 131 data?: Data; 132 + /** The {@link OperationResult.error} for the executed subscription. */ 35 133 error?: CombinedError; 134 + /** The {@link OperationResult.extensions} for the executed mutation. */ 36 135 extensions?: Record<string, any>; 136 + /** The {@link Operation} that the current state is for. 137 + * 138 + * @remarks 139 + * This is the subscription {@link Operation} that is currently active. 140 + * When {@link UseSubscriptionState.fetching} is `true`, this is the 141 + * last `Operation` that the current state was for. 142 + */ 37 143 operation?: Operation<Data, Variables>; 38 144 } 39 145 146 + /** Triggers {@link useSubscription} to reexecute a GraphQL subscription operation. 147 + * 148 + * @param opts - optionally, context options that will be merged with the hook's 149 + * {@link UseSubscriptionArgs.context} options and the `Client`’s options. 150 + * 151 + * @remarks 152 + * When called, {@link useSubscription} will restart the GraphQL subscription 153 + * operation it currently holds. If {@link UseSubscriptionArgs.pause} is set 154 + * to `true`, it will start executing the subscription. 155 + * 156 + * ```ts 157 + * const [result, executeSubscription] = useSubscription({ 158 + * query, 159 + * pause: true, 160 + * }); 161 + * 162 + * const start = () => { 163 + * executeSubscription(); 164 + * }; 165 + * ``` 166 + */ 167 + export type UseSubscriptionExecute = (opts?: Partial<OperationContext>) => void; 168 + 169 + /** Result tuple returned by the {@link useSubscription} hook. 170 + * 171 + * @remarks 172 + * Similarly to a `useState` hook’s return value, 173 + * the first element is the {@link useSubscription}’s state, 174 + * a {@link UseSubscriptionState} object, 175 + * and the second is used to imperatively re-execute or start the subscription 176 + * via a {@link UseMutationExecute} function. 177 + */ 40 178 export type UseSubscriptionResponse< 41 179 Data = any, 42 180 Variables extends AnyVariables = AnyVariables 43 - > = [ 44 - UseSubscriptionState<Data, Variables>, 45 - (opts?: Partial<OperationContext>) => void 46 - ]; 181 + > = [UseSubscriptionState<Data, Variables>, UseSubscriptionExecute]; 47 182 183 + /** Hook to run a GraphQL subscription and get updated GraphQL results. 184 + * 185 + * @param args - a {@link UseSubscriptionArgs} object, to pass a `query`, `variables`, and options. 186 + * @param handler - optionally, a {@link SubscriptionHandler} function to combine multiple subscription results. 187 + * @returns a {@link UseSubscriptionResponse} tuple of a {@link UseSubscriptionState} result, and an execute function. 188 + * 189 + * @remarks 190 + * `useSubscription` allows GraphQL subscriptions to be defined and executed. 191 + * Given {@link UseSubscriptionArgs.query}, it executes the GraphQL subscription with the 192 + * context’s {@link Client}. 193 + * 194 + * The returned result updates when the `Client` has new results 195 + * for the subscription, and `data` is updated with the result’s data 196 + * or with the `data` that a `handler` returns. 197 + * 198 + * @example 199 + * ```ts 200 + * import { gql, useSubscription } from 'urql'; 201 + * 202 + * const NotificationsSubscription = gql` 203 + * subscription { newNotification { id, text } } 204 + * `; 205 + * 206 + * const combineNotifications = (notifications = [], data) => { 207 + * return [...notifications, data.newNotification]; 208 + * }; 209 + * 210 + * const Notifications = () => { 211 + * const [result, executeSubscription] = useSubscription( 212 + * { query: NotificationsSubscription }, 213 + * combineNotifications, 214 + * ); 215 + * // ... 216 + * }; 217 + * ``` 218 + */ 48 219 export function useSubscription< 49 220 Data = any, 50 221 Result = Data,
+27 -3
packages/storage-rn/src/makeAsyncStorage.ts
··· 2 2 import AsyncStorage from '@react-native-async-storage/async-storage'; 3 3 import NetInfo from '@react-native-community/netinfo'; 4 4 5 - export type StorageOptions = { 5 + export interface StorageOptions { 6 + /** Name of the `AsyncStorage` key that’s used for persisted data. 7 + * @defaultValue `'graphcache-data'` 8 + */ 6 9 dataKey?: string; 10 + /** Name of the `AsyncStorage` key that’s used for persisted metadata. 11 + * @defaultValue `'graphcache-metadata'` 12 + */ 7 13 metadataKey?: string; 8 - maxAge?: number; // Number of days 9 - }; 14 + /** Maximum age of cache entries (in days) after which data is discarded. 15 + * @defaultValue `7` days 16 + */ 17 + maxAge?: number; 18 + } 10 19 11 20 const parseData = (persistedData: any, fallback: any) => { 12 21 try { ··· 20 29 21 30 let disconnect; 22 31 32 + /** React Native storage adapter persisting to `AsyncStorage`. */ 23 33 export interface DefaultAsyncStorage extends StorageAdapter { 34 + /** Clears the entire `AsyncStorage`. */ 24 35 clear(): Promise<any>; 25 36 } 26 37 38 + /** Creates a {@link StorageAdapter} which uses React Native’s `AsyncStorage`. 39 + * 40 + * @param opts - A {@link StorageOptions} configuration object. 41 + * @returns the created {@link DefaultAsyncStorage} adapter. 42 + * 43 + * @remarks 44 + * `makeAsyncStorage` creates a storage adapter for React Native, 45 + * which persisted to `AsyncStorage` via the `@react-native-async-storage/async-storage` 46 + * package. 47 + * 48 + * Note: We have no data on stability of this storage and our Offline Support 49 + * for large APIs or longterm use. Proceed with caution. 50 + */ 27 51 export const makeAsyncStorage: ( 28 52 ops?: StorageOptions 29 53 ) => DefaultAsyncStorage = ({
+64 -1
packages/svelte-urql/src/common.ts
··· 2 2 import type { AnyVariables, OperationResult } from '@urql/core'; 3 3 import { Source, make } from 'wonka'; 4 4 5 + /** An {@link OperationResult} with an added {@link OperationResultState.fetching} flag. 6 + * 7 + * @remarks 8 + * Stores will contain a readable state based on {@link OperationResult | OperationResults} 9 + * they received. 10 + */ 5 11 export interface OperationResultState< 6 12 Data = any, 7 13 Variables extends AnyVariables = AnyVariables 8 14 > extends OperationResult<Data, Variables> { 15 + /** Indicates whether the store is waiting for a new {@link OperationResult}. 16 + * 17 + * @remarks 18 + * When a store starts executing a GraphQL operation, `fetching` is 19 + * set to `true` until a result arrives. 20 + * 21 + * Hint: This is subtly different than whether the operation is actually 22 + * fetching, and doesn’t indicate whether an operation is being re-executed 23 + * in the background. For this, see {@link OperationResult.stale}. 24 + */ 9 25 fetching: boolean; 10 26 } 11 27 12 - /** A Readable containing an `OperationResult` with a fetching flag. */ 28 + /** A Readable store of {@link OperationResultState}. */ 13 29 export type OperationResultStore< 14 30 Data = any, 15 31 Variables extends AnyVariables = AnyVariables 16 32 > = Readable<OperationResultState<Data, Variables>>; 17 33 34 + /** Consumes a {@link Readable} as a {@link Source}. 35 + * @internal 36 + */ 18 37 export const fromStore = <T>(store$: Readable<T>): Source<T> => 19 38 make(observer => store$.subscribe(observer.next)); 20 39 ··· 28 47 stale: false, 29 48 }; 30 49 50 + /** A pausable Svelte store. 51 + * 52 + * @remarks 53 + * The {@link queryStore} and {@link useSubscription} store allow 54 + * you to pause execution and resume it later on, which is managed 55 + * by a `pause` option passed to them. 56 + * 57 + * A `Pauseable` allows execution of GraphQL operations to be paused, 58 + * which means a {@link OperationResultStore} won’t update with new 59 + * results or execute new operations, and to be resumed later on. 60 + */ 31 61 export interface Pausable { 62 + /** Indicates whether a store is currently paused. 63 + * 64 + * @remarks 65 + * When a {@link OperationResultStore} has been paused, it will stop 66 + * receiving updates from the {@link Client} and won’t execute GraphQL 67 + * operations, until this writable becomes `true` or 68 + * {@link Pausable.resume} is called. 69 + * 70 + * @see {@link https://urql.dev/goto/docs/basics/svelte#pausing-queries} for 71 + * documentation on the `Pausable`. 72 + */ 32 73 isPaused$: Writable<boolean>; 74 + /** Pauses a GraphQL operation to stop it from executing. 75 + * 76 + * @remarks 77 + * Pauses an {@link OperationResultStore}’s GraphQL operation, which 78 + * stops it from receiving updates from the {@link Client} and to stop 79 + * an ongoing operation. 80 + * 81 + * @see {@link https://urql.dev/goto/docs/basics/svelte#pausing-queries} for 82 + * documentation on the `Pausable`. 83 + */ 33 84 pause(): void; 85 + /** Resumes a paused GraphQL operation if it’s currently paused. 86 + * 87 + * @remarks 88 + * Resumes or starts {@link OperationResultStore}’s GraphQL operation, 89 + * if it’s currently paused. 90 + * 91 + * @see {@link https://urql.dev/goto/docs/basics/svelte#pausing-queries} for 92 + * documentation on the `Pausable`. 93 + */ 34 94 resume(): void; 35 95 } 36 96 97 + /** Creates a {@link Pausable}. 98 + * @internal 99 + */ 37 100 export const createPausable = (isPaused$: Writable<boolean>): Pausable => ({ 38 101 isPaused$, 39 102 pause() {
+32 -3
packages/svelte-urql/src/context.ts
··· 3 3 4 4 const _contextKey = '$$_urql'; 5 5 6 - /** Retrieves a Client from Svelte's context */ 6 + /** Returns a provided {@link Client}. 7 + * 8 + * @remarks 9 + * `getContextClient` returns the {@link Client} that’s previously 10 + * been provided on Svelte’s context with {@link setContextClient}. 11 + * 12 + * This is useful to create a `Client` on Svelte’s context once, and 13 + * then pass it to all GraphQL store functions without importing it 14 + * from a singleton export. 15 + * 16 + * @throws 17 + * In development, if `getContextClient` can’t get a {@link Client} 18 + * from Svelte’s context, an error will be thrown. 19 + */ 7 20 export const getContextClient = (): Client => { 8 21 const client = getContext(_contextKey); 9 22 if (process.env.NODE_ENV !== 'production' && !client) { ··· 15 28 return client as Client; 16 29 }; 17 30 18 - /** Sets a Client on Svelte's context */ 31 + /** Provides a {@link Client} to a component’s children. 32 + * 33 + * @remarks 34 + * `setContextClient` updates the Svelte context to provide 35 + * a {@link Client} to be later retrieved using the 36 + * {@link getContextClient} function. 37 + */ 19 38 export const setContextClient = (client: Client): void => { 20 39 setContext(_contextKey, client); 21 40 }; 22 41 23 - /** Creates Client and adds it to Svelte's context */ 42 + /** Creates a {@link Client} and provides it to a component’s children. 43 + * 44 + * @param args - a {@link ClientOptions} object to create a `Client` with. 45 + * @returns the created {@link Client}. 46 + * 47 + * @remarks 48 + * `initContextClient` is a convenience wrapper around 49 + * `setContextClient` that accepts {@link ClientOptions}, 50 + * creates a {@link Client} and provides it to be later 51 + * retrieved using the {@link getContextClient} function. 52 + */ 24 53 export const initContextClient = (args: ClientOptions): Client => { 25 54 const client = new Client(args); 26 55 setContextClient(client);
+7
packages/svelte-urql/src/index.ts
··· 1 1 export * from '@urql/core'; 2 + 3 + export type { 4 + Pausable, 5 + OperationResultStore, 6 + OperationResultState, 7 + } from './common'; 8 + 2 9 export * from './queryStore'; 3 10 export * from './mutationStore'; 4 11 export * from './subscriptionStore';
+67
packages/svelte-urql/src/mutationStore.ts
··· 15 15 initialResult, 16 16 } from './common'; 17 17 18 + /** Input arguments for the {@link mutationStore} function. 19 + * 20 + * @param query - The GraphQL mutation that the `mutationStore` executes. 21 + * @param variables - The variables for the GraphQL mutation that `mutationStore` executes. 22 + */ 18 23 export type MutationArgs< 19 24 Data = any, 20 25 Variables extends AnyVariables = AnyVariables 21 26 > = { 27 + /** The {@link Client} using which the subscription will be started. 28 + * 29 + * @remarks 30 + * If you’ve previously provided a {@link Client} on Svelte’s context 31 + * this can be set to {@link getContextClient}’s return value. 32 + */ 22 33 client: Client; 34 + /** Updates the {@link OperationContext} for the GraphQL mutation operation. 35 + * 36 + * @remarks 37 + * `context` may be passed to {@link mutationStore}, to update the 38 + * {@link OperationContext} of a mutation operation. This may be used to update 39 + * the `context` that exchanges will receive for a single hook. 40 + * 41 + * @example 42 + * ```ts 43 + * mutationStore({ 44 + * query, 45 + * context: { 46 + * additionalTypenames: ['Item'], 47 + * }, 48 + * }); 49 + * ``` 50 + */ 23 51 context?: Partial<OperationContext>; 24 52 } & GraphQLRequestParams<Data, Variables>; 25 53 54 + /** Function to create a `mutationStore` that runs a GraphQL mutation and updates with a GraphQL result. 55 + * 56 + * @param args - a {@link MutationArgs} object, to pass a `query`, `variables`, and options. 57 + * @returns a {@link OperationResultStore} of the mutation’s result. 58 + * 59 + * @remarks 60 + * `mutationStore` allows a GraphQL mutation to be defined as a Svelte store. 61 + * Given {@link MutationArgs.query}, it executes the GraphQL mutation on the 62 + * {@link MutationArgs.client}. 63 + * 64 + * The returned store updates with an {@link OperationResult} when 65 + * the `Client` returns a result for the mutation. 66 + * 67 + * Hint: It’s often easier to use {@link Client.mutation} if you’re 68 + * creating a mutation imperatively and don’t need a store. 69 + * 70 + * @see {@link https://urql.dev/goto/docs/basics/svelte#mutations} for 71 + * `mutationStore` docs. 72 + * 73 + * @example 74 + * ```ts 75 + * import { mutationStore, gql, getContextClient } from '@urql/svelte'; 76 + * 77 + * const client = getContextClient(); 78 + * 79 + * let result; 80 + * function updateTodo({ id, title }) { 81 + * result = queryStore({ 82 + * client, 83 + * query: gql` 84 + * mutation($id: ID!, $title: String!) { 85 + * updateTodo(id: $id, title: $title) { id, title } 86 + * } 87 + * `, 88 + * variables: { id, title }, 89 + * }); 90 + * } 91 + * ``` 92 + */ 26 93 export function mutationStore< 27 94 Data = any, 28 95 Variables extends AnyVariables = AnyVariables
+76
packages/svelte-urql/src/queryStore.ts
··· 30 30 fromStore, 31 31 } from './common'; 32 32 33 + /** Input arguments for the {@link queryStore} function. 34 + * 35 + * @param query - The GraphQL query that the `queryStore` executes. 36 + * @param variables - The variables for the GraphQL query that `queryStore` executes. 37 + */ 33 38 export type QueryArgs< 34 39 Data = any, 35 40 Variables extends AnyVariables = AnyVariables 36 41 > = { 42 + /** The {@link Client} using which the query will be executed. 43 + * 44 + * @remarks 45 + * If you’ve previously provided a {@link Client} on Svelte’s context 46 + * this can be set to {@link getContextClient}’s return value. 47 + */ 37 48 client: Client; 49 + /** Updates the {@link OperationContext} for the executed GraphQL query operation. 50 + * 51 + * @remarks 52 + * `context` may be passed to {@link queryStore}, to update the {@link OperationContext} 53 + * of a query operation. This may be used to update the `context` that exchanges 54 + * will receive for a single hook. 55 + * 56 + * @example 57 + * ```ts 58 + * queryStore({ 59 + * query, 60 + * context: { 61 + * additionalTypenames: ['Item'], 62 + * }, 63 + * }); 64 + * ``` 65 + */ 38 66 context?: Partial<OperationContext>; 67 + /** Sets the {@link RequestPolicy} for the executed GraphQL query operation. 68 + * 69 + * @remarks 70 + * `requestPolicy` modifies the {@link RequestPolicy} of the GraphQL query operation 71 + * that the {@link queryStore} executes, and indicates a caching strategy for cache exchanges. 72 + * 73 + * For example, when set to `'cache-and-network'`, the `queryStore` will 74 + * receive a cached result with `stale: true` and an API request will be 75 + * sent in the background. 76 + * 77 + * @see {@link OperationContext.requestPolicy} for where this value is set. 78 + */ 39 79 requestPolicy?: RequestPolicy; 80 + /** Prevents the {@link queryStore} from automatically executing GraphQL query operations. 81 + * 82 + * @remarks 83 + * `pause` may be set to `true` to stop the {@link queryStore} from executing 84 + * automatically. The store will stop receiving updates from the {@link Client} 85 + * and won’t execute the query operation, until either it’s set to `false` 86 + * or {@link Pausable.resume} is called. 87 + * 88 + * @see {@link https://urql.dev/goto/docs/basics/svelte#pausing-queries} for 89 + * documentation on the `pause` option. 90 + */ 40 91 pause?: boolean; 41 92 } & GraphQLRequestParams<Data, Variables>; 42 93 94 + /** Function to create a `queryStore` that runs a GraphQL query and updates with GraphQL results. 95 + * 96 + * @param args - a {@link QueryArgs} object, to pass a `query`, `variables`, and options. 97 + * @returns a {@link OperationResultStore} of query results, which implements {@link Pausable}. 98 + * 99 + * @remarks 100 + * `queryStore` allows GraphQL queries to be defined as Svelte stores. 101 + * Given {@link QueryArgs.query}, it executes the GraphQL query on the 102 + * {@link QueryArgs.client}. 103 + * 104 + * The returned store updates with {@link OperationResult} values when 105 + * the `Client` has new results for the query. 106 + * 107 + * @see {@link https://urql.dev/goto/docs/basics/svelte#queries} for `queryStore` docs. 108 + * 109 + * @example 110 + * ```ts 111 + * import { queryStore, gql, getContextClient } from '@urql/svelte'; 112 + * 113 + * const todos = queryStore({ 114 + * client: getContextClient(), 115 + * query: gql`{ todos { id, title } }`, 116 + * }); 117 + * ``` 118 + */ 43 119 export function queryStore< 44 120 Data = any, 45 121 Variables extends AnyVariables = AnyVariables
+93
packages/svelte-urql/src/subscriptionStore.ts
··· 29 29 fromStore, 30 30 } from './common'; 31 31 32 + /** Combines previous data with an incoming subscription result’s data. 33 + * 34 + * @remarks 35 + * A `SubscriptionHandler` may be passed to {@link subscriptionStore} to 36 + * aggregate subscription results into a combined `data` value on the 37 + * {@link OperationResultStore}. 38 + * 39 + * This is useful when a subscription event delivers a single item, while 40 + * you’d like to display a list of events. 41 + * 42 + * @example 43 + * ```ts 44 + * const NotificationsSubscription = gql` 45 + * subscription { newNotification { id, text } } 46 + * `; 47 + * 48 + * subscriptionStore( 49 + * { query: NotificationsSubscription }, 50 + * function combineNotifications(notifications = [], data) { 51 + * return [...notifications, data.newNotification]; 52 + * }, 53 + * ); 54 + * ``` 55 + */ 32 56 export type SubscriptionHandler<T, R> = (prev: R | undefined, data: T) => R; 33 57 58 + /** Input arguments for the {@link subscriptionStore} function. 59 + * 60 + * @param query - The GraphQL subscription that the `subscriptionStore` executes. 61 + * @param variables - The variables for the GraphQL subscription that `subscriptionStore` executes. 62 + */ 34 63 export type SubscriptionArgs< 35 64 Data = any, 36 65 Variables extends AnyVariables = AnyVariables 37 66 > = { 67 + /** The {@link Client} using which the subscription will be started. 68 + * 69 + * @remarks 70 + * If you’ve previously provided a {@link Client} on Svelte’s context 71 + * this can be set to {@link getContextClient}’s return value. 72 + */ 38 73 client: Client; 74 + /** Updates the {@link OperationContext} for the GraphQL subscription operation. 75 + * 76 + * @remarks 77 + * `context` may be passed to {@link subscriptionStore}, to update the 78 + * {@link OperationContext} of a subscription operation. This may be used to update 79 + * the `context` that exchanges will receive for a single hook. 80 + * 81 + * @example 82 + * ```ts 83 + * subscriptionStore({ 84 + * query, 85 + * context: { 86 + * additionalTypenames: ['Item'], 87 + * }, 88 + * }); 89 + * ``` 90 + */ 39 91 context?: Partial<OperationContext>; 92 + /** Prevents the {@link subscriptionStore} from automatically starting the GraphQL subscription. 93 + * 94 + * @remarks 95 + * `pause` may be set to `true` to stop the {@link subscriptionStore} from starting 96 + * its subscription automatically. The store won't execute the subscription operation, 97 + * until either it’s set to `false` or {@link Pausable.resume} is called. 98 + */ 40 99 pause?: boolean; 41 100 } & GraphQLRequestParams<Data, Variables>; 42 101 102 + /** Function to create a `subscriptionStore` that starts a GraphQL subscription. 103 + * 104 + * @param args - a {@link QueryArgs} object, to pass a `query`, `variables`, and options. 105 + * @param handler - optionally, a {@link SubscriptionHandler} function to combine multiple subscription results. 106 + * @returns a {@link OperationResultStore} of subscription results, which implements {@link Pausable}. 107 + * 108 + * @remarks 109 + * `subscriptionStore` allows GraphQL subscriptions to be defined as Svelte stores. 110 + * Given {@link SubscriptionArgs.query}, it executes the GraphQL subsription on the 111 + * {@link SubscriptionArgs.client}. 112 + * 113 + * The returned store updates with {@link OperationResult} values when 114 + * the `Client` has new results for the subscription. 115 + * 116 + * @see {@link https://urql.dev/goto/docs/advanced/subscriptions#svelte} for 117 + * `subscriptionStore` docs. 118 + * 119 + * @example 120 + * ```ts 121 + * import { subscriptionStore, gql, getContextClient } from '@urql/svelte'; 122 + * 123 + * const todos = subscriptionStore({ 124 + * client: getContextClient(), 125 + * query: gql` 126 + * subscription { 127 + * newNotification { id, text } 128 + * } 129 + * `, 130 + * function combineNotifications(notifications = [], data) { 131 + * return [...notifications, data.newNotification]; 132 + * }, 133 + * }); 134 + * ``` 135 + */ 43 136 export function subscriptionStore< 44 137 Data, 45 138 Result = Data,
+1 -2
packages/vue-urql/src/index.ts
··· 12 12 export type { 13 13 UseSubscriptionArgs, 14 14 UseSubscriptionResponse, 15 - UseSubscriptionState, 16 15 SubscriptionHandlerArg, 17 16 SubscriptionHandler, 18 17 } from './useSubscription'; 19 18 20 19 export { useMutation } from './useMutation'; 21 20 22 - export type { UseMutationResponse, UseMutationState } from './useMutation'; 21 + export type { UseMutationResponse } from './useMutation'; 23 22 24 23 import { install } from './useClient'; 25 24
+65
packages/vue-urql/src/useClient.ts
··· 3 3 4 4 const clientsPerInstance = new WeakMap<{}, Ref<Client>>(); 5 5 6 + /** Provides a {@link Client} to a component’s children. 7 + * 8 + * @param opts - {@link ClientOptions}, a {@link Client}, or a reactive ref object of a `Client`. 9 + * 10 + * @remarks 11 + * `provideClient` provides a {@link Client} to `@urql/vue`’s GraphQL 12 + * functions in children components. 13 + * 14 + * Hint: GraphQL functions and {@link useClient} will see the 15 + * provided `Client`, even if `provideClient` has been called 16 + * in the same component’s `setup` function. 17 + * 18 + * @example 19 + * ```ts 20 + * import { provideClient } from '@urql/vue'; 21 + * // All of `@urql/core` is also re-exported by `@urql/vue`: 22 + * import { Client, cacheExchange, fetchExchange } from '@urql/core'; 23 + * 24 + * export default { 25 + * setup() { 26 + * provideClient(new Client({ 27 + * url: 'https://API', 28 + * exchanges: [cacheExchange, fetchExchange], 29 + * })); 30 + * }, 31 + * }; 32 + * ``` 33 + */ 6 34 export function provideClient(opts: ClientOptions | Client | Ref<Client>) { 7 35 let client: Ref<Client>; 8 36 if (!isRef(opts)) { ··· 20 48 return client.value; 21 49 } 22 50 51 + /** Provides a {@link Client} to a Vue app. 52 + * 53 + * @param app - the Vue {@link App} 54 + * @param opts - {@link ClientOptions}, a {@link Client}, or a reactive ref object of a `Client`. 55 + * 56 + * @remarks 57 + * `install` provides a {@link Client} to `@urql/vue`’s GraphQL 58 + * functions in a Vue app. 59 + * 60 + * @example 61 + * ```ts 62 + * import * as urql from '@urql/vue'; 63 + * // All of `@urql/core` is also re-exported by `@urql/vue`: 64 + * import { cacheExchange, fetchExchange } from '@urql/core'; 65 + * 66 + * import { createApp } from 'vue'; 67 + * import Root from './App.vue'; 68 + * 69 + * const app = createApp(Root); 70 + * app.use(urql, { 71 + * url: 'http://localhost:3000/graphql', 72 + * exchanges: [cacheExchange, fetchExchange], 73 + * }); 74 + * ``` 75 + */ 23 76 export function install(app: App, opts: ClientOptions | Client | Ref<Client>) { 24 77 let client: Ref<Client>; 25 78 if (!isRef(opts)) { ··· 30 83 app.provide('$urql', client); 31 84 } 32 85 86 + /** Returns a provided reactive ref object of a {@link Client}. 87 + * 88 + * @remarks 89 + * `useClient` may be called in Vue `setup` functions to retrieve a 90 + * reactive rev object of a {@link Client} that’s previously been 91 + * provided with {@link provideClient} in the current or a parent’s 92 + * `setup` function. 93 + * 94 + * @throws 95 + * In development, if `useClient` is called outside of a Vue `setup` 96 + * function or no {@link Client} was provided, an error will be thrown. 97 + */ 33 98 export function useClient(): Ref<Client> { 34 99 const instance = getCurrentInstance(); 35 100 if (process.env.NODE_ENV !== 'production' && !instance) {
+92
packages/vue-urql/src/useClientHandle.ts
··· 20 20 UseSubscriptionResponse, 21 21 } from './useSubscription'; 22 22 23 + /** Handle to create GraphQL operations outside of Vue’s `setup` functions. 24 + * 25 + * @remarks 26 + * The `ClientHandle` object is created inside a Vue `setup` function but 27 + * allows its methods to be called outside of `setup` functions, delaying 28 + * the creation of GraphQL operations, as an alternative to pausing queries 29 + * or subscriptions. 30 + * 31 + * This is also important when chaining multiple functions inside an 32 + * `async setup()` function. 33 + * 34 + * Hint: If you only need a single, non-updating result and want to execute 35 + * queries programmatically, it may be easier to call the {@link Client.query} 36 + * method. 37 + */ 23 38 export interface ClientHandle { 39 + /** The {@link Client} that’ll be used to execute GraphQL operations. */ 24 40 client: Client; 25 41 42 + /** Calls {@link useQuery} outside of a synchronous Vue `setup` function. 43 + * 44 + * @param args - a {@link UseQueryArgs} object, to pass a `query`, `variables`, and options. 45 + * @returns a {@link UseQueryResponse} object. 46 + * 47 + * @remarks 48 + * Creates a {@link UseQueryResponse} outside of a synchronous Vue `setup` 49 + * function or when chained in an `async setup()` function. 50 + */ 26 51 useQuery<T = any, V extends AnyVariables = AnyVariables>( 27 52 args: UseQueryArgs<T, V> 28 53 ): UseQueryResponse<T, V>; 29 54 55 + /** Calls {@link useSubscription} outside of a synchronous Vue `setup` function. 56 + * 57 + * @param args - a {@link UseSubscriptionArgs} object, to pass a `query`, `variables`, and options. 58 + * @param handler - optionally, a {@link SubscriptionHandler} function to combine multiple subscription results. 59 + * @returns a {@link UseSubscriptionResponse} object. 60 + * 61 + * @remarks 62 + * Creates a {@link UseSubscriptionResponse} outside of a synchronous Vue `setup` 63 + * function or when chained in an `async setup()` function. 64 + */ 30 65 useSubscription<T = any, R = T, V extends AnyVariables = AnyVariables>( 31 66 args: UseSubscriptionArgs<T, V>, 32 67 handler?: SubscriptionHandlerArg<T, R> 33 68 ): UseSubscriptionResponse<T, R, V>; 34 69 70 + /** Calls {@link useMutation} outside of a synchronous Vue `setup` function. 71 + * 72 + * @param query - a GraphQL mutation document which `useMutation` will execute. 73 + * @returns a {@link UseMutationResponse} object. 74 + * 75 + * @remarks 76 + * Creates a {@link UseMutationResponse} outside of a synchronous Vue `setup` 77 + * function or when chained in an `async setup()` function. 78 + */ 35 79 useMutation<T = any, V extends AnyVariables = AnyVariables>( 36 80 query: TypedDocumentNode<T, V> | DocumentNode | string 37 81 ): UseMutationResponse<T, V>; 38 82 } 39 83 84 + /** Creates a {@link ClientHandle} inside a Vue `setup` function. 85 + * 86 + * @remarks 87 + * `useClientHandle` creates and returns a {@link ClientHandle} 88 + * when called in a Vue `setup` function, which allows queries, 89 + * mutations, and subscriptions to be created _outside_ of 90 + * `setup` functions. 91 + * 92 + * This is also important when chaining multiple functions inside an 93 + * `async setup()` function. 94 + * 95 + * {@link useQuery} and other GraphQL functions must usually 96 + * be created in Vue `setup` functions so they can stop GraphQL 97 + * operations when your component unmounts. However, while they 98 + * queries and subscriptions can be paused, sometimes it’s easier 99 + * to delay the creation of their response objects. 100 + * 101 + * 102 + * @example 103 + * ```ts 104 + * import { ref, computed } from 'vue'; 105 + * import { gql, useClientHandle } from '@urql/vue'; 106 + * 107 + * export default { 108 + * async setup() { 109 + * const handle = useClientHandle(); 110 + * 111 + * const pokemons = await handle.useQuery({ 112 + * query: gql`{ pokemons(limit: 10) { id, name } }`, 113 + * }); 114 + * 115 + * const index = ref(0); 116 + * 117 + * // The `handle` allows another `useQuery` call to now be setup again 118 + * const pokemon = await handle.useQuery({ 119 + * query: gql` 120 + * query ($id: ID!) { 121 + * pokemon(id: $id) { id, name } 122 + * } 123 + * `, 124 + * variables: computed(() => ({ 125 + * id: pokemons.data.value.pokemons[index.value].id, 126 + * }), 127 + * }); 128 + * } 129 + * }; 130 + * ``` 131 + */ 40 132 export function useClientHandle(): ClientHandle { 41 133 const client = useClient(); 42 134 const stops: WatchStopHandle[] = [];
+95 -8
packages/vue-urql/src/useMutation.ts
··· 18 18 import { useClient } from './useClient'; 19 19 import { unwrapPossibleProxy } from './utils'; 20 20 21 - export interface UseMutationState<T, V extends AnyVariables = AnyVariables> { 21 + /** State of the last mutation executed by {@link useMutation}. 22 + * 23 + * @remarks 24 + * `UseMutationResponse` is returned by {@link useMutation} and 25 + * gives you the {@link OperationResult} of the last executed mutation, 26 + * and a {@link UseMutationResponse.executeMutation} method to 27 + * start mutations. 28 + * 29 + * Even if the mutation document passed to {@link useMutation} changes, 30 + * the state isn’t reset, so you can keep displaying the previous result. 31 + */ 32 + export interface UseMutationResponse<T, V extends AnyVariables = AnyVariables> { 33 + /** Indicates whether `useMutation` is currently executing a mutation. */ 22 34 fetching: Ref<boolean>; 35 + /** Indicates that the mutation result is not fresh. 36 + * 37 + * @remarks 38 + * The `stale` flag is set to `true` when a new result for the mutation 39 + * is expected. 40 + * This is mostly unused for mutations and will rarely affect you, and 41 + * is more relevant for queries. 42 + * 43 + * @see {@link OperationResult.stale} for the source of this value. 44 + */ 23 45 stale: Ref<boolean>; 46 + /** Reactive {@link OperationResult.data} for the executed mutation. */ 24 47 data: Ref<T | undefined>; 48 + /** Reactive {@link OperationResult.error} for the executed mutation. */ 25 49 error: Ref<CombinedError | undefined>; 50 + /** Reactive {@link OperationResult.extensions} for the executed mutation. */ 26 51 extensions: Ref<Record<string, any> | undefined>; 52 + /** Reactive {@link Operation} that the current state is for. 53 + * 54 + * @remarks 55 + * This is the mutation {@link Operation} that has last been executed. 56 + * When {@link UseQueryState.fetching} is `true`, this is the 57 + * last `Operation` that the current state was for. 58 + */ 27 59 operation: Ref<Operation<T, V> | undefined>; 28 - executeMutation: ( 60 + /** Triggers {@link useMutation} to execute its GraphQL mutation operation. 61 + * 62 + * @param variables - variables using which the mutation will be executed. 63 + * @param context - optionally, context options that will be merged with 64 + * {@link UseMutationArgs.context} and the `Client`’s options. 65 + * @returns the {@link OperationResult} of the mutation. 66 + * 67 + * @remarks 68 + * When called, {@link useMutation} will start the GraphQL mutation 69 + * it currently holds and use the `variables` passed to it. 70 + * 71 + * Once the mutation response comes back from the API, its 72 + * returned promise will resolve to the mutation’s {@link OperationResult} 73 + * and the {@link UseMutationResponse} will be updated with the result. 74 + * 75 + * @example 76 + * ```ts 77 + * const result = useMutation(UpdateTodo); 78 + * const start = async ({ id, title }) => { 79 + * const result = await result.executeMutation({ id, title }); 80 + * }; 81 + */ 82 + executeMutation( 29 83 variables: V, 30 84 context?: Partial<OperationContext> 31 - ) => Promise<OperationResult<T>>; 85 + ): Promise<OperationResult<T>>; 32 86 } 33 87 34 - export type UseMutationResponse< 35 - T, 36 - V extends AnyVariables = AnyVariables 37 - > = UseMutationState<T, V>; 38 - 88 + /** Function to create a GraphQL mutation, run by passing variables to {@link UseMutationResponse.executeMutation} 89 + * 90 + * @param query - a GraphQL mutation document which `useMutation` will execute. 91 + * @returns a {@link UseMutationResponse} object. 92 + * 93 + * @remarks 94 + * `useMutation` allows GraphQL mutations to be defined inside Vue `setup` functions, 95 + * and keeps its state after the mutation is started. Mutations can be started by calling 96 + * {@link UseMutationResponse.executeMutation} with variables. 97 + * 98 + * The returned result updates when a mutation is executed and keeps 99 + * track of the last mutation result. 100 + * 101 + * @see {@link https://urql.dev/goto/docs/basics/vue#mutations} for `useMutation` docs. 102 + * 103 + * @example 104 + * ```ts 105 + * import { gql, useMutation } from '@urql/vue'; 106 + * 107 + * const UpdateTodo = gql` 108 + * mutation ($id: ID!, $title: String!) { 109 + * updateTodo(id: $id, title: $title) { 110 + * id, title 111 + * } 112 + * } 113 + * `; 114 + * 115 + * export default { 116 + * setup() { 117 + * const result = useMutation(UpdateTodo); 118 + * const start = async ({ id, title }) => { 119 + * const result = await result.executeMutation({ id, title }); 120 + * }; 121 + * // ... 122 + * }, 123 + * }; 124 + * ``` 125 + */ 39 126 export function useMutation<T = any, V extends AnyVariables = AnyVariables>( 40 127 query: TypedDocumentNode<T, V> | DocumentNode | string 41 128 ): UseMutationResponse<T, V> {
+180 -5
packages/vue-urql/src/useQuery.ts
··· 23 23 type MaybeRef<T> = T | Ref<T>; 24 24 type MaybeRefObj<T extends {}> = { [K in keyof T]: MaybeRef<T[K]> }; 25 25 26 + /** Input arguments for the {@link useQuery} function. 27 + * 28 + * @param query - The GraphQL query that `useQuery` executes. 29 + * @param variables - The variables for the GraphQL query that `useQuery` executes. 30 + */ 26 31 export type UseQueryArgs< 27 32 Data = any, 28 33 Variables extends AnyVariables = AnyVariables 29 34 > = { 35 + /** Updates the {@link RequestPolicy} for the executed GraphQL query operation. 36 + * 37 + * @remarks 38 + * `requestPolicy` modifies the {@link RequestPolicy} of the GraphQL query operation 39 + * that `useQuery` executes, and indicates a caching strategy for cache exchanges. 40 + * 41 + * For example, when set to `'cache-and-network'`, {@link useQuery} will 42 + * receive a cached result with `stale: true` and an API request will be 43 + * sent in the background. 44 + * 45 + * @see {@link OperationContext.requestPolicy} for where this value is set. 46 + */ 30 47 requestPolicy?: MaybeRef<RequestPolicy>; 48 + /** Updates the {@link OperationContext} for the executed GraphQL query operation. 49 + * 50 + * @remarks 51 + * `context` may be passed to {@link useQuery}, to update the {@link OperationContext} 52 + * of a query operation. This may be used to update the `context` that exchanges 53 + * will receive for a single hook. 54 + * 55 + * @example 56 + * ```ts 57 + * const result = useQuery({ 58 + * query, 59 + * context: { 60 + * additionalTypenames: ['Item'], 61 + * }, 62 + * }); 63 + * ``` 64 + */ 31 65 context?: MaybeRef<Partial<OperationContext>>; 66 + /** Prevents {@link useQuery} from automatically executing GraphQL query operations. 67 + * 68 + * @remarks 69 + * `pause` may be set to `true` to stop {@link useQuery} from executing 70 + * automatically. This will pause the query until {@link UseQueryState.resume} 71 + * is called, or, if `pause` is a reactive ref of a boolean, until this 72 + * ref changes to `true`. 73 + * 74 + * @see {@link https://urql.dev/goto/docs/basics/vue#pausing-usequery} for 75 + * documentation on the `pause` option. 76 + */ 32 77 pause?: MaybeRef<boolean>; 33 78 } & MaybeRefObj<GraphQLRequestParams<Data, Variables>>; 34 79 35 - export type QueryPartialState< 36 - T = any, 37 - V extends AnyVariables = AnyVariables 38 - > = Partial<OperationResult<T, V>> & { fetching?: boolean }; 39 - 80 + /** State of the current query, your {@link useQuery} function is executing. 81 + * 82 + * @remarks 83 + * `UseQueryState` is returned by {@link useQuery} and 84 + * gives you the updating {@link OperationResult} of 85 + * GraphQL queries. 86 + * 87 + * Each value that is part of the result is wrapped in a reactive ref 88 + * and updates as results come in. 89 + * 90 + * Hint: Even when the query and variables update, the previous state of 91 + * the last result is preserved, which allows you to display the 92 + * previous state, while implementing a loading indicator separately. 93 + */ 40 94 export interface UseQueryState<T = any, V extends AnyVariables = AnyVariables> { 95 + /** Indicates whether `useQuery` is waiting for a new result. 96 + * 97 + * @remarks 98 + * When `useQuery` receives a new query and/or variables, it will 99 + * start executing the new query operation and `fetching` is set to 100 + * `true` until a result arrives. 101 + * 102 + * Hint: This is subtly different than whether the query is actually 103 + * fetching, and doesn’t indicate whether a query is being re-executed 104 + * in the background. For this, see {@link UseQueryState.stale}. 105 + */ 41 106 fetching: Ref<boolean>; 107 + /** Indicates that the state is not fresh and a new result will follow. 108 + * 109 + * @remarks 110 + * The `stale` flag is set to `true` when a new result for the query 111 + * is expected and `useQuery` is waiting for it. This may indicate that 112 + * a new request is being requested in the background. 113 + * 114 + * @see {@link OperationResult.stale} for the source of this value. 115 + */ 42 116 stale: Ref<boolean>; 117 + /** Reactive {@link OperationResult.data} for the executed query. */ 43 118 data: Ref<T | undefined>; 119 + /** Reactive {@link OperationResult.error} for the executed query. */ 44 120 error: Ref<CombinedError | undefined>; 121 + /** Reactive {@link OperationResult.extensions} for the executed query. */ 45 122 extensions: Ref<Record<string, any> | undefined>; 123 + /** Reactive {@link Operation} that the current state is for. 124 + * 125 + * @remarks 126 + * This is the {@link Operation} that is currently being executed. 127 + * When {@link UseQueryState.fetching} is `true`, this is the 128 + * last `Operation` that the current state was for. 129 + */ 46 130 operation: Ref<Operation<T, V> | undefined>; 131 + /** Indicates whether {@link useQuery} is currently paused. 132 + * 133 + * @remarks 134 + * When `useQuery` has been paused, it will stop receiving updates 135 + * from the {@link Client} and won’t execute query operations, until 136 + * {@link UseQueryArgs.pause} becomes `true` or {@link UseQueryState.resume} 137 + * is called. 138 + * 139 + * @see {@link https://urql.dev/goto/docs/basics/vue#pausing-usequery} for 140 + * documentation on the `pause` option. 141 + */ 47 142 isPaused: Ref<boolean>; 143 + /** Resumes {@link useQuery} if it’s currently paused. 144 + * 145 + * @remarks 146 + * Resumes or starts {@link useQuery}’s query, if it’s currently paused. 147 + * 148 + * @see {@link https://urql.dev/goto/docs/basics/vue#pausing-usequery} for 149 + * documentation on the `pause` option. 150 + */ 48 151 resume(): void; 152 + /** Pauses {@link useQuery} to stop it from executing the query. 153 + * 154 + * @remarks 155 + * Pauses {@link useQuery}’s query, which stops it from receiving updates 156 + * from the {@link Client} and to stop the ongoing query operation. 157 + * 158 + * @see {@link https://urql.dev/goto/docs/basics/vue#pausing-usequery} for 159 + * documentation on the `pause` option. 160 + */ 49 161 pause(): void; 162 + /** Triggers {@link useQuery} to execute a new GraphQL query operation. 163 + * 164 + * @param opts - optionally, context options that will be merged with 165 + * {@link UseQueryArgs.context} and the `Client`’s options. 166 + * 167 + * @remarks 168 + * When called, {@link useQuery} will re-execute the GraphQL query operation 169 + * it currently holds, unless it’s currently paused. 170 + * 171 + * This is useful for re-executing a query and get a new network result, 172 + * by passing a new request policy. 173 + * 174 + * ```ts 175 + * const result = useQuery({ query }); 176 + * 177 + * const refresh = () => { 178 + * // Re-execute the query with a network-only policy, skipping the cache 179 + * result.executeQuery({ requestPolicy: 'network-only' }); 180 + * }; 181 + * ``` 182 + */ 50 183 executeQuery(opts?: Partial<OperationContext>): UseQueryResponse<T, V>; 51 184 } 52 185 186 + /** Return value of {@link useQuery}, which is an awaitable {@link UseQueryState}. 187 + * 188 + * @remarks 189 + * {@link useQuery} returns a {@link UseQueryState} but may also be 190 + * awaited inside a Vue `async setup()` function. If it’s awaited 191 + * the query is executed before resolving. 192 + */ 53 193 export type UseQueryResponse< 54 194 T, 55 195 V extends AnyVariables = AnyVariables ··· 59 199 flush: 'pre' as const, 60 200 }; 61 201 202 + /** Function to run a GraphQL query and get reactive GraphQL results. 203 + * 204 + * @param args - a {@link UseQueryArgs} object, to pass a `query`, `variables`, and options. 205 + * @returns a {@link UseQueryResponse} object. 206 + * 207 + * @remarks 208 + * `useQuery` allows GraphQL queries to be defined and executed inside 209 + * Vue `setup` functions. 210 + * Given {@link UseQueryArgs.query}, it executes the GraphQL query with the 211 + * provided {@link Client}. 212 + * 213 + * The returned result’s reactive values update when the `Client` has 214 + * new results for the query, and changes when your input `args` change. 215 + * 216 + * Additionally, `useQuery` may also be awaited inside an `async setup()` 217 + * function to use Vue’s Suspense feature. 218 + * 219 + * @see {@link https://urql.dev/goto/docs/basics/vue#queries} for `useQuery` docs. 220 + * 221 + * @example 222 + * ```ts 223 + * import { gql, useQuery } from '@urql/vue'; 224 + * 225 + * const TodosQuery = gql` 226 + * query { todos { id, title } } 227 + * `; 228 + * 229 + * export default { 230 + * setup() { 231 + * const result = useQuery({ query: TodosQuery }); 232 + * return { data: result.data }; 233 + * }, 234 + * }; 235 + * ``` 236 + */ 62 237 export function useQuery<T = any, V extends AnyVariables = AnyVariables>( 63 238 args: UseQueryArgs<T, V> 64 239 ): UseQueryResponse<T, V> {
+174 -11
packages/vue-urql/src/useSubscription.ts
··· 22 22 type MaybeRef<T> = Exclude<T, void> | Ref<Exclude<T, void>>; 23 23 type MaybeRefObj<T extends {}> = { [K in keyof T]: MaybeRef<T[K]> }; 24 24 25 + /** Input arguments for the {@link useSubscription} function. 26 + * 27 + * @param query - The GraphQL subscription document that `useSubscription` executes. 28 + * @param variables - The variables for the GraphQL subscription that `useSubscription` executes. 29 + */ 25 30 export type UseSubscriptionArgs< 26 31 Data = any, 27 32 Variables extends AnyVariables = AnyVariables 28 33 > = { 34 + /** Prevents {@link useSubscription} from automatically executing GraphQL subscription operations. 35 + * 36 + * @remarks 37 + * `pause` may be set to `true` to stop {@link useSubscription} from starting 38 + * its subscription automatically. This will pause the subscription until 39 + * {@link UseSubscriptonState.resume} is called, or, if `pause` is a reactive 40 + * ref of a boolean, until this ref changes to `true`. 41 + */ 29 42 pause?: MaybeRef<boolean>; 43 + /** Updates the {@link OperationContext} for the executed GraphQL subscription operation. 44 + * 45 + * @remarks 46 + * `context` may be passed to {@link useSubscription}, to update the {@link OperationContext} 47 + * of a subscription operation. This may be used to update the `context` that exchanges 48 + * will receive for a single hook. 49 + * 50 + * @example 51 + * ```ts 52 + * const result = useQuery({ 53 + * query, 54 + * context: { 55 + * additionalTypenames: ['Item'], 56 + * }, 57 + * }); 58 + * ``` 59 + */ 30 60 context?: MaybeRef<Partial<OperationContext>>; 31 61 } & MaybeRefObj<GraphQLRequestParams<Data, Variables>>; 32 62 63 + /** Combines previous data with an incoming subscription result’s data. 64 + * 65 + * @remarks 66 + * A `SubscriptionHandler` may be passed to {@link useSubscription} to 67 + * aggregate subscription results into a combined {@link UseSubscriptionResponse.data} 68 + * value. 69 + * 70 + * This is useful when a subscription event delivers a single item, while 71 + * you’d like to display a list of events. 72 + * 73 + * @example 74 + * ```ts 75 + * const NotificationsSubscription = gql` 76 + * subscription { newNotification { id, text } } 77 + * `; 78 + * 79 + * const combineNotifications = (notifications = [], data) => { 80 + * return [...notifications, data.newNotification]; 81 + * }; 82 + * 83 + * const result = useSubscription( 84 + * { query: NotificationsSubscription }, 85 + * combineNotifications, 86 + * ); 87 + * ``` 88 + */ 33 89 export type SubscriptionHandler<T, R> = (prev: R | undefined, data: T) => R; 90 + 91 + /** A {@link SubscriptionHandler} or a reactive ref of one. */ 34 92 export type SubscriptionHandlerArg<T, R> = MaybeRef<SubscriptionHandler<T, R>>; 35 93 36 - export interface UseSubscriptionState< 94 + /** State of the current query, your {@link useSubscription} function is executing. 95 + * 96 + * @remarks 97 + * `UseSubscriptionResponse` is returned by {@link useSubscription} and 98 + * gives you the updating {@link OperationResult} of GraphQL subscriptions. 99 + * 100 + * Each value that is part of the result is wrapped in a reactive ref 101 + * and updates as results come in. 102 + * 103 + * Hint: Even when the query and variables update, the prior state of 104 + * the last result is preserved. 105 + */ 106 + export interface UseSubscriptionResponse< 37 107 T = any, 38 108 R = T, 39 109 V extends AnyVariables = AnyVariables 40 110 > { 111 + /** Indicates whether `useSubscription`’s subscription is active. 112 + * 113 + * @remarks 114 + * When `useSubscription` starts a subscription, the `fetching` flag 115 + * is set to `true` and will remain `true` until the subscription 116 + * completes on the API, or `useSubscription` is paused. 117 + */ 41 118 fetching: Ref<boolean>; 119 + /** Indicates that the subscription result is not fresh. 120 + * 121 + * @remarks 122 + * This is mostly unused for subscriptions and will rarely affect you, and 123 + * is more relevant for queries. 124 + * 125 + * @see {@link OperationResult.stale} for the source of this value. 126 + */ 42 127 stale: Ref<boolean>; 128 + /** Reactive {@link OperationResult.data} for the executed subscription, or data returned by the handler. 129 + * 130 + * @remarks 131 + * `data` will be set to the last {@link OperationResult.data} value 132 + * received for the subscription. 133 + * 134 + * It will instead be set to the values that {@link SubscriptionHandler} 135 + * returned, if a handler has been passed to {@link useSubscription}. 136 + */ 43 137 data: Ref<R | undefined>; 138 + /** Reactive {@link OperationResult.error} for the executed subscription. */ 44 139 error: Ref<CombinedError | undefined>; 140 + /** Reactive {@link OperationResult.extensions} for the executed mutation. */ 45 141 extensions: Ref<Record<string, any> | undefined>; 142 + /** Reactive {@link Operation} that the current state is for. 143 + * 144 + * @remarks 145 + * This is the subscription {@link Operation} that is currently active. 146 + * When {@link UseQueryState.fetching} is `true`, this is the 147 + * last `Operation` that the current state was for. 148 + */ 46 149 operation: Ref<Operation<T, V> | undefined>; 150 + /** Indicates whether {@link useSubscription} is currently paused. 151 + * 152 + * @remarks 153 + * When `useSubscription` has been paused, it will stop receiving updates 154 + * from the {@link Client} and won’t execute the subscription, until 155 + * {@link UseSubscriptionArgs.pause} becomes true or 156 + * {@link UseSubscriptionResponse.resume} is called. 157 + */ 47 158 isPaused: Ref<boolean>; 159 + /** Resumes {@link useSubscription} if it’s currently paused. 160 + * 161 + * @remarks 162 + * Resumes or starts {@link useSubscription}’s subscription, if it’s currently paused. 163 + */ 48 164 resume(): void; 165 + /** Pauses {@link useSubscription} to stop the subscription. 166 + * 167 + * @remarks 168 + * Pauses {@link useSubscription}’s subscription, which stops it 169 + * from receiving updates from the {@link Client} and to stop executing 170 + * the subscription operation. 171 + */ 49 172 pause(): void; 173 + /** Triggers {@link useQuery} to reexecute a GraphQL subscription operation. 174 + * 175 + * @param opts - optionally, context options that will be merged with 176 + * {@link UseQueryArgs.context} and the `Client`’s options. 177 + * 178 + * @remarks 179 + * When called, {@link useSubscription} will re-execute the GraphQL subscription 180 + * operation it currently holds, unless it’s currently paused. 181 + */ 50 182 executeSubscription(opts?: Partial<OperationContext>): void; 51 183 } 52 184 53 - export type UseSubscriptionResponse< 54 - T = any, 55 - R = T, 56 - V extends AnyVariables = AnyVariables 57 - > = UseSubscriptionState<T, R, V>; 58 - 59 185 const watchOptions = { 60 186 flush: 'pre' as const, 61 187 }; 62 188 189 + /** Function to run a GraphQL subscription and get reactive GraphQL results. 190 + * 191 + * @param args - a {@link UseSubscriptionArgs} object, to pass a `query`, `variables`, and options. 192 + * @param handler - optionally, a {@link SubscriptionHandler} function to combine multiple subscription results. 193 + * @returns a {@link UseSubscriptionResponse} object. 194 + * 195 + * @remarks 196 + * `useSubscription` allows GraphQL subscriptions to be defined and executed inside 197 + * Vue `setup` functions. 198 + * Given {@link UseSubscriptionArgs.query}, it executes the GraphQL subscription with the 199 + * provided {@link Client}. 200 + * 201 + * The returned result updates when the `Client` has new results 202 + * for the subscription, and `data` is updated with the result’s data 203 + * or with the `data` that a `handler` returns. 204 + * 205 + * @example 206 + * ```ts 207 + * import { gql, useSubscription } from '@urql/vue'; 208 + * 209 + * const NotificationsSubscription = gql` 210 + * subscription { newNotification { id, text } } 211 + * `; 212 + * 213 + * export default { 214 + * setup() { 215 + * const result = useSubscription( 216 + * { query: NotificationsSubscription }, 217 + * function combineNotifications(notifications = [], data) { 218 + * return [...notifications, data.newNotification]; 219 + * }, 220 + * ); 221 + * // ... 222 + * }, 223 + * }; 224 + * ``` 225 + */ 63 226 export function useSubscription< 64 227 T = any, 65 228 R = T, 66 229 V extends AnyVariables = AnyVariables 67 230 >( 68 231 args: UseSubscriptionArgs<T, V>, 69 - handler?: SubscriptionHandlerArg<T, R> 232 + handler?: MaybeRef<SubscriptionHandler<T, R>> 70 233 ): UseSubscriptionResponse<T, R, V> { 71 234 return callUseSubscription(args, handler); 72 235 } ··· 77 240 V extends AnyVariables = AnyVariables 78 241 >( 79 242 _args: UseSubscriptionArgs<T, V>, 80 - handler?: SubscriptionHandlerArg<T, R>, 243 + handler?: MaybeRef<SubscriptionHandler<T, R>>, 81 244 client: Ref<Client> = useClient(), 82 245 stops: WatchStopHandle[] = [] 83 246 ): UseSubscriptionResponse<T, R, V> { ··· 159 322 }, watchOptions) 160 323 ); 161 324 162 - const state: UseSubscriptionState<T, R, V> = { 325 + const state: UseSubscriptionResponse<T, R, V> = { 163 326 data, 164 327 stale, 165 328 error, ··· 169 332 isPaused, 170 333 executeSubscription( 171 334 opts?: Partial<OperationContext> 172 - ): UseSubscriptionState<T, R, V> { 335 + ): UseSubscriptionResponse<T, R, V> { 173 336 source.value = client.value.executeSubscription<T, V>(request.value, { 174 337 ...unwrapPossibleProxy(args.context), 175 338 ...opts,