import { createUseMetaState, UseMetaState } from './meta/useMetaState'; import { createUseMutation, UseMutation } from './mutation/useMutation'; import { createGraphqlHOC, GraphQLHOC } from './query/hoc'; import { createPrepareQuery, PrepareQuery } from './query/preparedQuery'; import { createUseLazyQuery, LazyFetchPolicy, UseLazyQuery, } from './query/useLazyQuery'; import { createUseQuery, UseQuery } from './query/useQuery'; import { createUseRefetch, UseRefetch } from './query/useRefetch'; import { createUseTransactionQuery, UseTransactionQuery, } from './query/useTransactionQuery'; import { createSSRHelpers, PrepareReactRender, UseHydrateCache, } from './ssr/ssr'; import { createUseSubscription, UseSubscription, } from './subscription/useSubscription'; import type { RetryOptions, GQlessClient } from 'gqless'; import type { FetchPolicy } from './common'; import type { ReactClientOptionsWithDefaults } from './utils'; import { createUsePaginatedQuery, PaginatedQueryFetchPolicy, UsePaginatedQuery, } from './query/usePaginatedQuery'; export interface ReactClientDefaults { /** * Enable/Disable by default 'React Suspense' behavior * * > _Valid for __graphql HOC__ & __useQuery___ * * > _You can override it on a per-function basis_ * * @default false */ suspense?: boolean; /** * Enable/Disable by default 'React Suspense' behavior for useLazyQuery hook * * > _Valid only for __useLazyQuery___ * * > _You can override it on a per-hook basis_ * * @default false */ lazyQuerySuspense?: boolean; /** * Enable/Disable by default 'React Suspense' behavior for useTransactionQuery hook * * > _Valid only for __useTransactionQuery___ * * > _You can override it on a per-hook basis_ * * __The _default value_ is obtained from the "`defaults.suspense`" value__ */ transactionQuerySuspense?: boolean; /** * Enable/Disable by default 'React Suspense' behavior for useMutation hook * * > _Valid only for __useMutation___ * * > _You can override it on a per-hook basis_ * * @default false */ mutationSuspense?: boolean; /** * Enable/Disable by default 'React Suspense' behavior for prepareQuery hooks * * > _Valid only for __prepareQuery___ hooks * * > _You can override it on a per-hook basis_ * * __The _default value_ is obtained from the "`defaults.suspense`" value__ */ preparedSuspense?: boolean; /** * Enable/Disable by default 'React Suspense' behavior for usePaginatedQuery hooks * * > _Valid only for __usePaginatedQuery___ hooks * * > _You can override it on a per-hook basis_ * * @default false */ paginatedQuerySuspense?: boolean; /** * Define default 'fetchPolicy' hooks behaviour * * > _Valid for __useTransactionQuery___ * * > _You can override it on a per-hook basis_ * * @default "cache-first" */ transactionFetchPolicy?: FetchPolicy; /** * Define default 'fetchPolicy' hooks behaviour * * > Valid for __useLazyQuery__ * * > _You can override it on a per-hook basis_ * * @default "network-only" */ lazyFetchPolicy?: LazyFetchPolicy; /** * Define default 'fetchPolicy' hooks behaviour * * > __Valid for __usePaginatedQuery____ * * > _You can override it on a per-hook basis_ * * @default "cache-first" */ paginatedQueryFetchPolicy?: PaginatedQueryFetchPolicy; /** * __Enable__/__Disable__ default 'stale-while-revalidate' behaviour * * > _Valid for __graphql HOC__ & __useQuery___ * * > _You can override it on a per-function basis_ * * @default false */ staleWhileRevalidate?: boolean; /** * Retry on error behaviour * * _You can override these defaults on a per-hook basis_ * * > _Valid for __useLazyQuery__, __useTransactionQuery__ & __useRefetch___ * * > For __useQuery__ & __graphql HOC__ you should use the `retry` in the core client options * * @default true */ retry?: RetryOptions; /** * Refetch after SSR hydration * * @default false */ refetchAfterHydrate?: boolean; } export interface CreateReactClientOptions { /** * Default behaviour values */ defaults?: ReactClientDefaults; } export interface ReactClient< GeneratedSchema extends { query: object; mutation: object; subscription: object; } > { useQuery: UseQuery; useRefetch: UseRefetch; useLazyQuery: UseLazyQuery; useTransactionQuery: UseTransactionQuery; usePaginatedQuery: UsePaginatedQuery; useMutation: UseMutation; graphql: GraphQLHOC; state: { isLoading: boolean }; prepareReactRender: PrepareReactRender; useHydrateCache: UseHydrateCache; useMetaState: UseMetaState; useSubscription: UseSubscription; prepareQuery: PrepareQuery; } export function createReactClient< GeneratedSchema extends { query: object; mutation: object; subscription: object; } >( client: GQlessClient, optsCreate: CreateReactClientOptions = {} ): ReactClient { const { suspense = false } = (optsCreate.defaults ||= {}); const { transactionFetchPolicy = 'cache-first', lazyFetchPolicy = 'network-only', staleWhileRevalidate = false, retry = true, lazyQuerySuspense = false, transactionQuerySuspense = suspense, mutationSuspense = false, preparedSuspense = suspense, refetchAfterHydrate = false, paginatedQueryFetchPolicy = 'cache-first', paginatedQuerySuspense = suspense, } = optsCreate.defaults; const defaults: ReactClientOptionsWithDefaults['defaults'] = { transactionFetchPolicy, lazyFetchPolicy, staleWhileRevalidate, suspense, retry, lazyQuerySuspense, transactionQuerySuspense, mutationSuspense, preparedSuspense, refetchAfterHydrate, paginatedQueryFetchPolicy, paginatedQuerySuspense, }; const opts: ReactClientOptionsWithDefaults = Object.assign({}, optsCreate, { defaults, }); const state = new Proxy( { isLoading: false, }, { get(target, key, receiver) { if (key === 'isLoading') return Boolean(client.scheduler.resolving); return Reflect.get(target, key, receiver); }, } ); const { prepareReactRender, useHydrateCache } = createSSRHelpers( client, opts ); return { useQuery: createUseQuery(client, opts), useRefetch: createUseRefetch(client, opts), useLazyQuery: createUseLazyQuery(client, opts), useTransactionQuery: createUseTransactionQuery( client, opts ), usePaginatedQuery: createUsePaginatedQuery(client, opts), useMutation: createUseMutation(client, opts), graphql: createGraphqlHOC(client, opts), state, prepareReactRender, useHydrateCache, useMetaState: createUseMetaState(client), useSubscription: createUseSubscription(client, opts), prepareQuery: createPrepareQuery(client, opts), }; }