convex
Version:
Client for the Convex Cloud
582 lines (550 loc) • 19.6 kB
TypeScript
/**
* The names of actions in a Convex API.
*
* @public
*/
export declare type ActionNames<API extends GenericAPI> = keyof API["actions"] & string;
/**
* Create the API type from the types of all of the modules.
*
* Input is an object mapping file paths to the type of each module.
*
* For internal use by Convex code generation.
*
* @public
*/
export declare type ApiFromModules<Modules extends Record<string, Record<string, any>>> = {
queries: Expand<ConvertToClientFunctions<PickByValue<MergeAllExports<Modules>, {
isQuery: true;
}>>>;
mutations: Expand<ConvertToClientFunctions<PickByValue<MergeAllExports<Modules>, {
isMutation: true;
}>>>;
actions: Expand<ConvertToClientFunctions<PickByValue<MergeAllExports<Modules>, {
isAction: true;
}>>>;
};
/**
* The configuration needed to construct a Convex client like the
* {@link ConvexHttpClient} and {@link react.ConvexReactClient}.
*
* This configuration is automatically generated by `npx convex dev` and
* `npx convex deploy`. You can find the generated version at
* `convex/_generated/clientConfig.js`.
*
* @public
*/
export declare interface ClientConfiguration {
/**
* The URL of the Convex deployment.
*/
address: string;
}
/**
* Options for {@link InternalConvexClient}.
*
* @public
*/
export declare type ClientOptions = {
/**
* 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;
};
/**
* State describing the client's connection with the Convex backend.
*
* @public
*/
declare type ConnectionState = {
hasInflightMutation: boolean;
hasInflightAction: boolean;
isWebSocketConnected: boolean;
};
/**
* Converts a map of query and mutation types into their client form.
*
* This is done by:
* - Unwrapping `Promise` if it's in the output.
* - Switching functions that output `undefined` to `null`.
*
*/
declare type ConvertToClientFunctions<FunctionsByName extends Record<string, any>> = {
[Name in keyof FunctionsByName]: (...args: FunctionsByName[Name]["args"]) => UndefinedToNull<Awaited<FunctionsByName[Name]["output"]>>;
};
/**
* A Convex client that runs queries and mutations over HTTP.
*
* This is appropriate for server-side code (like Netlify Lambdas) or non-reactive
* webapps.
*
* If you're building a React app, consider using
* {@link react.ConvexReactClient} instead.
*
*
* @public
*/
export declare class ConvexHttpClient<API extends GenericAPI> {
private readonly address;
private auth?;
private debug;
constructor(clientConfig: ClientConfiguration);
/**
* Obtain the {@link ConvexHttpClient}'s URL to its backend.
*
* @returns The URL to the Convex backend, including the client's API version.
*/
backendUrl(): string;
/**
* 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 value - JWT-encoded OpenID Connect identity token.
*/
setAuth(value: string): void;
/**
* Clear the current authentication token if set.
*/
clearAuth(): void;
/**
* Sets whether the result log lines should be printed on the console or not.
*
* @internal
*/
setDebug(debug: boolean): void;
/**
* Construct a new {@link Query}.
*
* @param name - The name of the query function.
* @returns The {@link Query} object with that name.
*/
query<Name extends QueryNames<API>>(name: Name): (...args: Parameters<NamedQuery<API, Name>>) => Promise<ReturnType<NamedQuery<API, Name>>>;
/**
* Construct a new {@link Mutation}.
*
* @param name - The name of the mutation function.
* @returns The {@link Mutation} object with that name.
*/
mutation<Name extends MutationNames<API>>(name: Name): (...args: Parameters<NamedMutation<API, Name>>) => Promise<ReturnType<NamedMutation<API, Name>>>;
/**
* Construct a new {@link Action}.
*
* @param name - The name of the action.
* @returns The {@link Action} object with that name.
* @public
*/
action<Name extends ActionNames<API>>(name: Name): (...args: Parameters<NamedAction<API, Name>>) => Promise<ReturnType<NamedAction<API, Name>>>;
}
/**
* Common utilities for manipulating TypeScript types.
* @module
*/
/**
* Hack! This type causes TypeScript to simplify how it renders object types.
*
* It is functionally the identity for object types, but in practice it can
* simplify expressions like `A & B`.
*/
declare type Expand<ObjectType extends Record<any, any>> = ObjectType extends Record<any, any> ? {
[Key in keyof ObjectType]: ObjectType[Key];
} : never;
/**
* Internal Codegen Type Helpers
*/
/**
* Generate the fully-qualified query/mutation name of an export.
*
* This is `path/to/module:export` or `path/to/module` for the default export.
*/
declare type FunctionName<FilePath extends string, ExportName extends string> = ExportName extends "default" ? FilePath : `${FilePath}:${ExportName}`;
/**
* Description of the Convex functions available to an application.
*
* This is a generic type that expresses the shape of API types created by
* `npx convex codegen`. It's used to make the Convex clients type-safe.
*
* @public
*/
export declare type GenericAPI = {
queries: Record<string, (...args: any[]) => any>;
mutations: Record<string, (...args: any[]) => any>;
actions: Record<string, (...args: any[]) => any>;
};
/**
* An identifier for a document in Convex.
*
* Convex documents are uniquely identified by their `GenericId`, which is accessible
* on the `_id` field. To learn more, see [Data Modeling](https://docs.convex.dev/using/data-modeling).
*
* Documents can be loaded using `db.get(id)` in query and mutation functions.
*
* **Important**: Use `myId.equals(otherId)` to check for equality.
* Using `===` will not work because two different instances of `GenericId` can refer
* to the same document.
*
* `GenericId`s are 17 bytes long and consist of:
* - A 15-byte random value.
* - A 2-byte timestamp representing the document's creation, in days since the Unix epoch.
* This is encoded in base 62 ([0-9A-Za-z]).
*
* If you're using code generation, use the `Id` class typed for your data model in
* `convex/_generated/dataModel.js`.
*
* @typeParam TableName - A string literal type of the table name (like "users").
*
* @public
*/
declare class GenericId<TableName extends string> {
/**
* The table name this {@link GenericId} references.
*/
readonly tableName: TableName;
/**
* The identifier string.
*
* This contains the characters `[0-9A-Za-z]`.
*/
readonly id: string;
constructor(tableName: TableName, id: string);
/**
* Check if this {@link GenericId} refers to the same document as another {@link GenericId}.
*
* @param other - The other {@link GenericId} to compare to.
* @returns `true` if the objects refer to the same document.
*/
equals(other: unknown): boolean;
/**
* Parse a {@link GenericId} from its JSON representation.
*/
static fromJSON(obj: any): GenericId<string>;
/**
* Convert a {@link GenericId} into its JSON representation.
*/
toJSON(): JSONValue;
/**
* Convert a {@link GenericId} into its string representation.
*
* This includes the identifier but not the table name.
*/
toString(): string;
/**
* Pretty-print this {@link GenericId} for debugging.
*/
inspect(): string;
}
/**
* Low-level client for directly integrating state management libraries
* with Convex.
*
* Most developers should use higher level clients, like
* the {@link ConvexHttpClient} or the React hook based {@link react.ConvexReactClient}.
*
* @public
*/
export declare class InternalConvexClient {
private readonly state;
private readonly mutationManager;
private readonly actionManager;
private readonly webSocketManager;
private remoteQuerySet;
private readonly optimisticQueryResults;
private readonly onTransition;
private nextMutationId;
private nextActionId;
private readonly sessionId;
/**
* @param clientConfig - The generated client configuration for your project.
* You can find this at `convex/_generated/clientConfig.js`.
* @param onTransition - A callback receiving an array of query tokens
* corresponding to query results that have changed.
* @param options - See {@link ClientOptions} for a full description.
*/
constructor(clientConfig: ClientConfiguration, onTransition: (updatedQueries: QueryToken[]) => void, options?: ClientOptions);
/**
* Compute the current query results based on the remoteQuerySet and the
* current optimistic updates and call `onTransition` for all the changed
* queries.
*
* @param completedMutations - A set of mutation IDs whose optimistic updates
* are no longer needed.
*/
private notifyOnQueryResultChanges;
setAuth(value: string): void;
/** @internal */
setAdminAuth(value: string): void;
clearAuth(): void;
/**
* Subscribe to a query function.
*
* Whenever this query's result changes, the `onTransition` callback
* passed into the constructor will be called.
*
* @param name - The name of the query.
* @param args - An array of the arguments to the query.
* @param journal - An (optional) journal produced from a previous
* execution of this query function. Note that if this query function with
* these arguments has already been requested the journal will have no effect.
* @returns An object containing a {@link QueryToken} corresponding to this
* query and an `unsubscribe` callback.
*/
subscribe(name: string, args: any[], journal?: QueryJournal): {
queryToken: QueryToken;
unsubscribe: () => void;
};
/**
* A query result based only on the current, local state.
*
* The only way this will return a value is if we're already subscribed to the
* query or its value has been set optimistically.
*/
localQueryResult(udfPath: string, args: any[]): Value | undefined;
/**
* Retrieve the current {@link QueryJournal} for this query function.
*
* If we have not yet received a result for this query, this will be `undefined`.
*
* @param name - The name of the query.
* @param args - An array of arguments to this query.
* @returns The query's {@link QueryJournal} or `undefined`.
*/
queryJournal(name: string, args: any[]): QueryJournal | undefined;
/**
* Get the current {@link ConnectionState} between the client and the Convex
* backend.
*
* @returns The {@link ConnectionState} with the Convex backend.
*/
connectionState(): ConnectionState;
mutate<Args extends any[]>(udfPath: string, args: Args, optimisticUpdate?: OptimisticUpdate<GenericAPI, Args> | null): Promise<any>;
action<Args extends any[]>(udfPath: string, args: Args): Promise<any>;
close(): Promise<void>;
}
/**
* The type of JavaScript values serializable to JSON.
*
* @public
*/
declare type JSONValue = null | boolean | number | string | JSONValue[] | {
[key: string]: JSONValue;
};
/**
* Name and merge together all of the exports in the `convex/` directory into
* a flat object type.
*/
declare type MergeAllExports<Modules extends Record<string, Record<string, any>>> = UnionToIntersection<{
[FilePath in keyof Modules]: NameModule<FilePath & string, Modules[FilePath]>;
}[keyof Modules]>;
/**
* An interface to execute a Convex mutation function on the server.
*
* @public
*/
export declare interface Mutation<F extends (...args: any[]) => Promise<any>> {
/**
* Execute the mutation on the server, returning a `Promise` of its return value.
*
* @param args - Arguments for the mutation.
* @returns The return value of the server-side function call.
*/
(...args: Parameters<F>): Promise<Awaited<ReturnType<F>>>;
}
/**
* The names of mutation functions in a Convex API.
*
* @public
*/
export declare type MutationNames<API extends GenericAPI> = keyof API["mutations"] & string;
/**
* The type of an action in a Convex API.
*
* @public
*/
export declare type NamedAction<API extends GenericAPI, Name extends MutationNames<API>> = API["actions"][Name];
/**
* The type of a mutation function in a Convex API.
*
* @public
*/
export declare type NamedMutation<API extends GenericAPI, Name extends MutationNames<API>> = API["mutations"][Name];
/**
* The type of a query function in a Convex API.
*
* @public
*/
export declare type NamedQuery<API extends GenericAPI, Name extends QueryNames<API>> = API["queries"][Name];
/**
* Generate a type of this module where each export is renamed to its
* fully-qualified {@link FunctionName}.
*/
declare type NameModule<FilePath extends string, Module extends Record<string, any>> = {
[ExportName in keyof Module as FunctionName<FilePath, ExportName & string>]: Module[ExportName];
};
/**
* A view of the query results currently in the Convex client for use within
* optimistic updates.
*
* @public
*/
export declare interface OptimisticLocalStore<API extends GenericAPI = GenericAPI> {
/**
* Retrieve the result of a query from the client.
*
* Important: Query results should be treated as immutable!
* Always make new copies of structures within query results to avoid
* corrupting data within the client.
*
* @param name - The name of the query.
* @param args - An array of the arguments for this query.
* @returns The query result or `undefined` if the query is not currently
* in the client.
*/
getQuery<Name extends QueryNames<API>>(name: Name, args: Parameters<NamedQuery<API, Name>>): undefined | ReturnType<NamedQuery<API, Name>>;
/**
* Retrieve the results are arguments of all queries with a given name.
*
* This is useful for complex optimistic updates that need to inspect and
* update many query results (for example updating a paginated list).
*
* Important: Query results should be treated as immutable!
* Always make new copies of structures within query results to avoid
* corrupting data within the client.
* @param name - The name of the query.
* @returns An array of objects, one for each query of the given name.
* Each object includes:
* - `args` - An array of the arguments to the query.
* - `value` The query result or `undefined` if the query is loading.
*/
getAllQueries<Name extends QueryNames<API>>(name: Name): {
args: Parameters<NamedQuery<API, Name>>;
value: undefined | ReturnType<NamedQuery<API, Name>>;
}[];
/**
* Optimistically update the result of a query.
*
* This can either be a new value (perhaps derived from the old value from
* {@link OptimisticLocalStore.getQuery}) or `undefined` to remove the query.
* Removing a query is useful to create loading states while Convex recomputes
* the query results.
*
* @param name - The name of the query.
* @param args - An array of the arguments for this query.
* @param value - The new value to set the query to or `undefined` to remove
* it from the client.
*/
setQuery<Name extends QueryNames<API>>(name: Name, args: Parameters<NamedQuery<API, Name>>, value: undefined | ReturnType<NamedQuery<API, Name>>): void;
}
/**
* A temporary, local update to query results within this client.
*
* This update will always be executed when a mutation is synced to the Convex
* server and rolled back when the mutation completes.
*
* Note that optimistic updates can be called multiple times! If the client
* loads new data while the mutation is in progress, the update will be replayed
* again.
*
* @param localQueryStore - An interface to read and edit local query results.
* @param args - The arguments to the mutation.
*
* @public
*/
export declare type OptimisticUpdate<API extends GenericAPI, Arguments extends Value[]> = (localQueryStore: OptimisticLocalStore<API>, ...args: Arguments) => void;
/**
* From ObjectType, pick the properties that are assignable to T.
*/
declare type PickByValue<ObjectType, T> = Pick<ObjectType, {
[Key in keyof ObjectType]: ObjectType[Key] extends T ? Key : never;
}[keyof ObjectType]>;
/**
* An interface to execute a Convex query function on the server.
*
* @public
*/
export declare interface Query<F extends (...args: any[]) => Promise<any>> {
/**
* Execute the query on the server, returning a `Promise` of the return value.
*
* @param args - Arguments for the query.
* @returns The result of the query.
*/
(...args: Parameters<F>): Promise<Awaited<ReturnType<F>>>;
}
/**
* A serialized representation of decisions made during a query's execution.
*
* A journal is produced when a query function first executes and is re-used
* when a query is re-executed.
*
* Currently this is used to store pagination end cursors to ensure
* that pages of paginated queries will always end at the same cursor. This
* enables gapless, reactive pagination.
*
* `null` is used to represent empty journals.
* @public
*/
export declare type QueryJournal = string | null;
/**
* Helper types for interacting with the overall API type
*/
/**
* The names of query functions in a Convex API.
*
* @public
*/
export declare type QueryNames<API extends GenericAPI> = keyof API["queries"] & string;
/**
* The result of running a query function on the server.
*
* If the function hit an exception it will have an `errorMessage`. Otherwise
* it will produce a `Value`.
*
* @public
*/
export declare type QueryResult = {
success: true;
value: Value;
} | {
success: false;
errorMessage: string;
};
/**
* A string representing the name and arguments of a query.
*
* This is used by the {@link InternalConvexClient}.
*
* @public
*/
export declare type QueryToken = string;
declare type UndefinedToNull<T> = T extends void ? null : T;
/**
* Convert a union type like `A | B | C` into an intersection type like
* `A & B & C`.
*/
declare type UnionToIntersection<UnionType> = (UnionType extends any ? (k: UnionType) => void : never) extends (k: infer I) => void ? I : never;
/**
* A value supported by Convex.
*
* Values can be:
* - stored inside of documents.
* - used as arguments and return types to queries and mutation functions.
*
* You can see the full set of supported types at
* [Types](https://docs.convex.dev/using/types).
*
* @public
*/
declare type Value = GenericId<string> | null | bigint | number | boolean | string | ArrayBuffer | Value[] | Set<Value> | Map<Value, Value> | {
[key: string]: Value;
};
export { }