https://github.com/couzic/immutable-lens
Type-safe Lens API for immutable updates in complex data structures
https://github.com/couzic/immutable-lens
equality-check functional-lenses immutable lens state-management typescript update
Last synced: 4 months ago
JSON representation
Type-safe Lens API for immutable updates in complex data structures
- Host: GitHub
- URL: https://github.com/couzic/immutable-lens
- Owner: couzic
- License: mit
- Created: 2017-07-20T21:55:47.000Z (about 8 years ago)
- Default Branch: master
- Last Pushed: 2023-05-08T21:41:30.000Z (over 2 years ago)
- Last Synced: 2025-06-11T03:01:57.370Z (4 months ago)
- Topics: equality-check, functional-lenses, immutable, lens, state-management, typescript, update
- Language: TypeScript
- Size: 173 KB
- Stars: 8
- Watchers: 3
- Forks: 0
- Open Issues: 7
-
Metadata Files:
- Readme: README.md
Awesome Lists containing this project
README
# immutable-lens
#### Type-safe Lens API for immutable updates in deep data structures
### Features
- No mutations (obviously...)
- Human-friendly API
- Update your Redux store, your React component state, your Immutable.js collection... Whatever !
- Bring in your favorite libraries (Ramda, lodash-fp, date-fns...)
- Optimized for the strict equality checks performed in `React.PureComponent`, `connect()`...
- Written in TypeScript, designed for maximal type-safety### Quickstart
#### Install
```sh
$ npm i -S immutable-lens
```#### Create lens
```typescript
import {createLens} from 'immutable-lens'type State = {
user: {
name: string
age: number
}
}
const lens = createLens()
```#### Focus
```typescript
const userLens = lens.focusPath('user')
const nameLens = userLens.focusPath('name')
const ageLens = lens.focusPath('user', 'age')
```#### Read
```typescript
const state: State = {
user: {
name: 'Bob',
age: 18
}
}userLens.read(state) // {name: 'Bob', age: 18}
nameLens.read(state) // 'Bob'
```#### Update
```typescript
const setNameToJohn =
// THE FIVE LINES BELOW ARE ALL EQUIVALENT
nameLens.setValue('John')
nameLens.update(currentName => 'John')
userLens.setFields({name: 'John'})
userLens.updateFields({name: (currentName) => 'John'})
userLens.updatePartial(user => ({name: 'John'}))setNameToJohn(state) // {user: {name: 'John', age: 18}}
```#### Compose updates with `pipeUpdaters()`
```typescript
import {createLens, pipeUpdaters} from 'immutable-lens'type State = {
user: {
name: string
}
}const state = {
user: {
name: 'Bob',
}
}const nameLens = createLens().focusPath('user', 'name')
const setNameToJohn = nameLens.setValue('John')
const uppercaseName = nameLens.update(name => name.toUpperCase())const setNameToJOHN = pipeUpdaters(
setNameToJohn,
uppercaseName
)const updatedState = setNameToJOHN(state) // {user: {name: 'JOHN', age: 18}}
```#### Use `defaultTo()` to avoid undefined values when reading or updating optional types
```typescript
import {createLens} from 'immutable-lens'type State = {
loggedUser?: {
name: string
age: number
}
}const state = {
// optional loggedUser field is undefined
}const nameLens = createLens()
.focusOn('loggedUser')
.defaultTo({name: 'Guest', age: 0})
.focusOn('name')const name = nameLens.read(state) // 'Guest'
const setNameToBob = nameLens.setValue('Bob')
const updatedState = setNameToBob(state) // {user: {name: 'Bob', age: 0}}
```#### Focus on array index
```typescript
import {Lens, createLens} from 'immutable-lens'type Person = {
name: string
}type State = {
friends: Person[]
}const firstFriendLens = createLens()
.focusOn('friends')
.focusIndex(0)
const firstFriend: Person | undefined = firstFriendLens.read({friends: []})
```