Skip to content

Commit

Permalink
Updates docs
Browse files Browse the repository at this point in the history
  • Loading branch information
infomiho committed Feb 16, 2023
1 parent 9e79a14 commit 790bd33
Showing 1 changed file with 76 additions and 27 deletions.
103 changes: 76 additions & 27 deletions web/docs/language/features.md
Original file line number Diff line number Diff line change
Expand Up @@ -485,7 +485,7 @@ In other words, the hook returns a function whose API matches the original Actio

The `useAction` hook accepts two arguments:
- `actionFn` (required) - The Wasp Action (i.e., the client-side query function generated by Wasp based on a query declaration) you wish to enhance.
- `actionOptions` (optional) - An object configuring the extra features you want to add to the given Action. While this argument is technically optional, there is no point in using the `useAction` hook without providing it (it would be the same as using the Action directly). The Action options object supports the following fields:
- `actionOptions` (optional) - An object configuring the extra features you want to add to the given Action. While this argument is technically optional, there is no point in using the `useAction` hook without providing it (it would be the same as using the Action directly). The Action options object supports the following fields:
- `optimisticUpdates` (optional) - An array of objects where each object defines an [optimistic update](https://stackoverflow.com/a/33009713) to perform on the query cache. To define an optimistic update, you must specify the following properties:
- `getQuerySpecifier` (required) - A function returning the query specifier (i.e., a value used to address the query you want to update). A query specifier is an array specifying the query function and arguments. For example, to optimistically update the query used with `useQuery(fetchFilteredTasks, {isDone: true }]`, your `getQuerySpecifier` function would have to return the array `[fetchFilteredTasks, { isDone: true}]`. Wasp will forward the argument you pass into the decorated Action to this function (i.e., you can use the properties of the added/change item to address the query).
- `updateQuery` (required) - The function used to perform the optimistic update. It should return the desired state of the cache. Wasp will call it with the following arguments:
Expand All @@ -494,7 +494,7 @@ The `useAction` hook accepts two arguments:

**NOTE:** The `updateQuery` function must be a pure function. It must return the desired cache value identified by the `getQuerySpecifier` function and _must not_ perform any side effects. Also, make sure you only update the query caches affected by your action causing the optimistic update (Wasp cannot yet verify this). Finally, your implementation of the `updateQuery` function should work correctly regardless of the state of `oldData` (e.g., don't rely on array positioning). If you need to do something else during your optimistic update, you can directly use _react-query_'s lower-level API (read more about it [here](#advanced-usage)).

Here's an example showing how to configure the Action from the previous example to perform an optimistic update:
Here's an example showing how to configure the Action from the previous example to perform an optimistic update:
```jsx {3,9,10,11,12,13,14,15,16,27} title=src/client/pages/Task.js
import React from 'react'
import { useQuery } from '@wasp/queries'
Expand Down Expand Up @@ -532,7 +532,7 @@ const TaskPage = ({ id }) => {
)
}

export default TaskPage
export default TaskPage
```
#### Advanced usage
The `useAction` hook currently only supports specifying optimistic updates. You can expect more features in future versions of Wasp.
Expand Down Expand Up @@ -590,8 +590,8 @@ If you have server tasks that you do not want to handle as part of the normal re
* persist between server restarts
* can be retried if they fail
* can be delayed until the future
* can have a recurring schedule!
* can have a recurring schedule!

Some examples where you may want to use a `job` on the server include sending an email, making an HTTP request to some external API, or doing some nightly calculations.

### Job Executors
Expand All @@ -606,7 +606,7 @@ Currently, Wasp supports only one type of job executor, which is `PgBoss`, but i

We have selected [pg-boss](https://github.com/timgit/pg-boss/) as our first job executor to handle the low-volume, basic job queue workloads many web applications have. By using PostgreSQL (and [SKIP LOCKED](https://www.2ndquadrant.com/en/blog/what-is-select-skip-locked-for-in-postgresql-9-5/)) as its storage and synchronization mechanism, it allows us to provide many job queue pros without any additional infrastructure or complex management.

:::info
:::info
Keep in mind that pg-boss jobs run alongside your other server-side code, so they are not appropriate for CPU-heavy workloads. Additionally, some care is required if you modify scheduled jobs. Please see pg-boss details below for more information.

<details>
Expand Down Expand Up @@ -654,9 +654,9 @@ console.log(await submittedJob.pgBoss.details())
await mySpecialJob.delay(10).submit({ job: "args" })
```

And that is it! Your job will be executed by the job executor (pg-boss, in this case) as if you called `foo({ job: "args" })`.
And that is it! Your job will be executed by the job executor (pg-boss, in this case) as if you called `foo({ job: "args" })`.

Note that in our example, `foo` takes an argument, but this does not always have to be the case. It all depends on how you've implemented your worker function.
Note that in our example, `foo` takes an argument, but this does not always have to be the case. It all depends on how you've implemented your worker function.

### Recurring jobs

Expand Down Expand Up @@ -715,23 +715,23 @@ job mySpecialJob {
// Can reference context.entities.Task, for example.
}
```

- ##### `executorOptions: dict` (optional)
Executor-specific default options to use when submitting jobs. These are passed directly through and you should consult the documentation for the job executor. These can be overridden during invocation with `submit()` or in a `schedule`.

- ##### `pgBoss: JSON` (optional)
See the docs for [pg-boss](https://github.com/timgit/pg-boss/blob/8.0.0/docs/readme.md#sendname-data-options).

#### `schedule: dict` (optional)

- ##### `cron: string` (required)
A 5-placeholder format cron expression string. See rationale for minute-level precision [here](https://github.com/timgit/pg-boss/blob/8.0.0/docs/readme.md#scheduling).

_If you need help building cron expressions, Check out_ <em>[Crontab guru](https://crontab.guru/#0_*_*_*_*).</em>

- ##### `args: JSON` (optional)
The arguments to pass to the `perform.fn` function when invoked.

- ##### `executorOptions: dict` (optional)
Executor-specific options to use when submitting jobs. These are passed directly through and you should consult the documentation for the job executor. The `perform.executorOptions` are the default options, and `schedule.executorOptions` can override/extend those.

Expand Down Expand Up @@ -814,7 +814,7 @@ In the future, we will add support for picking any version you like, but we have

Wasp provides authentication and authorization support out-of-the-box. Enabling it for your app is optional and can be done by configuring the `auth` field of the `app` declaration:

```c
```c
app MyApp {
title: "My app",
//...
Expand Down Expand Up @@ -855,7 +855,7 @@ Check out this [section of our Todo app tutorial](/docs/tutorials/todo-app/06-au
Path where a successfully authenticated user will be sent upon successful login/signup.
Default value is "/".

:::note
:::note
Automatic redirect on successful login only works when using the Wasp provided [`Signup` and `Login` forms](#high-level-api)
:::

Expand All @@ -864,7 +864,7 @@ Automatic redirect on successful login only works when using the Wasp provided [
`usernameAndPassword` authentication method makes it possible to signup/login into the app by using a username and password.
This method requires that `userEntity` specified in `auth` contains `username: string` and `password: string` fields:

```c
```c
app MyApp {
title: "My app",
//...
Expand Down Expand Up @@ -916,10 +916,10 @@ export const signUp = async (args, context) => {
// ...
const newUser = context.entities.User.create({
data: {
username: args.username,
data: {
username: args.username,
password: args.password // password hashed automatically by Wasp! 🐝
}
}
})
// Your custom code after sign-up.
Expand All @@ -937,8 +937,8 @@ You don't need to worry about hashing the password yourself! Even when you are u
To disable/enable default validations, or add your own, you can modify your custom signUp function like so:
```js
const newUser = context.entities.User.create({
data: {
username: args.username,
data: {
username: args.username,
password: args.password // password hashed automatically by Wasp! 🐝
},
_waspSkipDefaultValidations: false, // can be omitted if false (default), or explicitly set to true
Expand Down Expand Up @@ -1133,7 +1133,7 @@ import AuthError from '@wasp/core/AuthError.js'
```

## Social Login Providers (OAuth 2.0)
Wasp allows you to easily add social login providers to your app.
Wasp allows you to easily add social login providers to your app.

The following is a list of links to guides that will help you get started with the currently supported providers:
- [GitHub](/docs/integrations/github)
Expand All @@ -1150,7 +1150,7 @@ When using Social Login Providers, Wasp gives you the following options:
<Tabs>
<TabItem value="google" label="Google" default>

```c
```c
auth: {
userEntity: User,
externalAuthEntity: SocialLogin,
Expand All @@ -1159,7 +1159,7 @@ When using Social Login Providers, Wasp gives you the following options:
},
}
```
<p>Add <code>google: &#123;&#125;</code> to your <code>auth.methods</code> dictionary to use it with default settings</p>
<p>By default, Wasp expects you to set two environment variables in order to use Google authentication:</p>
<ul>
Expand Down Expand Up @@ -1266,7 +1266,7 @@ If you would like to allow the user to select their own username, or some other
Alternatively, you could add a `displayName` property to your User entity and assign it using the details of their provider account. Below is an example of how to do this by using:
- the `getUserFieldsFn` function to configure the user's `username` or `displayName` from their provider account

We also show you how to customize the configuration of the Provider's settings using:
We also show you how to customize the configuration of the Provider's settings using:
- the `configFn` function

```c title=main.wasp {9,10,13,14,26}
Expand Down Expand Up @@ -1304,7 +1304,7 @@ psl=}
```
#### `configFn`
#### `configFn`
This function should return an object with the following shape:
<Tabs>
Expand Down Expand Up @@ -1377,20 +1377,69 @@ This function should return the user fields to use when creating a new user upon
## Client configuration

You can configure the client using the `client` field inside the `app`
declaration,
declaration,

```c
app MyApp {
title: "My app",
// ...
client: {
rootComponent: import Root from "@client/Root.jsx",
setupFn: import mySetupFunction from "@client/myClientSetupCode.js"
}
}
```

`app.client` is a dictionary with the following fields:

#### `rootComponent: ClientImport` (optional)

`rootComponent` defines the root component of your client application. It is
expected to be a React component, and Wasp will use it to wrap your entire app.
It must render its children, which are the actual pages of your application.

You can use it to define a common layout for your application:

```jsx title="src/client/Root.jsx"
export default async function Root({ children }) {
return (
<div>
<header>
<h1>My App</h1>
</header>
{children}
<footer>
<p>My App footer</p>
</footer>
</div>
)
}
```

You can use it to setup various providers that your application needs:

```jsx title="src/client/Root.jsx"
import store from './store'
import { Provider } from 'react-redux'

export default async function Root({ children }) {
return (
<Provider store={store}>
<App>{children}</App>
</Provider>
)
}

function App({ children }) {
return (
<div>
<h1>My App</h1>
{children}
</div>
)
}
```

#### `setupFn: ClientImport` (optional)

`setupFn` declares a JavaScript function that Wasp executes on the client
Expand Down

0 comments on commit 790bd33

Please sign in to comment.