Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/js2me/stonex
💡 Simple state container for JavaScript/TypeScript applications 💡
https://github.com/js2me/stonex
data-storage predictable predictable-state redux state state-container state-management stonex-store
Last synced: about 2 months ago
JSON representation
💡 Simple state container for JavaScript/TypeScript applications 💡
- Host: GitHub
- URL: https://github.com/js2me/stonex
- Owner: js2me
- License: mit
- Created: 2019-02-27T20:59:16.000Z (almost 6 years ago)
- Default Branch: master
- Last Pushed: 2023-01-03T17:37:21.000Z (almost 2 years ago)
- Last Synced: 2024-10-04T17:25:22.027Z (3 months ago)
- Topics: data-storage, predictable, predictable-state, redux, state, state-container, state-management, stonex-store
- Language: TypeScript
- Homepage:
- Size: 1.02 MB
- Stars: 9
- Watchers: 1
- Forks: 0
- Open Issues: 16
-
Metadata Files:
- Readme: README.md
- Changelog: CHANGELOG.md
- License: LICENSE
Awesome Lists containing this project
README
[![stonex](./logo.png)](https://www.npmjs.com/package/stonex)
[![](https://img.shields.io/badge/license-MIT-red.svg)](./LICENSE)
[![](https://img.shields.io/npm/v/stonex.svg)](https://www.npmjs.com/package/stonex)
[![](https://img.shields.io/travis/acacode/stonex.svg)](https://travis-ci.org/acacode/stonex)
[![](https://img.shields.io/npm/dm/stonex.svg)](http://npm-stat.com/charts.html?package=stonex)
[![](https://badgen.net/bundlephobia/min/stonex)](https://bundlephobia.com/result?p=stonex)
[![](https://badgen.net/bundlephobia/minzip/stonex)](https://bundlephobia.com/result?p=stonex)
🌀 State container for JavaScript/TypeScript applications 🌀️
#### Table of Contents
[What is that ?](#what-is-that)
[How to use](#-how-to-use)
[Documentation](#-documentation):
- [Stonex Store](#stonexstoresource-link)
- [Stonex Module](#stonexmodulesource-link)
- [StateWorker](#stateworkersource-link)
- [createStoreBinder](#createstorebindersource-link)
[License](#-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)](https://github.com/acacode/react-stonex)
## 💡 How to use
**1.** Needs to install it:
```shell
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`
```js
// UsersModule.jsimport { 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`:
```js
// store.jsimport { StonexStore } from 'stonex'
import UsersModule from './UsersModule'const store = new StonexStore({
users: UsersModule,
})```
**4.** Use `store` to work with modules:
```js
// store.jsstore.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]](./src/StonexStore.ts#L33)
`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]](./README#L229)
2. **configuration** - Configuration object which need to override something inside stonex.
Object with keys: `stateWorker`, `modifiers`
- `stateWorker`[[Source link]](./src/StateWorker.ts#L4)
Default value is [`StateWorker`](./src/StateWorker.ts#L4)
Needs for overriding of all behaviour with working with state of each module.(`this.setState`, `this.getState`, etc)
- `modifiers`[[Source link]](./src/StateWorker.ts#L4)
Default value is `[]`
This list of functions where function is [Modifier](./src/ModifiersWorker.ts#L9)
Simple description about `Modifier` type:
```js
const yourModifier = (store) => {
// it has been called when store will be created
return (module) => {
// it has been called when module will be createdreturn (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 storeUsings:
```js
const store = new StonexStore({
key1: StonexModule1,
key2: StonexModule2
}, {
stateWorker: YourStateWorker,
modifiers: [
YourModifier,
SomeLogger,
SomeStoreModifier,
]
})
```
### `StonexModule`[[Source link]](./src/StonexModule.ts#L30)
`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 moduleUsings:
```js
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](./src/StonexModule.ts#L3).
It is a simple object, which works the same as class which has been extended from StonexModule.Example:
[Pure Stonex Module](./src/StonexModule.ts#L3) implementation of above `AnimalsModule` class
```js
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]](./src/StateWorker.ts#L33)
`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:
```js
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]](./src/StoreBinder.ts#L21)
`import { createStoreBinder } from 'stonex'`This function create an [`StoreBinder`](./src/StoreBinder.ts#L7) 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:
```js
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](./LICENSE).