examples: Update Convex to latest version (0.19) (#52473)

Update Convex example to use convex 0.19.x

- [x] The "examples guidelines" are followed from our contributing doc https://github.com/vercel/next.js/blob/canary/contributing/examples/adding-examples.md
- [x] Make sure the linting passes by running `pnpm build && pnpm lint`. See https://github.com/vercel/next.js/blob/canary/contributing/repository/linting.md
This commit is contained in:
Tom Ballinger 2023-07-09 15:51:15 -07:00 committed by GitHub
parent 7ea788e472
commit a2618ede90
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
16 changed files with 158 additions and 556 deletions

View file

@ -6,66 +6,79 @@ https://docs.convex.dev/using/writing-convex-functions for more.
A query function that takes two arguments looks like:
```javascript
// myQueryFunction.js
// functions.js
import { query } from './_generated/server'
import { v } from 'convex/values'
export default query(async ({ db }, first, second) => {
// Validate arguments here.
if (typeof first !== 'number' || first < 0) {
throw new Error('First argument is not a non-negative number.')
}
if (typeof second !== 'string' || second.length > 1000) {
throw new Error('Second argument is not a string of length 1000 or less.')
}
export const myQueryFunction = query({
// Validators for arguments.
args: {
first: v.number(),
second: v.string(),
},
// Query the database as many times as you need here.
// See https://docs.convex.dev/using/database-queries to learn how to write queries.
const documents = await db.query('tablename').collect()
// Function implementation.
hander: async ({ db }, { first, second }) => {
// Read the database as many times as you need here.
// See https://docs.convex.dev/database/reading-data.
const documents = await db.query('tablename').collect()
// Write arbitrary JavaScript here: filter, aggregate, build derived data,
// remove non-public properties, or create new objects.
return documents
// Write arbitrary JavaScript here: filter, aggregate, build derived data,
// remove non-public properties, or create new objects.
return documents
},
})
```
Using this query function in a React component looks like:
```javascript
const data = useQuery('myQueryFunction', 10, 'hello')
const data = useQuery(api.functions.myQueryFunction, {
first: 10,
second: 'hello',
})
```
A mutation function looks like:
```javascript
// myMutationFunction.js
// functions.js
import { mutation } from './_generated/server'
import { v } from 'convex/values'
export default mutation(async ({ db }, first, second) => {
// Validate arguments here.
if (typeof first !== 'string' || typeof second !== 'string') {
throw new Error('Both arguments must be strings')
}
export const myMutationFunction = mutation({
// Validators for arguments.
args: {
first: v.string(),
second: v.string(),
},
// Insert or modify documents in the database here.
// Mutations can also read from the database like queries.
const message = { body: first, author: second }
const id = await db.insert('messages', message)
// Function implementation.
hander: async ({ db }, { first, second }) => {
// Insert or modify documents in the database here.
// Mutations can also read from the database like queries.
// See https://docs.convex.dev/database/writing-data.
const message = { body: first, author: second }
const id = await db.insert('messages', message)
// Optionally, return a value from your mutation.
return await db.get(id)
// Optionally, return a value from your mutation.
return await db.get(id)
},
})
```
Using this mutation function in a React component looks like:
```javascript
const mutation = useMutation('myMutationFunction')
const mutation = useMutation(api.functions.myMutationFunction)
function handleButtonPress() {
// fire and forget, the most common way to use mutations
mutation('Hello!', 'me')
mutation({ first: 'Hello!', second: 'me' })
// OR
// use the result once the mutation has completed
mutation('Hello!', 'me').then((result) => console.log(result))
mutation({ first: 'Hello!', second: 'me' }).then((result) =>
console.log(result)
)
}
```

View file

@ -1,28 +1,37 @@
/* eslint-disable */
/**
* Generated API.
* Generated `api` utility.
*
* THIS CODE IS AUTOMATICALLY GENERATED.
*
* Generated by convex@0.12.0.
* To regenerate, run `npx convex codegen`.
* Generated by convex@0.19.0.
* To regenerate, run `npx convex dev`.
* @module
*/
import type { ApiFromModules } from "convex/api";
import type * as listMessages from "../listMessages";
import type * as sendMessage from "../sendMessage";
import type {
ApiFromModules,
FilterApi,
FunctionReference,
} from "convex/server";
import type * as messages from "../messages";
/**
* A type describing your app's public Convex API.
* A utility for referencing Convex functions in your app's API.
*
* This `API` type includes information about the arguments and return
* types of your app's query and mutation functions.
*
* This type should be used with type-parameterized classes like
* `ConvexReactClient` to create app-specific types.
* Usage:
* ```js
* const myFunctionReference = api.myModule.myFunction;
* ```
*/
export type API = ApiFromModules<{
listMessages: typeof listMessages;
sendMessage: typeof sendMessage;
declare const fullApi: ApiFromModules<{
messages: typeof messages;
}>;
export declare const api: FilterApi<
typeof fullApi,
FunctionReference<any, "public">
>;
export declare const internal: FilterApi<
typeof fullApi,
FunctionReference<any, "internal">
>;

View file

@ -0,0 +1,23 @@
/* eslint-disable */
/**
* Generated `api` utility.
*
* THIS CODE IS AUTOMATICALLY GENERATED.
*
* Generated by convex@0.19.0.
* To regenerate, run `npx convex dev`.
* @module
*/
import { anyApi } from "convex/server";
/**
* A utility for referencing Convex functions in your app's API.
*
* Usage:
* ```js
* const myFunctionReference = api.myModule.myFunction;
* ```
*/
export const api = anyApi;
export const internal = anyApi;

View file

@ -4,14 +4,14 @@
*
* THIS CODE IS AUTOMATICALLY GENERATED.
*
* Generated by convex@0.12.0.
* To regenerate, run `npx convex codegen`.
* Generated by convex@0.19.0.
* To regenerate, run `npx convex dev`.
* @module
*/
import type { DataModelFromSchemaDefinition } from "convex/schema";
import type { DataModelFromSchemaDefinition } from "convex/server";
import type { DocumentByName, TableNamesInDataModel } from "convex/server";
import { GenericId, GenericIdConstructor } from "convex/values";
import type { GenericId } from "convex/values";
import schema from "../schema";
/**
@ -37,28 +37,13 @@ export type Doc<TableName extends TableNames> = DocumentByName<
*
* 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 `Id` can refer
* to the same document.
* IDs are just strings at runtime, but this type can be used to distinguish them from other
* strings when type checking.
*
* @typeParam TableName - A string literal type of the table name (like "users").
*/
export type Id<TableName extends TableNames> = GenericId<TableName>;
/**
* An identifier for a document in Convex.
*
* Convex documents are uniquely identified by their `Id`, which is accessible
* on the `_id` field. To learn more, see [Document IDs](https://docs.convex.dev/using/document-ids).
*
* 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 `Id` can refer
* to the same document.
*/
export declare const Id: GenericIdConstructor<TableNames>;
/**
* A type describing your Convex data model.
*

View file

@ -1,26 +0,0 @@
/* eslint-disable */
/**
* Generated data model types.
*
* THIS CODE IS AUTOMATICALLY GENERATED.
*
* Generated by convex@0.12.0.
* To regenerate, run `npx convex codegen`.
* @module
*/
import { GenericId } from "convex/values";
/**
* An identifier for a document in Convex.
*
* Convex documents are uniquely identified by their `Id`, 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 `Id` can refer
* to the same document.
*/
export const Id = GenericId;

View file

@ -1,167 +0,0 @@
/* eslint-disable */
/**
* Generated React hooks.
*
* THIS CODE IS AUTOMATICALLY GENERATED.
*
* Generated by convex@0.12.0.
* To regenerate, run `npx convex codegen`.
* @module
*/
import type { OptimisticLocalStore as GenericOptimisticLocalStore } from "convex/browser";
import type {
UseActionForAPI,
UseConvexForAPI,
UsePaginatedQueryForAPI,
UseMutationForAPI,
UseQueriesForAPI,
UseQueryForAPI,
} from "convex/react";
import type { API } from "./api";
/**
* Load a reactive query within a React component.
*
* This React hook contains internal state that will cause a rerender whenever
* the query result changes.
*
* This relies on the {@link ConvexProvider} being above in the React component tree.
*
* @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.
*/
export declare const useQuery: UseQueryForAPI<API>;
/**
* 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.
*
* This relies on the {@link ConvexProvider} being above in the React component tree.
*
* @param name - The name of the mutation.
* @returns The {@link ReactMutation} object with that name.
*/
export declare const useMutation: UseMutationForAPI<API>;
/**
* 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.
*
* This relies on the {@link ConvexProvider} being above in the React component tree.
*
* @param name - The name of the action.
* @returns The {@link ReactAction} object with that name.
*/
export declare const useAction: UseActionForAPI<API>;
/**
* Get the {@link ConvexReactClient} within a React component.
*
* This relies on the {@link ConvexProvider} being above in the React component tree.
*
* @returns The active {@link ConvexReactClient} object, or `undefined`.
*/
export declare const useConvex: UseConvexForAPI<API>;
/**
* Load data reactively from a paginated query to a create a growing list.
*
* This can be used to power "infinite scroll" UIs.
*
* This hook must be used with Convex query functions that match
* {@link PaginatedQueryFunction}. This means they must:
* 1. Have a first argument must be an object containing `numItems` and `cursor`.
* 2. Return a {@link PaginationResult}.
*
* `usePaginatedQuery` concatenates all the pages
* of results into a single list and manages the continuation cursors when
* requesting more items.
*
* Example usage:
* ```typescript
* const { results, status, loadMore } = usePaginatedQuery(
* "listMessages",
* { initialNumItems: 5 },
* "#general"
* );
* ```
*
* @param name - The name of the query function.
* @param options - An object specifying the `initialNumItems` to be loaded in
* the first page.
* @param args - The arguments to the query function, excluding the first.
* @returns A {@link UsePaginatedQueryResult} that includes the currently loaded
* items, the status of the pagination, and a `loadMore` function.
*/
export declare const usePaginatedQuery: UsePaginatedQueryForAPI<API>;
/**
* Load a variable number of reactive Convex queries.
*
* `useQueries` is similar to {@link useQuery} but it allows
* loading multiple queries which can be useful for loading a dynamic number
* of queries without violating the rules of React hooks.
*
* This hook accepts an object whose keys are identifiers for each query and the
* values are objects of `{ name: string, args: Value[] }`. The `name` is the
* name of the Convex query function to load, and the `args` are the arguments to
* that function.
*
* The hook returns an object that maps each identifier to the result of the query,
* `undefined` if the query is still loading, or an instance of `Error` if the query
* threw an exception.
*
* For example if you loaded a query like:
* ```typescript
* const results = useQueriesGeneric({
* messagesInGeneral: {
* name: "listMessages",
* args: ["#general"]
* }
* });
* ```
* then the result would look like:
* ```typescript
* {
* messagesInGeneral: [{
* channel: "#general",
* body: "hello"
* _id: ...,
* _creationTime: ...
* }]
* }
* ```
*
* This React hook contains internal state that will cause a rerender
* whenever any of the query results change.
*
* Throws an error if not used under {@link ConvexProvider}.
*
* @param queries - An object mapping identifiers to objects of
* `{name: string, args: Value[] }` describing which query functions to fetch.
* @returns An object with the same keys as the input. The values are the result
* of the query function, `undefined` if it's still loading, or an `Error` if
* it threw an exception.
*/
export declare const useQueries: UseQueriesForAPI<API>;
/**
* A view of the query results currently in the Convex client for use within
* optimistic updates.
*/
export type OptimisticLocalStore = GenericOptimisticLocalStore<API>;

View file

@ -1,166 +0,0 @@
/* eslint-disable */
/**
* Generated React hooks.
*
* THIS CODE IS AUTOMATICALLY GENERATED.
*
* Generated by convex@0.12.0.
* To regenerate, run `npx convex codegen`.
* @module
*/
import {
useConvexGeneric,
useActionGeneric,
useMutationGeneric,
usePaginatedQueryGeneric,
useQueriesGeneric,
useQueryGeneric,
} from "convex/react";
/**
* Load a reactive query within a React component.
*
* This React hook contains internal state that will cause a rerender whenever
* the query result changes.
*
* This relies on the {@link ConvexProvider} being above in the React component tree.
*
* @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.
*/
export const useQuery = useQueryGeneric;
/**
* 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.
*
* This relies on the {@link ConvexProvider} being above in the React component tree.
*
* @param name - The name of the mutation.
* @returns The {@link ReactMutation} object with that name.
*/
export const useMutation = useMutationGeneric;
/**
* Construct a new {@link ReactAction}.
*
* Convex function 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.
*
* This relies on the {@link ConvexProvider} being above in the React component tree.
*
* @param name - The name of the function.
* @returns The {@link ReactAction} object with that name.
*/
export const useAction = useActionGeneric;
/**
* Get the {@link ConvexReactClient} within a React component.
*
* This relies on the {@link ConvexProvider} being above in the React component tree.
*
* @returns The active {@link ConvexReactClient} object, or `undefined`.
*/
export const useConvex = useConvexGeneric;
/**
* Load data reactively from a paginated query to a create a growing list.
*
* This can be used to power "infinite scroll" UIs.
*
* This hook must be used with Convex query functions that match
* {@link PaginatedQueryFunction}. This means they must:
* 1. Have a first argument must be an object containing `numItems` and `cursor`.
* 2. Return a {@link PaginationResult}.
*
* `usePaginatedQuery` concatenates all the pages
* of results into a single list and manages the continuation cursors when
* requesting more items.
*
* Example usage:
* ```typescript
* const { results, status, loadMore } = usePaginatedQuery(
* "listMessages",
* { initialNumItems: 5 },
* "#general"
* );
* ```
*
* If the query `name` or `args` change, the pagination state will be reset
* to the first page. Similarly, if any of the pages result in an InvalidCursor
* or QueryScannedTooManyDocuments error, the pagination state will also reset
* to the first page.
*
* To learn more about pagination, see [Paginated Queries](https://docs.convex.dev/using/pagination).
*
* @param name - The name of the query function.
* @param options - An object specifying the `initialNumItems` to be loaded in
* the first page.
* @param args - The arguments to the query function, excluding the first.
* @returns A {@link UsePaginatedQueryResult} that includes the currently loaded
* items, the status of the pagination, and a `loadMore` function.
*/
export const usePaginatedQuery = usePaginatedQueryGeneric;
/**
* Load a variable number of reactive Convex queries.
*
* `useQueries` is similar to {@link useQuery} but it allows
* loading multiple queries which can be useful for loading a dynamic number
* of queries without violating the rules of React hooks.
*
* This hook accepts an object whose keys are identifiers for each query and the
* values are objects of `{ name: string, args: Value[] }`. The `name` is the
* name of the Convex query function to load, and the `args` are the arguments to
* that function.
*
* The hook returns an object that maps each identifier to the result of the query,
* `undefined` if the query is still loading, or an instance of `Error` if the query
* threw an exception.
*
* For example if you loaded a query like:
* ```typescript
* const results = useQueriesGeneric({
* messagesInGeneral: {
* name: "listMessages",
* args: ["#general"]
* }
* });
* ```
* then the result would look like:
* ```typescript
* {
* messagesInGeneral: [{
* channel: "#general",
* body: "hello"
* _id: ...,
* _creationTime: ...
* }]
* }
* ```
*
* This React hook contains internal state that will cause a rerender
* whenever any of the query results change.
*
* Throws an error if not used under {@link ConvexProvider}.
*
* @param queries - An object mapping identifiers to objects of
* `{name: string, args: Value[] }` describing which query functions to fetch.
* @returns An object with the same keys as the input. The values are the result
* of the query function, `undefined` if it's still loading, or an `Error` if
* it threw an exception.
*/
export const useQueries = useQueriesGeneric;

View file

@ -4,53 +4,23 @@
*
* THIS CODE IS AUTOMATICALLY GENERATED.
*
* Generated by convex@0.12.0.
* To regenerate, run `npx convex codegen`.
* Generated by convex@0.19.0.
* To regenerate, run `npx convex dev`.
* @module
*/
import {
ActionBuilderForAPI,
HttpEndpointBuilderForAPI,
ActionBuilder,
HttpActionBuilder,
MutationBuilder,
QueryBuilderForDataModel,
InternalActionBuilderForAPI,
InternalMutationBuilder,
InternalQueryBuilderForDataModel,
CronJobsForAPI,
QueryBuilder,
ActionCtx as GenericActionCtx,
HttpEndpointCtx as GenericHttpEndpointCtx,
MutationCtx as GenericMutationCtx,
QueryCtx as GenericQueryCtx,
DatabaseReader as GenericDatabaseReader,
DatabaseWriter as GenericDatabaseWriter,
} from "convex/server";
import type { DataModel } from "./dataModel.js";
import type { API } from "./api.js";
/**
* Returns a cron job scheduler, used to schedule Convex functions to run on a recurring basis.
*
* ```js
* // convex/crons.js
* import { cronJobs } from './_generated/server';
*
* const crons = cronJobs();
* crons.weekly(
* "weekly re-engagement email",
* {
* hourUTC: 17, // (9:30am Pacific/10:30am Daylight Savings Pacific)
* minuteUTC: 30,
* },
* "sendEmails"
* )
* export default crons;
* ```
*
* @returns The cron job scheduler object. Create this object in `convex/crons.js` and export it
* as the default export.
*/
export declare const cronJobs: CronJobsForAPI<API>;
/**
* Define a query in this Convex app's public API.
@ -60,7 +30,7 @@ export declare const cronJobs: CronJobsForAPI<API>;
* @param func - The query function. It receives a {@link QueryCtx} as its first argument.
* @returns The wrapped query. Include this as an `export` to name it and make it accessible.
*/
export declare const query: QueryBuilderForDataModel<DataModel>;
export declare const query: QueryBuilder<DataModel, "public">;
/**
* Define a query that is only accessible from other Convex functions (but not from the client).
@ -70,7 +40,7 @@ export declare const query: QueryBuilderForDataModel<DataModel>;
* @param func - The query function. It receives a {@link QueryCtx} as its first argument.
* @returns The wrapped query. Include this as an `export` to name it and make it accessible.
*/
export declare const internalQuery: InternalQueryBuilderForDataModel<DataModel>;
export declare const internalQuery: QueryBuilder<DataModel, "internal">;
/**
* Define a mutation in this Convex app's public API.
@ -80,7 +50,7 @@ export declare const internalQuery: InternalQueryBuilderForDataModel<DataModel>;
* @param func - The mutation function. It receives a {@link MutationCtx} as its first argument.
* @returns The wrapped mutation. Include this as an `export` to name it and make it accessible.
*/
export declare const mutation: MutationBuilder<DataModel, API>;
export declare const mutation: MutationBuilder<DataModel, "public">;
/**
* Define a mutation that is only accessible from other Convex functions (but not from the client).
@ -90,42 +60,40 @@ export declare const mutation: MutationBuilder<DataModel, API>;
* @param func - The mutation function. It receives a {@link MutationCtx} as its first argument.
* @returns The wrapped mutation. Include this as an `export` to name it and make it accessible.
*/
export declare const internalMutation: InternalMutationBuilder<DataModel, API>;
export declare const internalMutation: MutationBuilder<DataModel, "internal">;
/**
* Define an action in this Convex app's public API.
*
* An action is a function which can execute any JavaScript code, including non-deterministic
* code and code with side-effects. Actions are often used to call into third-party services.
* Actions execute in a Node.js environment and can interact with the database indirectly by
* calling queries and mutations via the provided {@link ActionCtx} object. Actions need to be defined
* in the `/convex/actions directory`. Queries and mutations, on the other hand, must be defined
* outside of the `/convex/actions directory`.
* code and code with side-effects, like calling third-party services.
* They can be run in Convex's JavaScript environment or in Node.js using the "use node" directive.
* They can interact with the database indirectly by calling queries and mutations using the {@link ActionCtx}.
*
* @param func - The action. It receives a {@link ActionCtx} as its first argument.
* @param func - The action. It receives an {@link ActionCtx} as its first argument.
* @returns The wrapped action. Include this as an `export` to name it and make it accessible.
*/
export declare const action: ActionBuilderForAPI<API>;
export declare const action: ActionBuilder<"public">;
/**
* Define an action that is only accessible from other Convex functions (but not from the client).
*
* @param func - The function. It receives a {@link ActionCtx} as its first argument.
* @param func - The function. It receives an {@link ActionCtx} as its first argument.
* @returns The wrapped function. Include this as an `export` to name it and make it accessible.
*/
export declare const internalAction: InternalActionBuilderForAPI<API>;
export declare const internalAction: ActionBuilder<"internal">;
/**
* Define an HTTP endpoint.
* Define an HTTP action.
*
* This function will be used to respond to HTTP requests received by a Convex
* deployment if the requests matches the path and method where this endpoint
* is routed. Be sure to route your endpoint in `convex/http.js`.
* deployment if the requests matches the path and method where this action
* is routed. Be sure to route your action in `convex/http.js`.
*
* @param func - The endpoint function. It receives a {@link HttpEndpointCtx} as its first argument.
* @returns The wrapped endpoint function. Import this function from `convex/http.js` and route it to hook it up.
* @param func - The function. It receives an {@link ActionCtx} as its first argument.
* @returns The wrapped function. Import this function from `convex/http.js` and route it to hook it up.
*/
export declare const httpEndpoint: HttpEndpointBuilderForAPI<API>;
export declare const httpAction: HttpActionBuilder;
/**
* A set of services for use within Convex query functions.
@ -144,7 +112,7 @@ export type QueryCtx = GenericQueryCtx<DataModel>;
* The mutation context is passed as the first argument to any Convex mutation
* function run on the server.
*/
export type MutationCtx = GenericMutationCtx<DataModel, API>;
export type MutationCtx = GenericMutationCtx<DataModel>;
/**
* A set of services for use within Convex action functions.
@ -152,15 +120,7 @@ export type MutationCtx = GenericMutationCtx<DataModel, API>;
* The action context is passed as the first argument to any Convex action
* function run on the server.
*/
export type ActionCtx = GenericActionCtx<API>;
/**
* A set of services for use within Convex HTTP endpoints.
*
* The HttpEndpointCtx is passed as the first argument to any Convex HTTP
* endpoint run on the server.
*/
export type HttpEndpointCtx = GenericHttpEndpointCtx<API>;
export type ActionCtx = GenericActionCtx;
/**
* An interface to read from the database within Convex query functions.

View file

@ -4,20 +4,19 @@
*
* THIS CODE IS AUTOMATICALLY GENERATED.
*
* Generated by convex@0.12.0.
* To regenerate, run `npx convex codegen`.
* Generated by convex@0.19.0.
* To regenerate, run `npx convex dev`.
* @module
*/
import {
actionGeneric,
httpEndpointGeneric,
httpActionGeneric,
queryGeneric,
mutationGeneric,
internalActionGeneric,
internalMutationGeneric,
internalQueryGeneric,
cronJobsGeneric,
} from "convex/server";
/**
@ -64,13 +63,11 @@ export const internalMutation = internalMutationGeneric;
* Define an action in this Convex app's public API.
*
* An action is a function which can execute any JavaScript code, including non-deterministic
* code and code with side-effects. Actions are often used to call into third-party services.
* Actions execute in a Node.js environment and can interact with the database indirectly by
* calling queries and mutations via the provided {@link ActionCtx} object. Actions need to be defined
* in the `/convex/actions directory`. Queries and mutations, on the other hand, must be defined
* outside of the `/convex/actions directory`.
* code and code with side-effects, like calling third-party services.
* They can be run in Convex's JavaScript environment or in Node.js using the "use node" directive.
* They can interact with the database indirectly by calling queries and mutations using the {@link ActionCtx}.
*
* @param func - The action. It receives a {@link ActionCtx} as its first argument.
* @param func - The action. It receives an {@link ActionCtx} as its first argument.
* @returns The wrapped action. Include this as an `export` to name it and make it accessible.
*/
export const action = actionGeneric;
@ -78,40 +75,16 @@ export const action = actionGeneric;
/**
* Define an action that is only accessible from other Convex functions (but not from the client).
*
* @param func - The function. It receives a {@link ActionCtx} as its first argument.
* @param func - The function. It receives an {@link ActionCtx} as its first argument.
* @returns The wrapped function. Include this as an `export` to name it and make it accessible.
*/
export const internalAction = internalActionGeneric;
/**
* Define a Convex HTTP endpoint.
* Define a Convex HTTP action.
*
* @param func - The function. It receives an {@link HttpEndpointCtx} as its first argument, and a `Request` object
* @param func - The function. It receives an {@link ActionCtx} as its first argument, and a `Request` object
* as its second.
* @returns The wrapped endpoint function. Route a URL path to this function in `convex/http.js`.
*/
export const httpEndpoint = httpEndpointGeneric;
/**
* Returns a cron job scheduler, used to schedule Convex functions to run on a recurring basis.
*
* ```js
* // convex/crons.js
* import { cronJobs } from './_generated/server';
*
* const crons = cronJobs();
* crons.weekly(
* "weekly re-engagement email",
* {
* hourUTC: 17, // (9:30am Pacific/10:30am Daylight Savings Pacific)
* minuteUTC: 30,
* },
* "sendEmails"
* )
* export default crons;
* ```
*
* @returns The cron job scheduler object. Create this object in `convex/crons.js` and export it
* as the default export.
*/
export const cronJobs = cronJobsGeneric;
export const httpAction = httpActionGeneric;

View file

@ -1,6 +0,0 @@
import { query } from './_generated/server'
import { Doc } from './_generated/dataModel'
export default query(async ({ db }): Promise<Doc<'messages'>[]> => {
return await db.query('messages').collect()
})

View file

@ -0,0 +1,13 @@
import { query, mutation } from './_generated/server'
import { Doc } from './_generated/dataModel'
export const list = query(async ({ db }): Promise<Doc<'messages'>[]> => {
return await db.query('messages').collect()
})
export const send = mutation(
async ({ db }, { body, author }: { body: string; author: string }) => {
const message = { body, author }
await db.insert('messages', message)
}
)

View file

@ -1,8 +1,9 @@
import { defineSchema, defineTable, s } from 'convex/schema'
import { defineSchema, defineTable } from 'convex/server'
import { v } from 'convex/values'
export default defineSchema({
messages: defineTable({
author: s.string(),
body: s.string(),
author: v.string(),
body: v.string(),
}),
})

View file

@ -1,8 +0,0 @@
import { mutation } from './_generated/server'
export default mutation(
async ({ db }, { body, author }: { body: string; author: string }) => {
const message = { body, author }
await db.insert('messages', message)
}
)

View file

@ -10,17 +10,16 @@
"start": "next start"
},
"dependencies": {
"convex": "~0.12.0",
"convex": "~0.19.0",
"next": "latest",
"react": "^18.2.0",
"react-dom": "^18.2.0"
},
"devDependencies": {
"@types/node": "^18.13.0",
"@types/react": "^18.0.28",
"@types/react-dom": "^18.0.10",
"@types/node": "^18.15.3",
"@types/react-dom": "18.0.11",
"@types/react": "18.0.37",
"npm-run-all": "^4.1.5",
"prettier": "^2.8.4",
"typescript": "^4.9.5"
}
}

View file

@ -5,9 +5,7 @@ import { ConvexProvider, ConvexReactClient } from 'convex/react'
const address = process.env.NEXT_PUBLIC_CONVEX_URL
if (!address) {
throw new Error(
'Convex address not found in env. Have you run npx convex dev for a dev deploy or npx convex deploy for prod?'
)
throw new Error('Convex deployment url not found in environment.')
}
const convex = new ConvexReactClient(address)

View file

@ -1,11 +1,12 @@
import { FormEvent, useEffect, useState } from 'react'
import { useMutation, useQuery } from '../convex/_generated/react'
import { useMutation, useQuery } from 'convex/react'
import { api } from '../convex/_generated/api'
export default function App() {
const messages = useQuery('listMessages') || []
const messages = useQuery(api.messages.list) || []
const [newMessageText, setNewMessageText] = useState('')
const sendMessage = useMutation('sendMessage')
const sendMessage = useMutation(api.messages.send)
const [name, setName] = useState('user')