What is that ?
How to use
Documentation:
- Stonex Store
- Stonex Module
- StateWorker
- createStoreBinder
License
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)
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) // {}
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:
- modules - Map of modules which will contains in stonex store.
Each module should be extended fromStonexModule
class or you can create a [pure stonex module] - configuration - Configuration object which need to override something inside stonex.
Object with keys:stateWorker
,modifiers
stateWorker
[Source link] Default value isStateWorker
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 aboutModifier
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 storecreateStateSnapshot()
Return snapshot of states of all modules connected to storegetState(moduleName: string)
Returns state of modulemodules: StonexModules
Object with stonex modules where key is name of moduleresetState(moduleName: string, callback: (state: any) => any = noop)
Reset state of module to initial valuesetState(moduleName: string, changes: any, callback: (state: any) => any = noop)
Update state of modulestoreId: 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()
Licensed under the MIT License.