stx
A blazing fast state manager with network sync out of the box.
- Set and get deep nested paths
- Data listeners for watching changes
- Subscriptions for watching deep nested changes
- In-state references with special notation
- Create branches from a master state
- Minimum state diff is synchronised over web sockets
- Works both on server and browser
Here is a fully working Vue example
Here is the complete documentation (WIP)
Here is a persistency plugin for RocksDB
Qucik Start Guide
CRUD operations
Create
const create = const state =
Serialize
state // → { firstKey: 'value' }
Set
⚠ Default behaviour is merge.
statestate // → { firstKey: 'value', second: { subKey: 'subValue' } }
Get
state // → { subKey: 'subValue' }
Remove
statestate // → undefinedstate // → { second: { subKey: 'subValue' } }
Compute
⚠ Paths are represented as arrays for nested keys.
const subKey = statesubKey // → subValue
Get with set
Second parameter of get is a default value for the path.
⚠ It will be set
and returned if the relative path is undefined, otherwise it will be ignored.
state // → 1state // → 1
Navigate
Path
subKey // → [ 'second', 'subKey' ]
Parent
subKeyparent // → { subKey: 'subValue' }
Root
subKey // → { second: { subKey: 'subValue' }, first: 1 }
Listeners
On
⚠ A listener without a name is by default a data
listener. Fires on set
, remove
, add-key
, remove-key
.
let fired = stateconst third = stateconst listener = thirdfired // → []thirdfired // → [ 'set-changed' ]statefired // → [ 'set-changed', 'set-again' ]
Off
listenerthirdfired // → [ 'set-changed', 'set-again' ]
Emit
⚠ Events fired on a path can be listened only at exact same path.
const errors = statestateerrors // → [ 'satellites are not aligned' ]subKeysubKeyerrors // → [ 'satellites are not aligned', 'splines are not reticulated' ]
Creating branches from master state
const master = const branchA = master const branchB = master master // → undefined branchA// → { favourite: true, year: 2004, imdb: 7.5, title: 'The Edukators' }branchB// → { year: 2004, imdb: 7.5, title: 'The Edukators' }master// → { year: 2004, imdb: 7.5, title: 'The Edukators' } masterbranchB // → RbranchA // → R branchBbranchA // → R masterbranchA // → PGbranchB // → G
Listeners on branches
⚠ Events fired on master can be listened on branches and branches of branches.
fired = branchAbranchBmasterbranchAfired // → [ 'A-now', 'B-now', 'A-later' ]
References
branchB branchB // → truebranchB // → undefined
Origin
branchB// → [ '@', 'movies', 'goodByeLenin' ]branchB// → { favourite: true, year: 2003, imdb: 7.7, title: 'Good Bye Lenin' }
Data listeners on references
⚠ It is also possible to listen data
events explicitly.
fired = branchB branchBfired // → [ 'add-key-true' ]
Subscriptions
let count = 0const items = let subscription = itemscount // → 1 (fired once for existing path) itemscount // → 2 (fired once more for immediate child) itemscount // → 3 (fired once more for nested child)// i2.items.sub1.items.sub3.title === i3.title subscription
Subscription options
count = 0subscription = itemscount // → 1 (fired once for existing path) itemscount // → 1 (did not fire for ignored key) itemscount // → 2 (fired once more for 3rd level depth nested) itemscount // → 2 (did not fire for more than 3rd level depth) subscription
Over the wire
Server
const server = itemsitems
Client
const cItems = const client = cItemscItems