[go: up one dir, main page]
More Web Proxy on the site http://driver.im/
Skip to content
/ stonex Public

πŸ’‘ Simple state container for JavaScript/TypeScript applications πŸ’‘

License

Notifications You must be signed in to change notification settings

js2me/stonex

Repository files navigation

stonex

πŸŒ€ State container for JavaScript/TypeScript applications πŸŒ€οΈ

Table of Contents

What is that ?
How to use
Documentation:
- Stonex Store
- Stonex Module
- StateWorker
- createStoreBinder
License

❓ What is that ?

This is a simple and easy library for managing/storing data.
It allows you to store and manage data correctly, and also combine all business logic into separated Stonex modules.

Easily configurable, most things can be overridden if necessary.

As well as in other similar libraries, each Stonex module has its own state and actions. But, unlike other libraries, most of the Stonex features are provided "out of the box", for example, the creating asynchronous actions.

The syntax of the modules is almost identical to the syntax of the ReactJS component.

Also currently Stonex is supporting integrations with: ReactJS (react-stonex)

πŸ’‘ How to use

1. Needs to install it:

  npm i -S stonex

  # or using yarn

  yarn add stonex

2. Create a StonexModule which will contains actions and state

StonexModule gives methods setState, getState (the same as this.state), resetState

  // UsersModule.js

  import { StonexModule } from 'stonex'

  export default class UsersModule extends StonexModule {

    // required field
    state = {}

    createUser = async (id, userData) => {
      this.setState({
        ...this.state,
        [id]: {...userData}
      })

      return this.state
    }

  }

3. Create a store using class StonexStore:

  // store.js

  import { StonexStore } from 'stonex'
  import UsersModule from './UsersModule'

  const store = new StonexStore({
    users: UsersModule,
  })

4. Use store to work with modules:

  // store.js

  store.modules.users.createUser('123', { firstName: 'Foo' })

  console.log(store.modules.users.state) // { '123': { firstName: 'Foo' } }

  // you can reset state of your user module using
  store.modules.users.resetState()

  // after 'resetState' methodd your state will have initial value
  console.log(store.modules.users.state) // {}

πŸ“š Documentation

StonexStore[Source link]

import { StonexStore } from 'stonex'

Creates a new stonex store. Combining all your stonex modules together and allows to use them in your application.

Have two arguments:

  1. modules - Map of modules which will contains in stonex store.
    Each module should be extended from StonexModule class or you can create a [pure stonex module]
  2. configuration - Configuration object which need to override something inside stonex.
    Object with keys: stateWorker, modifiers
    • stateWorker[Source link] Default value is StateWorker
      Needs for overriding of all behaviour with working with state of each module.(this.setState, this.getState, etc)
    • modifiers[Source link] Default value is []
      This list of functions where function is Modifier
      Simple description about Modifier type:
        const yourModifier = (store) => {
          // it has been called when store will be created
          return (module) => {
            // it has been called when module will be created
      
            return (actionArgs, moduleName, methodName) => {
              // it has been called when some action will be called
      
            }
          }
        }

Instance of StonexStore have properties:

  • connectModule(moduleName: string, module: StonexModule | ModuleConfiguration | PureStonexModule)
    Connect Stonex Module to store
  • createStateSnapshot()
    Return snapshot of states of all modules connected to store
  • getState(moduleName: string)
    Returns state of module
  • modules: StonexModules
    Object with stonex modules where key is name of module
  • resetState(moduleName: string, callback: (state: any) => any = noop)
    Reset state of module to initial value
  • setState(moduleName: string, changes: any, callback: (state: any) => any = noop)
    Update state of module
  • storeId: number
    Unique identifier of store

Usings:

const store = new StonexStore({
  key1: StonexModule1,
  key2: StonexModule2
}, {
  stateWorker: YourStateWorker,
  modifiers: [
    YourModifier,
    SomeLogger,
    SomeStoreModifier,
  ]
})

StonexModule[Source link]

import { StonexModule } from 'stonex'

The important parent class of your stonex modules.
Provide linking store information to your stonex module and specific methods which allows to work with state.

StonexModule provides properties: this.setState, this.getState, this.resetState, this.moduleName, this.modules

setState - Update module's state
getState - Same as this.state. Returns fresh state of module
resetState - Reset state of module to the initial value
moduleName - Name of that stonex module containing in your store
modules - Reference to store modules. It allows to use other store modules inside module

Usings:

import { StonexModule } from 'stonex'

export default class AnimalsModule extends StonexModule{

  /* state */
  state = {}


  /* methods */

  createAnimal = (type, name) => {
    this.setState({
      ...this.state,
      [type]: [
        ...(this.state[type] || []),
        { name }
      ]
    })
    return this.state
  }

  createDog = (name) => this.createAnimal('dogs', name)

  createCat = (name) => this.createAnimal('cats', name)

}

Besides using StonexModule class you can create Pure Stonex module.
It is a simple object, which works the same as class which has been extended from StonexModule.

Example:
Pure Stonex Module implementation of above AnimalsModule class

export default {
  /* state */
  state: {},
  /* methods */
  createAnimal(type, name) {
    this.setState({
      ...this.state,
      [type]: [
        ...(this.state[type] || []),
        { name }
      ]
    })
    return this.state
  },
  createDog(name){ return this.createAnimal('dogs', name) },
  createCat(name){ return this.createAnimal('cats', name) },
}

Note: all methods should be not arrow functions.


StateWorker[Source link]

import { StateWorker } from 'stonex'

This is a class which do all things linked with state of each module. It provides initializing, updating and reseting state.
If will need to change behaviour of things like resetState or setState then it can helps you.

Overridden State Worker needs to send where you creating a store:

import { StonexStore, StateWorker } from 'stonex'


class YourStateWorker extends StateWorker {

  resetState(moduleInstance, callback){
    console.log(`Resetting state of ${moduleInstance.moduleName} module`)
    return super.resetState(moduleInstance, callback)
  }
}


const store = new StonexStore({
  key1: StonexModule1,
  key2: StonexModule2
}, {
  stateWorker: YourStateWorker, // HERE
  modifiers: []
})

createStoreBinder[Source link]

import { createStoreBinder } from 'stonex'

This function create an StoreBinder which needed if you want to change/override behaviour of all things which sends from store and add common methods/properties.
Factically its more needed for creating some middleware.

Example of usage:

import { createStoreBinder, StateWorker, StonexStore } from 'stonex'
import modules, { Modules } from './modules'
import Items from './modules/Items'

const store = new StonexStore(modules)


const modifiedStoreBinder = {
  ...createStoreBinder('items', store),
  cacheState: () => {
    sessionStorage.setItem('items-cache', JSON.stringify(store.modules.items.state))
  }
}

store.connectModule('items', {
  module: Items,
  storeBinder: modifiedStoreBinder
},)

store.modules.items.cacheState()

πŸ“ License

Licensed under the MIT License.