New Research: Supply Chain Attack on Axios Pulls Malicious Dependency from npm.Details →
Socket
Book a DemoSign in
Socket

lean-state

Package Overview
Dependencies
Maintainers
1
Versions
9
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

lean-state

A simple yet powerful way to manage state and reactive dataflow

latest
Source
npmnpm
Version
2.0.1
Version published
Maintainers
1
Created
Source

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


import { register } from 'lean-state'

type Global = {
  greeting: string
}

type Listeners =
  | 'listener1'
  | 'listener2'
  | 'listener3'

// register
const global = register<Global, Listeners>()

// 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.


import { register } from 'lean-state'

type Car = {
  make: string
  color: string
}

type Global = {
  cars: Record<string, Car>
  lastUpdatedCar: string,
  focusOnCar: string
}

type Listeners = 
  | 'listener1'
  | 'listener2'

const global = register<Global, Listeners>()

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' })

Keywords

state

FAQs

Package last updated on 24 Oct 2020

Did you know?

Socket

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Install

Related posts