Update checked-in dependencies
This commit is contained in:
parent
7fdbca3ba3
commit
357e0ceaa9
360 changed files with 25673 additions and 917 deletions
150
node_modules/@open-draft/until/README.md
generated
vendored
Normal file
150
node_modules/@open-draft/until/README.md
generated
vendored
Normal file
|
|
@ -0,0 +1,150 @@
|
|||
[](https://www.npmjs.com/package/@open-draft/until)
|
||||
|
||||
# `until`
|
||||
|
||||
Gracefully handle a Promise using `async`/`await`.
|
||||
|
||||
## Why?
|
||||
|
||||
With the addition of `async`/`await` keywords in ECMAScript 2017 the handling of Promises became much easier. However, one must keep in mind that the `await` keyword provides no standard error handling API. Consider this usage:
|
||||
|
||||
```js
|
||||
function getUser(id) {
|
||||
const data = await fetchUser(id)
|
||||
// Work with "data"...
|
||||
}
|
||||
```
|
||||
|
||||
In case `fetchUser()` throws an error, the entire `getUser()` function's scope will terminate. Because of this, it's recommended to implement error handling using `try`/`catch` block wrapping `await` expressions:
|
||||
|
||||
```js
|
||||
function getUser(id)
|
||||
let data = null
|
||||
|
||||
try {
|
||||
data = await asyncAction()
|
||||
} catch (error) {
|
||||
console.error(error)
|
||||
}
|
||||
|
||||
// Work with "data"...
|
||||
}
|
||||
```
|
||||
|
||||
While this is a semantically valid approach, constructing `try`/`catch` around each awaited operation may be tedious and get overlooked at times. Such error handling also introduces separate closures for execution and error scenarios of an asynchronous operation.
|
||||
|
||||
This library encapsulates the `try`/`catch` error handling in a utility function that does not create a separate closure and exposes a NodeJS-friendly API to work with errors and resolved data.
|
||||
|
||||
## Getting started
|
||||
|
||||
### Install
|
||||
|
||||
```bash
|
||||
npm install @open-draft/until
|
||||
```
|
||||
|
||||
### Usage
|
||||
|
||||
```js
|
||||
import { until } from '@open-draft/until'
|
||||
|
||||
async function(id) {
|
||||
const { error, data } = await until(() => fetchUser(id))
|
||||
|
||||
if (error) {
|
||||
return handleError(error)
|
||||
}
|
||||
|
||||
return data
|
||||
}
|
||||
```
|
||||
|
||||
### Usage with TypeScript
|
||||
|
||||
```ts
|
||||
import { until } from '@open-draft/until'
|
||||
|
||||
interface User {
|
||||
firstName: string
|
||||
age: number
|
||||
}
|
||||
|
||||
interface UserFetchError {
|
||||
type: 'FORBIDDEN' | 'NOT_FOUND'
|
||||
message?: string
|
||||
}
|
||||
|
||||
async function(id: string) {
|
||||
const { error, data } = await until<UserFetchError, User>(() => fetchUser(id))
|
||||
|
||||
if (error) {
|
||||
handleError(error.type, error.message)
|
||||
}
|
||||
|
||||
return data.firstName
|
||||
}
|
||||
```
|
||||
|
||||
## Frequently asked questions
|
||||
|
||||
### Why does `until` accept a function and not a `Promise` directly?
|
||||
|
||||
This has been intentionally introduced to await a single logical unit as opposed to a single `Promise`.
|
||||
|
||||
```js
|
||||
// Notice how a single "until" invocation can handle
|
||||
// a rather complex piece of logic. This way any rejections
|
||||
// or exceptions happening within the given function
|
||||
// can be handled via the same "error".
|
||||
const { error, data } = until(async () => {
|
||||
const user = await fetchUser()
|
||||
const nextUser = normalizeUser(user)
|
||||
const transaction = await saveModel('user', user)
|
||||
|
||||
invariant(transaction.status === 'OK', 'Saving user failed')
|
||||
|
||||
return transaction.result
|
||||
})
|
||||
|
||||
if (error) {
|
||||
// Handle any exceptions happened within the function.
|
||||
}
|
||||
```
|
||||
|
||||
### Why does `until` return an object and not an array?
|
||||
|
||||
The `until` function used to return an array of shape `[error, data]` prior to `2.0.0`. That has been changed, however, to get proper type-safety using discriminated union type.
|
||||
|
||||
Compare these two examples:
|
||||
|
||||
```ts
|
||||
const [error, data] = await until(() => action())
|
||||
|
||||
if (error) {
|
||||
return null
|
||||
}
|
||||
|
||||
// Data still has ambiguous "DataType | null" type here
|
||||
// even after you've checked and handled the "error" above.
|
||||
console.log(data)
|
||||
```
|
||||
|
||||
```ts
|
||||
const result = await until(() => action())
|
||||
|
||||
// At this point, "data" is ambiguous "DataType | null"
|
||||
// which is correct, as you haven't checked nor handled the "error".
|
||||
|
||||
if (result.error) {
|
||||
return null
|
||||
}
|
||||
|
||||
// Data is strict "DataType" since you've handled the "error" above.
|
||||
console.log(result.data)
|
||||
```
|
||||
|
||||
> It's crucial to keep the entire result of the `Promise` in a single variable and not destructure it. TypeScript will always keep the type of `error` and `data` as it was upon destructuring, ignoring any type guards you may perform later on.
|
||||
|
||||
## Special thanks
|
||||
|
||||
- [giuseppegurgone](https://twitter.com/giuseppegurgone) for the discussion about the original `until` API.
|
||||
Loading…
Add table
Add a link
Reference in a new issue