UNPKG

convex

Version:

Client for the Convex Cloud

383 lines 14.7 kB
/** * Tools to integrate Convex into React applications. * * This module contains: * 1. {@link ConvexReactClient}, a client for using Convex in React. * 2. {@link ConvexProvider}, a component that stores this client in React context. * 2. [Hooks](https://docs.convex.dev/generated-api/react#react-hooks) for calling into * this client within your React components. * * ## Usage * * ### Creating the Client * * ```typescript * import { ConvexReactClient } from "convex/react"; * import clientConfig from "../convex/_generated/clientConfig"; * * const convex = new ConvexReactClient(clientConfig); * ``` * * ### Storing the Client In React Context * * ```typescript * import { ConvexProvider } from "convex/react"; * * <ConvexProvider client={convex}> * <App /> * </ConvexProvider> * ``` * * ### Generating the Hooks * * This module is typically used alongside generated hooks. * * To generate the hooks, run `npx convex codegen` in your Convex project. This * will create a `convex/_generated/react.js` file with the following React * hooks, typed for your queries and mutations: * - [useQuery](https://docs.convex.dev/generated-api/react#usequery) * - [useMutation](https://docs.convex.dev/generated-api/react#usemutation) * - [useConvex](https://docs.convex.dev/generated-api/react#useconvex) * - [usePaginatedQuery](https://docs.convex.dev/generated-api/react#usepaginatedquery) * - [useQueries](https://docs.convex.dev/generated-api/react#usequeries) * * If you aren't using code generation, you can use these untyped hooks instead: * - {@link useQueryGeneric} * - {@link useMutationGeneric} * - {@link useConvexGeneric} * - {@link usePaginatedQueryGeneric} * - {@link useQueriesGeneric} * * ### Using the Hooks * * ```typescript * import { useQuery, useMutation } from "../convex/_generated/react"; * * function App() { * const counter = useQuery("getCounter"); * const increment = useMutation("incrementCounter"); * // Your component here! * } * ``` * @module */ import { GenericAPI, MutationNames, QueryNames, ActionNames, NamedMutation, NamedQuery, NamedAction } from "../browser/index.js"; import type { OptimisticUpdate } from "../browser/index.js"; import React from "react"; import { ClientConfiguration } from "../browser/client_config.js"; import { QueryJournal } from "../browser/sync/protocol.js"; import { ConnectionState } from "../browser/sync/client.js"; export * from "./use_paginated_query.js"; export { useQueriesGeneric, type RequestForQueries, type UseQueriesForAPI, } from "./use_queries.js"; /** * An interface to execute a Convex mutation function on the server. * * @public */ export interface ReactMutation<API extends GenericAPI, Name extends MutationNames<API>> { /** * Execute the mutation on the server, returning a `Promise` of its return value. * * @param args - Arguments for the mutation to pass up to the server. * @returns The return value of the server-side function call. */ (...args: Parameters<NamedMutation<API, Name>>): Promise<ReturnType<NamedMutation<API, Name>>>; /** * Define an optimistic update to apply as part of this mutation. * * This is a temporary update to the local query results to facilitate a * fast, interactive UI. It enables query results to update before a mutation * executed on the server. * * When the mutation is invoked, the optimistic update will be applied. * * Optimistic updates can also be used to temporarily remove queries from the * client and create loading experiences until a mutation completes and the * new query results are synced. * * The update will be automatically rolled back when the mutation is fully * completed and queries have been updated. * * @param optimisticUpdate - The optimistic update to apply. * @returns A new `ReactMutation` with the update configured. * * @public */ withOptimisticUpdate(optimisticUpdate: OptimisticUpdate<API, Parameters<NamedMutation<API, Name>>>): ReactMutation<API, Name>; } /** * An interface to execute a Convex action on the server. * * @public */ export interface ReactAction<API extends GenericAPI, Name extends ActionNames<API>> { /** * Execute the function on the server, returning a `Promise` of its return value. * * @param args - Arguments for the function to pass up to the server. * @returns The return value of the server-side function call. * @public */ (...args: Parameters<NamedAction<API, Name>>): Promise<ReturnType<NamedAction<API, Name>>>; } /** * A watch on the output of a Convex query function. * * @public */ export interface Watch<T> { /** * Initiate a watch on the output of a query. * * This will subscribe to this query and call * the callback whenever the query result changes. * * **Important: If the query is already known on the client this watch will * never be invoked.** To get the current, local result call * {@link react.Watch.localQueryResult}. * * @param callback - Function that is called whenever the query result changes. * @returns - A function that disposes of the subscription. */ onUpdate(callback: () => void): () => void; /** * Get the current result of a query. * * This will only return a result if we're already subscribed to the query * and have received a result from the server or the query value has been set * optimistically. * * @returns The result of the query or `undefined` if it isn't known. * @throws An error if the query encountered an error on the server. */ localQueryResult(): T | undefined; /** * Get the current {@link browser.QueryJournal} for this query. * * If we have not yet received a result for this query, this will be `undefined`. */ journal(): QueryJournal | undefined; } /** * Options for {@link ConvexReactClient}. * * @public */ export declare type ReactClientOptions = { /** * Whether to prompt the user that have unsaved changes pending * when navigating away or closing a web page with pending Convex mutations. * This is only possible when the `window` object exists, i.e. in a browser. * The default value is `true`. */ unsavedChangesWarning?: boolean; /** * Specifies an alternate [WebSocket](https://developer.mozilla.org/en-US/docs/Web/API/WebSocket) constructor to use for client communication with the Convex cloud. The default behavior is to use `WebSocket` from the global environment. */ webSocketConstructor?: typeof WebSocket; }; /** * A Convex client for use within React. * * This loads reactive queries and executes mutations over a WebSocket. * * @typeParam API - The API of your application, composed of all Convex queries * and mutations. `npx convex codegen` [generates this type](/generated-api/react#convexapi) * in `convex/_generated/react.d.ts`. * @public */ export declare class ConvexReactClient<API extends GenericAPI> { private clientConfig; private cachedSync?; private listeners; private options; private closed; private adminAuth?; /** * @param clientConfig - The generated client configuration for your project. * You can find this in `convex/_generated/clientConfig.js`. * @param options - See {@link ReactClientOptions} for a full description. */ constructor(clientConfig: ClientConfiguration, options?: ReactClientOptions); /** * Lazily instantiate the `InternalConvexClient` so we don't create the WebSocket * when server-side rendering. */ private get sync(); /** * Set the authentication token to be used for subsequent queries and mutations. * Should be called whenever the token changes (i.e. due to expiration and refresh) * @param token - JWT-encoded OpenID Connect Identity Token */ setAuth(token: string): void; /** * Clear the current authentication token if set. */ clearAuth(): void; /** * @internal */ setAdminAuth(token: string): void; /** * Construct a new {@link Watch} on a Convex query function. * * **Most application code should not call this method directly. Instead use * the `useQuery` hook generated by `npx convex codegen`.** * * @param name - The name of the query function. * @param args - The arguments to the query. * @param journal - An (optional) {@link browser.QueryJournal} to use while * executing this query. Note that if this query function with these arguments * has already been requested, the journal will have no effect. * @returns The {@link Watch} object. */ watchQuery<Name extends QueryNames<API>>(name: Name, args: Parameters<NamedQuery<API, Name>>, journal?: QueryJournal): Watch<ReturnType<NamedQuery<API, Name>>>; /** * Construct a new {@link ReactMutation}. * * @param name - The name of the Mutation. * @returns The {@link ReactMutation} object with that name. */ mutation<Name extends MutationNames<API>>(name: Name): ReactMutation<API, Name>; /** * Construct a new {@link ReactAction} * * @param name - The name of the Action. * @returns The {@link ReactAction} object with that name. */ action<Name extends ActionNames<API>>(name: Name): ReactAction<API, Name>; /** * Get the current {@link ConnectionState} between the client and the Convex * backend. * * @returns The {@link ConnectionState} with the Convex backend. */ connectionState(): ConnectionState; /** * Close any network handles associated with this client and stop all subscriptions. * * Call this method when you're done with a {@link ConvexReactClient} to * dispose of its sockets and resources. * * @returns A `Promise` fulfilled when the connection has been completely closed. */ close(): Promise<void>; private transition; } /** * Get the {@link ConvexReactClient} within a React component. * * This relies on the {@link ConvexProvider} being above in the React component tree. * * If you're using code generation, use the `useConvex` function in * `convex/_generated/react.js` which is typed for your API. * * @returns The active {@link ConvexReactClient} object, or `undefined`. * * @public */ export declare function useConvexGeneric<API extends GenericAPI>(): ConvexReactClient<API>; /** * Provides an active Convex {@link ConvexReactClient} to descendants of this component. * * Wrap your app in this component to use Convex hooks `useQuery`, * `useMutation`, and `useConvex`. * * @param props - an object with a `client` property that refers to a {@link ConvexReactClient}. * * @public */ export declare const ConvexProvider: React.FC<{ client: ConvexReactClient<any>; children?: React.ReactNode; }>; /** * Load a reactive query within a React component. * * This React hook contains internal state that will cause a rerender * whenever the query result changes. * * Throws an error if not used under {@link ConvexProvider}. * * If you're using code generation, use the `useQuery` function in * `convex/_generated/react.js` which is typed for your API. * * @param name - The name of the query function. * @param args - The arguments to the query function. * @returns `undefined` if loading and the query's return value otherwise. * * @public */ export declare function useQueryGeneric<API extends GenericAPI, Name extends QueryNames<API>>(name: Name, ...args: Parameters<NamedQuery<API, Name>>): ReturnType<NamedQuery<API, Name>> | undefined; /** * Construct a new {@link ReactMutation}. * * Mutation objects can be called like functions to request execution of the * corresponding Convex function, or further configured with * [optimistic updates](https://docs.convex.dev/using/optimistic-updates). * * The value returned by this hook is stable across renders, so it can be used * by React dependency arrays and memoization logic relying on object identity * without causing rerenders. * * If you're using code generation, use the `useMutation` function in * `convex/_generated/react.js` which is typed for your API. * * Throws an error if not used under {@link ConvexProvider}. * * @param name - The name of the mutation. * @returns The {@link ReactMutation} object with that name. * * @public */ export declare function useMutationGeneric<API extends GenericAPI, Name extends MutationNames<API>>(name: Name): ReactMutation<API, Name>; /** * Construct a new {@link ReactAction}. * * Action objects can be called like functions to request execution of the * corresponding Convex function. * * The value returned by this hook is stable across renders, so it can be used * by React dependency arrays and memoization logic relying on object identity * without causing rerenders. * * If you're using code generation, use the `useAction` function in * `convex/_generated/react.js` which is typed for your API. * * Throws an error if not used under {@link ConvexProvider}. * * @param name - The name of the action. * @returns The {@link ReactAction} object with that name. * * @public */ export declare function useActionGeneric<API extends GenericAPI, Name extends ActionNames<API>>(name: Name): ReactAction<API, Name>; /** * Internal type helper used by Convex code generation. * * Used to give {@link useQueryGeneric} a type specific to your API. * @public */ export declare type UseQueryForAPI<API extends GenericAPI> = <Name extends QueryNames<API>>(name: Name, ...args: Parameters<NamedQuery<API, Name>>) => ReturnType<NamedQuery<API, Name>> | undefined; /** * Internal type helper used by Convex code generation. * * Used to give {@link useMutationGeneric} a type specific to your API. * @public */ export declare type UseMutationForAPI<API extends GenericAPI> = <Name extends MutationNames<API>>(name: Name) => ReactMutation<API, Name>; /** * Internal type helper used by Convex code generation. * * Used to give {@link useMutationGeneric} a type specific to your API. * @public */ export declare type UseActionForAPI<API extends GenericAPI> = <Name extends ActionNames<API>>(name: Name) => ReactAction<API, Name>; /** * Internal type helper used by Convex code generation. * * Used to give {@link useConvexGeneric} a type specific to your API. * @public */ export declare type UseConvexForAPI<API extends GenericAPI> = () => ConvexReactClient<API>; //# sourceMappingURL=index.d.ts.map