Skip to content

Commit

Permalink
Update Convex Example (#39562)
Browse files Browse the repository at this point in the history
This makes a few changes to the Convex example app.
We're using this example app in the Convex quick start (https://docs.convex.dev/quick-start), so I want to make sure we're setting new users up for success.

Upgrade to the newest version of Convex (includes adding a tsconfig.json for Convex functions)
Switch to pinning Convex to latest
Check in generated code so the example will make more sense to users browsing on GitHub or before they regenerate the code. This required ignoring it in the global .prettierignore
Add prettier
Update styling so "Powered by Convex" appears on screen.
Switch the syntax of one function to make it type check after developers add a schema

Documentation / Examples

 Make sure the linting passes by running pnpm lint
 The examples guidelines are followed from our contributing doc

Co-authored-by: JJ Kasper <jj@jjsweb.site>
  • Loading branch information
alexcole and ijjk committed Aug 16, 2022
1 parent 059fba2 commit 11bd44f
Show file tree
Hide file tree
Showing 11 changed files with 274 additions and 9 deletions.
1 change: 1 addition & 0 deletions .prettierignore
Expand Up @@ -24,3 +24,4 @@ test/**/out/**
bench/nested-deps/pages/**/*
bench/nested-deps/components/**/*
pnpm-lock.yaml
**/convex/_generated/**
2 changes: 2 additions & 0 deletions examples/convex/.prettierignore
@@ -0,0 +1,2 @@
.next
convex/_generated
4 changes: 4 additions & 0 deletions examples/convex/.prettierrc.json
@@ -0,0 +1,4 @@
{
"singleQuote": true,
"semi": false
}
6 changes: 6 additions & 0 deletions examples/convex/convex.json
@@ -0,0 +1,6 @@
{
"authInfo": [],
"functions": "convex/",
"instanceName": "handsome-turtle-915",
"origin": "https://handsome-turtle-915.convex.cloud"
}
60 changes: 60 additions & 0 deletions examples/convex/convex/_generated/dataModel.ts
@@ -0,0 +1,60 @@
/* eslint-disable */
/**
* Generated data model types.
*
* THIS CODE IS AUTOMATICALLY GENERATED.
*
* Generated by convex@0.1.8.
* To regenerate, run `npx convex codegen`.
* @module
*/

import { AnyDataModel } from "convex/server";
import { GenericId } from "convex/values";

/**
* No `schema.ts` file found!
*
* This generated code has permissive types like `Document = any` because
* Convex doesn't know your schema. If you'd like more type safety, see
* https://docs.convex.dev/using/schemas for instructions on how to add a
* schema file.
*
* After you write a schema, rerun codegen with `npx convex codegen`.
*/

/**
* The names of all of your Convex tables.
*/
export type TableNames = string;

/**
* The type of a document stored in Convex.
*/
export type Document = any;

/**
* 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 type Id = GenericId<string>;
export const Id = GenericId;

/**
* A type describing your Convex data model.
*
* This type includes information about what tables you have, the type of
* documents stored in those tables, and the indexes defined on them.
*
* This type is used to parameterize methods like `queryGeneric` and
* `mutationGeneric` to make them type-safe.
*/
export type DataModel = AnyDataModel;
82 changes: 82 additions & 0 deletions examples/convex/convex/_generated/react.ts
@@ -0,0 +1,82 @@
/* eslint-disable */
/**
* Generated React hooks.
*
* THIS CODE IS AUTOMATICALLY GENERATED.
*
* Generated by convex@0.1.8.
* To regenerate, run `npx convex codegen`.
* @module
*/

import type getCounter from "../getCounter";
import type incrementCounter from "../incrementCounter";
import type { OptimisticLocalStore as GenericOptimisticLocalStore } from "convex/browser";
import type { ClientMutation, ClientQuery } from "convex/server";

/**
* A type describing your app's public Convex API.
*
* This `ConvexAPI` 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.
*/
export type ConvexAPI = {
queries: {
getCounter: ClientQuery<typeof getCounter>;
};
mutations: {
incrementCounter: ClientMutation<typeof incrementCounter>;
};
};

import { makeUseQuery, makeUseMutation, makeUseConvex } 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 = makeUseQuery<ConvexAPI>();

/**
* 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 = makeUseMutation<ConvexAPI>();

/**
* 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 = makeUseConvex<ConvexAPI>();

/**
* A view of the query results currently in the Convex client for use within
* optimistic updates.
*/
export type OptimisticLocalStore = GenericOptimisticLocalStore<ConvexAPI>;
79 changes: 79 additions & 0 deletions examples/convex/convex/_generated/server.ts
@@ -0,0 +1,79 @@
/* eslint-disable */
/**
* Generated utilities for implementing server-side Convex query and mutation functions.
*
* THIS CODE IS AUTOMATICALLY GENERATED.
*
* Generated by convex@0.1.8.
* To regenerate, run `npx convex codegen`.
* @module
*/

import {
makeQuery,
makeMutation,
QueryCtx as GenericQueryCtx,
MutationCtx as GenericMutationCtx,
DatabaseReader as GenericDatabaseReader,
DatabaseWriter as GenericDatabaseWriter,
} from "convex/server";
import { DataModel } from "./dataModel.js";

/**
* Define a query in this Convex app's public API.
*
* This function will be allowed to read your Convex database and will be accessible from the client.
*
* @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 const query = makeQuery<DataModel>();

/**
* Define a mutation in this Convex app's public API.
*
* This function will be allowed to modify your Convex database and will be accessible from the client.
*
* @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 const mutation = makeMutation<DataModel>();

/**
* A set of services for use within Convex query functions.
*
* The query context is passed as the first argument to any Convex query
* function run on the server.
*
* This differs from the {@link MutationCtx} because all of the services are
* read-only.
*/
export type QueryCtx = GenericQueryCtx<DataModel>;

/**
* A set of services for use within Convex mutation functions.
*
* The mutation context is passed as the first argument to any Convex mutation
* function run on the server.
*/
export type MutationCtx = GenericMutationCtx<DataModel>;

/**
* An interface to read from the database within Convex query functions.
*
* The two entry points are {@link DatabaseReader.get}, which fetches a single
* document by its {@link Id}, or {@link DatabaseReader.table}, which starts
* building a query.
*/
export type DatabaseReader = GenericDatabaseReader<DataModel>;

/**
* An interface to read from and write to the database within Convex mutation
* functions.
*
* Convex guarantees that all writes within a single mutation are
* executed atomically, so you never have to worry about partial writes leaving
* your data in an inconsistent state. See [the Convex Guide](https://docs.convex.dev/understanding/convex-fundamentals/functions#atomicity-and-optimistic-concurrency-control)
* for the guarantees Convex provides your functions.
*/
export type DatabaseWriter = GenericDatabaseWriter<DataModel>;
10 changes: 5 additions & 5 deletions examples/convex/convex/incrementCounter.ts
Expand Up @@ -7,16 +7,16 @@ export default mutation(
.filter((q) => q.eq(q.field('name'), counterName))
.first()
if (counterDoc === null) {
counterDoc = {
db.insert('counter_table', {
name: counterName,
counter: increment,
}
db.insert('counter_table', counterDoc)
})
// console.log messages appear in your browser's console and the Convex dashboard.
console.log('Created counter.')
} else {
counterDoc.counter += increment
db.replace(counterDoc._id, counterDoc)
console.log(`Value of counter is now ${counterDoc.counter}.`)
}
// Like console.log but relays log messages from the server to client.
console.log(`Value of counter is now ${counterDoc.counter}`)
}
)
28 changes: 28 additions & 0 deletions examples/convex/convex/tsconfig.json
@@ -0,0 +1,28 @@
{
/* This TypeScript project config describes the environment that
* Convex functions run in and is used to typecheck them.
* You can modify it, but some settings required to use Convex.
*/
"compilerOptions": {
/* These settings are not required by Convex and can be modified. */
"allowJs": true,
"strict": true,

/* These compiler options are required by Convex */
"target": "ESNext",
"lib": ["ES2021"],
"forceConsistentCasingInFileNames": true,
"allowSyntheticDefaultImports": true,
"module": "ESNext",
"moduleResolution": "Node",
"isolatedModules": true,
"noEmit": true,
/* Prevents node_modules from adding additional global types e.g. node types */
"types": []
},
"include": [
"./**/*",
"../node_modules/convex/dist/esm/environment/index.d.ts"
],
"exclude": ["./_generated"]
}
5 changes: 3 additions & 2 deletions examples/convex/package.json
Expand Up @@ -6,10 +6,11 @@
"start": "next start"
},
"dependencies": {
"convex": "latest",
"next": "latest",
"prettier": "^2.7.1",
"react": "^18.2.0",
"react-dom": "^18.2.0",
"convex": "^0.1.6"
"react-dom": "^18.2.0"
},
"devDependencies": {
"@types/node": "~16.11.12",
Expand Down
6 changes: 4 additions & 2 deletions examples/convex/styles/Home.module.css
@@ -1,11 +1,13 @@
.container {
padding: 0 2rem;
display: flex;
flex-direction: column;
min-height: 100vh;
}

.main {
min-height: 100vh;
padding: 4rem 0;
flex: 1;
flex: 10;
display: flex;
flex-direction: column;
justify-content: center;
Expand Down

0 comments on commit 11bd44f

Please sign in to comment.