Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/expo/results
An efficient, standards-compliant library for representing results of successful or failed operations
https://github.com/expo/results
results
Last synced: about 2 months ago
JSON representation
An efficient, standards-compliant library for representing results of successful or failed operations
- Host: GitHub
- URL: https://github.com/expo/results
- Owner: expo
- License: mit
- Created: 2020-04-29T21:16:56.000Z (over 4 years ago)
- Default Branch: main
- Last Pushed: 2023-01-07T17:39:53.000Z (over 1 year ago)
- Last Synced: 2024-04-26T01:41:25.228Z (5 months ago)
- Topics: results
- Language: TypeScript
- Size: 610 KB
- Stars: 102
- Watchers: 13
- Forks: 1
- Open Issues: 2
-
Metadata Files:
- Readme: README.md
- Changelog: CHANGELOG.md
- License: LICENSE
Awesome Lists containing this project
README
# @expo/results
[![Tests](https://github.com/expo/results/workflows/Tests/badge.svg)](https://github.com/expo/results/actions?query=branch%3Amaster)
[![codecov](https://codecov.io/gh/expo/results/branch/master/graph/badge.svg)](https://codecov.io/gh/expo/results)An efficient, standards-compliant library for representing results of successful or failed operations. A result object represents the result of an operation that can either return a value successfully or fail. Typically we'd simply either return a value or throw an error, but sometimes we perform multiple operations as a batch, some of which may succeed and others fail. Since we can't simultaneously return values and throw errors, we instead return collections of result objects. This allows a batch operation to return values for successful operations and errors for failed ones without loss of information, namely the errors. (In contrast, sometimes it is appropriate for a batch operation to return just successful values and omit values for failed operations.)
- [Usage](#usage)
- [Using Results](#using-results)
- [Creating Results](#creating-results)
- [API](#api)
- `Result`
- `ResultStatus`
- `result(value: T | Error): Result`
- `asyncResult(promise: Promise): Promise>`
- `enforceAsyncResult(resultPromise: Promise>): Promise`
- [Changelog](./CHANGELOG.md)
- [API History](./API_HISTORY.md)---
# Usage
## Using Results
```ts
import { Result, result } from '@expo/results';const results = await fetchWebPages(['https://expo.dev', 'http://example.com']);
for (const result of results) {
if (result.ok) {
console.log(result.value);
} else {
console.error(result.reason);
}
}
```## Creating Results
```ts
import { Result, result } from '@expo/results';/**
* The purpose of this result API is to let you write functions that can
* partially succeed and partially fail and return all of that information to
* the caller.
*/
function fetchWebPages(urls: string[]): Promise[]> {
return Promise.all(urls.map(fetchWebPage));
}async function fetchWebPage(url: string): Promise> {
try {
const response = await fetch(url);
const text = await response.text();
return result(text);
} catch (e) {
return result(e);
}
}// Or more idiomatically:
function fetchWebPage(url: string): Promise> {
return asyncResult(fetch(url).then(response => response.text()));
}
```---
# API
## `Result`
The main type that represents the result of either a successful operation or a failed one.
### Properties
- `ok: boolean`: whether the result represents a success or a failure. Successes always have a result value and never have a failure reason, while failures always have a failure reason and never have a result value. This property is provided for convenience instead of checking the `status` property.
- `status: ResultStatus`: the status of the result: either "fulfilled" or "rejected". This property and its possible values are the same as the `status` field of standard promise results. See the [ResultStatus](#resultstatus) enum.
- `value: T | undefined`: the value of the result, if it represents a success. This property is always `undefined` if the result represents a failure.
- `reason: Error | undefined`: the reason the operation that created the result failed, if the result represents a failure. This property is always `undefined` if the result represents a success.**TypeScript note:** when you check the `ok` or `status` properties to see if the result represents a success, the Result API is written so that the type checker knows `value` is defined and `reason` is not. This ergonomic design means you often don't need to use TypeScript's non-null assertion operator and can write `result.value` instead of `result.value!`.
### Methods
#### `enforceValue(): T`
Returns the value of this result if it represents a success, or throws the underlying error if this result represents a failure. Use this when you are certain the operation that created the result succeeded and consider it to be a programming error otherwise.
#### `enforceReason(): Error`
Returns the error that caused this failure, or throws a `TypeError` if this result actually represents a success. Use this when you are certain the operation that created the result failed and consider it to be a programming error otherwise.
### Other Behavior
#### String Coercion
When printing `Result` objects as strings (for example, inside of a template string), results that represent successes are printed as `[Success object]` and results that represent failures as printed as `[Failure object]`.
#### JSON Formatting
`Result` objects define `toJSON()` and return an object with just the `status` and either `value` or `reason` fields, depending on whether the result represents a success or failure, respectively. `Result` objects are JSON-serialized the same way as objects returned from [`Promise.allSettled()`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise/allSettled).
## `ResultStatus`
An enum whose values represent the status of a result, namely whether it is from a successful operation or a failure.
- `Fulfilled = "fulfilled"`: the status of a result that represents a success
- `Rejected = "rejected"`: the status of a result that represents a failure## `result(value: T | Error): Result`
The main function for creating `Result` objects. You may pass in any value or an error. If a value is passed in, the returned object represents a successful operation with the given value. If an error is passed in, the returned object represents a failed operation with the given reason.
Some operations don't return any values. To create a `Result` instance, call `result()` with no argument.
The `result` function does not provide a way to create a `Result` instance, that is, a result of a successful operation whose return value was an error.
## `asyncResult(promise: Promise): Promise>`
Converts a regular promise into one that always successfully resolves to a `Result` object.
If the given promise is fulfilled, its fulfillment value is used to create a success result.
Otherwise, if the given promise is rejected, its rejection reason is used to create a failure result. If the given promise is rejected with a reason other than an `Error` object, the reason is coerced to a string and used as the error message of a new `Error` object.
## `enforceAsyncResult(resultPromise: Promise>): Promise`
Converts a promise that resolves to a `Result` object into a regular promise that either resolves to a successful value or is rejected with an error. This function is the inverse of [`asyncResult`](#asyncresult).