https://github.com/attack-monkey/lean-state
A State Manager built for Lean Functional Typescript
https://github.com/attack-monkey/lean-state
Last synced: 29 days ago
JSON representation
A State Manager built for Lean Functional Typescript
- Host: GitHub
- URL: https://github.com/attack-monkey/lean-state
- Owner: attack-monkey
- Created: 2020-10-01T19:39:47.000Z (over 5 years ago)
- Default Branch: main
- Last Pushed: 2020-10-24T20:39:13.000Z (over 5 years ago)
- Last Synced: 2024-04-27T00:40:49.872Z (about 2 years ago)
- Language: TypeScript
- Size: 14.6 KB
- Stars: 0
- Watchers: 1
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
Awesome Lists containing this project
README
# lean-state 2.0
A State Manager built for Lean Functional Typescript
> Checkout: https://github.com/attack-monkey/Lean-Functional-Typescript
# Changes from 1.x
- Syntax changes to add more context to queries
# Install
```
npm i lean-state
```
# Use
```
import { register } from 'lean-state'
```
# Basics
```typescript
import { register } from 'lean-state'
type Global = {
greeting: string
}
type Listeners =
| 'listener1'
| 'listener2'
| 'listener3'
// register
const global = register()
// set
global.set('greeting').with('hello world')
// get
console.log(
global.get().greeting
)
// get the current and pass to function
global.once(
({ greeting }) => console.log(greeting)
)
// set up a listener...
global
.listenOn('listener1')
.for(['greeting'])
.subscribe(({ greeting }) => console.log('listener1: ' + greeting))
// make changes and the listener will react
global.set('greeting').with('howdy y\'all')
global.set('greeting').with('wassup')
global.set('greeting').with('g\'day mate')
// set up a listener that auto tears down when a condition is no longer met
global
.listenOn('listener2')
.for(['greeting'])
.while(({ greeting }) => greeting !== 'stop listening')
.subscribe(({ greeting }) => console.log('listener2: ' + greeting))
// make changes and both listeners will react
global.set('greeting').with('good day')
// this next change will trigger listener2 to tear down...
global.set('greeting').with('stop listening')
// listeners can also be set up to listen, starting from the next change...
global
.listenOn('listener3')
.fromNext(['greeting'])
.while(({ greeting }) => greeting !== 'stop listening')
.subscribe(({ greeting }) => console.log('listener3: ' + greeting))
// And more changes...
global.set('greeting').with('heeeey!!!')
global.set('greeting').with('stop listening')
```
# A complex example
Lean-state is a key-value store, so while complex data can be stored at a given key,
listeners can only listen to changes at that top-level key.
This isn't really a problem at all - but does change the way you think about listening to changes in data.
If for example a key stores a Record of items - but your app is focused on changes only at a given item - then it's a good idea to
also capture which id is being focused on and which id is being changed.
```typescript
import { register } from 'lean-state'
type Car = {
make: string
color: string
}
type Global = {
cars: Record
lastUpdatedCar: string,
focusOnCar: string
}
type Listeners =
| 'listener1'
| 'listener2'
const global = register()
const listenToAllCarChanges = () => {
global
.listenOn('listener1')
.fromNext(['lastUpdatedCar'])
.subscribe(({ cars, lastUpdatedCar }) =>
console.log(`change to car ${lastUpdatedCar} => ${JSON.stringify(cars[lastUpdatedCar], null, 2)}`)
)
}
const listenToNewFocusCar = (id: string) => {
// Set up the car to focus on
global.set('focusOnCar').with(id)
global
.listenOn('listener2')
// listen to the next change to lastUpdatedCar
.fromNext(['lastUpdatedCar'])
.subscribe(({ cars, focusOnCar, lastUpdatedCar }) => {
if(lastUpdatedCar === focusOnCar) {
console.log(`Focussed car is ${focusOnCar} and it changed to => ${JSON.stringify(cars[focusOnCar], null, 2)}`)
}
})
}
const setInitialData = () => {
global.set('cars').with({
'1': { make: 'Toyota', color: 'red' },
'2': { make: 'Toyota', color: 'blue'}
})
global.set('focusOnCar').with('1')
}
const updateCar = (id: string) => ({
with: (car: Car) => {
global.set('cars').at(id).with(car)
global.set('lastUpdatedCar').with(id)
}
})
// Set up data
setInitialData()
// Set up listeners
listenToAllCarChanges()
listenToNewFocusCar('1')
// Make updates
updateCar('3').with({ make: 'Corvette', color: 'red' })
updateCar('1').with({ make: 'Ferrari', color: 'pink' })
// Change focus car, which re-creates the listener
listenToNewFocusCar('2')
// Make more changes
updateCar('1').with({ make: 'Ferrari', color: 'red' })
updateCar('2').with({ make: 'Lamborgini', color: 'grey' })
```