From 612c26bcad7a37fef2e07749966f38b536c40815 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Julien=20Valverd=C3=A9?= Date: Sat, 30 May 2026 05:57:50 +0200 Subject: [PATCH] Update README --- packages/effect-lens/README.md | 40 ++++++++++++++++++++++++++++++---- 1 file changed, 36 insertions(+), 4 deletions(-) diff --git a/packages/effect-lens/README.md b/packages/effect-lens/README.md index ce345eb..8e641a0 100644 --- a/packages/effect-lens/README.md +++ b/packages/effect-lens/README.md @@ -57,8 +57,6 @@ Currently available: - `fromSynchronizedRef` (note: since `SynchronizedRef` is not reactive (does not produce a stream of value changes), the resulting Lens' `changes` stream will only emit the current value of the lens when evaluated, and nothing else) - `fromRef` (returns an effect because it creates an internal lock) -More to come! - #### Manually You can also create Lenses manually using `make` by providing: - `get`: an effect that reads the current value, @@ -174,8 +172,6 @@ Currently available: | `focusChunkAt` | Focuses to an indexed entry of a `Chunk`. Replaces the parent `Chunk` immutably when writing to the focused element | Immutable | | | `focusOption` | Focuses to the value inside an `Option`. Wraps writes back into `Option.some` | Immutable | Reading or writing fails with `NoSuchElementException` when the parent option is `None` | -Also more to come! - #### Manually You can create focused Lenses by composing them manually using `map`, `mapEffect` and `unwrap`: ```typescript @@ -204,6 +200,42 @@ const benzemonstreLens = ref.pipe( // As you can see, this is automatically tracked by the Lens type ``` +#### Low-level derived lenses +For advanced cases, you can derive a Lens manually using `derive`. This is the primitive used by the built-in transforms. + +A derived Lens describes how to transform three parent channels: +- `resolve`: reads the parent and returns the focused value plus a `commit` function to rebuild the parent, +- `mapStream`: transforms the parent `changes` stream, +- `mapLock`: transforms the parent write lock. + +Most custom focusing logic should use `map` or `mapEffect`, but `derive` is useful when you need full control over read, stream, lock, and write-back behavior. + +```typescript +declare const lens: Lens.Lens + +const nameLens = lens.pipe( + Lens.derive({ + resolve: parent => Effect.map( + parent, + resolved => ({ + value: resolved.value.name, + commit: next => resolved.commit( + Effect.map(next, name => ({ + ...resolved.value, + name, + })), + ), + }), + ), + + mapStream: Stream.map(user => user.name), + + // This derived Lens does not add lock behavior, so it reuses the parent lock. + mapLock: identity, + }), +) +``` + ### Subscribable