@@ -4,13 +4,13 @@ A Lens type for [Effect](https://effect.website/) to easily manage nested state.
|
|||||||
|
|
||||||
## Install
|
## Install
|
||||||
```
|
```
|
||||||
npm install effect-lens@beta effect@4.0.0-beta.85
|
npm install effect-lens@beta effect@4.0.0-beta.98
|
||||||
yarn add effect-lens@beta effect@4.0.0-beta.85
|
yarn add effect-lens@beta effect@4.0.0-beta.98
|
||||||
bun add effect-lens@beta effect@4.0.0-beta.85
|
bun add effect-lens@beta effect@4.0.0-beta.98
|
||||||
```
|
```
|
||||||
|
|
||||||
## Peer dependencies
|
## Peer dependencies
|
||||||
- `effect` 4.0.0-beta.85
|
- `effect` 4.0.0-beta.98
|
||||||
|
|
||||||
|
|
||||||
## Quickstart
|
## Quickstart
|
||||||
@@ -64,7 +64,7 @@ You can also create Lenses manually using `make` by providing:
|
|||||||
- `get`: an effect that reads the current value,
|
- `get`: an effect that reads the current value,
|
||||||
- `changes`: a stream of value changes,
|
- `changes`: a stream of value changes,
|
||||||
- `commit`: an effectful write primitive,
|
- `commit`: an effectful write primitive,
|
||||||
- `lock`: an effect that produces the lock used to serialize writes.
|
- `lock`: an effect that produces the lock used to serialize writes and preserve atomicity.
|
||||||
|
|
||||||
You can get pretty creative! Here's an example of a Lens that points to a specific key of the browser `LocalStorage`:
|
You can get pretty creative! Here's an example of a Lens that points to a specific key of the browser `LocalStorage`:
|
||||||
```typescript
|
```typescript
|
||||||
@@ -101,9 +101,6 @@ const lens = Effect.all([
|
|||||||
)
|
)
|
||||||
```
|
```
|
||||||
|
|
||||||
Note: while Lens supports asynchronous effects for the proxy logic, we would recommend keeping them synchronous to preserve atomicity.
|
|
||||||
|
|
||||||
|
|
||||||
### Focusing
|
### Focusing
|
||||||
|
|
||||||
Lenses can focus on a nested part of the data type they point to.
|
Lenses can focus on a nested part of the data type they point to.
|
||||||
@@ -242,30 +239,33 @@ const nameLens = lens.pipe(
|
|||||||
|
|
||||||
### View
|
### View
|
||||||
|
|
||||||
Effect 4 no longer provides its former `Subscribable` and `Readable` abstractions. This library provides a `View` interface, which you can use as a constraint to allow some parts of your app to only read and subscribe to the Lenses you provide them:
|
A `View` is a read-only, reactive view of a value: it lets you read the current value and observe subsequent changes. Every `Lens` is also a `View`, which you can use as a constraint to allow some parts of your app to only read and subscribe to the Lenses you provide them. It replaces Effect v3's `Subscribable` module:
|
||||||
```typescript
|
```typescript
|
||||||
const ref = yield* SubscriptionRef.make<{
|
const ref = yield* SubscriptionRef.make<{
|
||||||
readonly users: readonly User[]
|
readonly users: readonly User[]
|
||||||
}>({ users: [...] })
|
}>({ users: [] })
|
||||||
|
|
||||||
const someFunctionThatShouldOnlyHaveReadonlyAccessToTheState = (
|
const logUserCount = (users: View.View<readonly User[]>) =>
|
||||||
usersView: View.View<readonly User[], never, never>
|
Effect.gen(function*() {
|
||||||
) => Effect.gen(function*() {
|
const userCount = View.map(users, users => users.length)
|
||||||
// Do whatever
|
yield* Console.log(`There are ${yield* userCount.get} users`)
|
||||||
const usersCountView = View.map(usersView, a => a.length)
|
yield* Stream.runForEach(
|
||||||
const users = yield* usersView.get
|
userCount.changes,
|
||||||
yield* Effect.forkScoped(Stream.runForEach(usersView.changes, ...))
|
count => Console.log(`There are now ${count} users`),
|
||||||
|
)
|
||||||
})
|
})
|
||||||
|
|
||||||
const lens = ref.pipe(
|
const usersLens = ref.pipe(
|
||||||
Lens.fromSubscriptionRef,
|
Lens.fromSubscriptionRef,
|
||||||
Lens.focusObjectOn("users"),
|
Lens.focusObjectOn("users"),
|
||||||
)
|
)
|
||||||
yield* someFunctionThatShouldOnlyHaveReadonlyAccessToTheState(lens)
|
yield* Effect.forkScoped(logUserCount(usersLens))
|
||||||
```
|
```
|
||||||
|
|
||||||
|
Use `Lens.asView` when you want to make that read-only boundary explicit.
|
||||||
|
|
||||||
#### Focusing
|
#### Focusing
|
||||||
This library provides a `View` module with value and error transforms, recovery (`catch`, `catchCause`, `orElse`, `orElseSucceed`, and `retry`), and transforms to narrow the focus of `View`'s, same as Lenses:
|
Views can be focused in the same way as Lenses. The `View` module also provides value and error transforms, plus recovery (`catch`, `catchCause`, `orElse`, `orElseSucceed`, and `retry`):
|
||||||
```typescript
|
```typescript
|
||||||
import { View } from "effect-lens"
|
import { View } from "effect-lens"
|
||||||
|
|
||||||
|
|||||||
@@ -64,7 +64,7 @@ You can also create Lenses manually using `make` by providing:
|
|||||||
- `get`: an effect that reads the current value,
|
- `get`: an effect that reads the current value,
|
||||||
- `changes`: a stream of value changes,
|
- `changes`: a stream of value changes,
|
||||||
- `commit`: an effectful write primitive,
|
- `commit`: an effectful write primitive,
|
||||||
- `lock`: an effect that produces the lock used to serialize writes.
|
- `lock`: an effect that produces the lock used to serialize writes and preserve atomicity.
|
||||||
|
|
||||||
You can get pretty creative! Here's an example of a Lens that points to a specific key of the browser `LocalStorage`:
|
You can get pretty creative! Here's an example of a Lens that points to a specific key of the browser `LocalStorage`:
|
||||||
```typescript
|
```typescript
|
||||||
@@ -101,9 +101,6 @@ const lens = Effect.all([
|
|||||||
)
|
)
|
||||||
```
|
```
|
||||||
|
|
||||||
Note: while Lens supports asynchronous effects for the proxy logic, we would recommend keeping them synchronous to preserve atomicity.
|
|
||||||
|
|
||||||
|
|
||||||
### Focusing
|
### Focusing
|
||||||
|
|
||||||
Lenses can focus on a nested part of the data type they point to.
|
Lenses can focus on a nested part of the data type they point to.
|
||||||
|
|||||||
Reference in New Issue
Block a user