state-update-builder
v0.0.8
Published
A javascript utility to navigate, update and then generate versionable copies of plain js objects
Downloads
12
Maintainers
Readme
state-update-builder
A javascript utility to navigate, update and then generate versionable copies of plain js objects
Why You Should Use It
This small lib is useful in the following scenarios:
- navigate through objects subtree and retrieve data
- shallow copy objects
- object versioning:
- you have to change data or structure of a shallow copy without affecting the original
- grant immutable objects using plain objects
Install
npm install --save state-update-builder
Basic Usage (ES6 syntax)
You can simply navigate and update create a copy of an object
import StateUpdateBuilder from 'state-update-builder'
let obj = {a:{ b:1},c:{ d:3}};
let builder = new StateUpdateBuilder(obj);
//set param b of a to 2
builder.traverseNode('a').set('b', 2);
let objNextState = builder.execute();
console.log(obj == objNextState) //returns false
console.log(obj.a == objNextState.a) //returns false
console.log(obj.c == objNextState.c) //returns true because only the "a" subtree is changed
PROPS
Name|Description
----|-----------
origin
| current SUB subtree node. You should consider it as readonly prop
current
| current SUB updated node. You should consider it as readonly prop
API
API to navigate object
Name|Description|Return
----|-----------|------
traverseNode(label:string)
|navigate to "label" subtree. "label" prop must be an object|a new StateUpdateBuilder (linked to caller SUB) positioned on "label" subtree
traverseList(label:string, lambda:function)
|navigate from current subtree to "label" array than into the first element of "lambda" that matches lambda condition|a new StateUpdateBuilder (linked to caller SUB) positioned on matched "label" element subtree
checkSubtree(label:string, lambda:function)
|check if "label" subtree exists in the currentNode. If "label" is an array you can use "lambda" parameter to check array item like traverseList
. If "label" is a node, you can use "lambda" to perform an extra check of its content|bool
API to update object subtree
Name|Description|Return
----|-----------|------
set(label:string, value:any)
|set "value" to "label" (original object wont be affected)|current SUB
setNode(node:any)
|replace current subtree with "node" (original object wont be affected)|current SUB
merge(label:string, value)
|merge "value" with "label" (original object wont be affected)|current SUB
mergeNode(node:object)
|merge current subtree with "node" (original object wont be affected)|current SUB
removeNode(label:string [, lambda:function])
| remove "label" subtree (original object wont be affected). If "label" is an array and you you can pass lambda to select the element you want to remove (without lambda the whole array will be removed)|current SUB
push(label:string, array:Array)
|add "array" elements into "label" array (original object wont be affected)|current SUB
unshift(label:string, array:Array)
|remove "array" elments from "label" array (original object wont be affected)|current SUB
splice(label:string, start:number, deleteCount:number, item1:any, item2:any, ...)
| call splice fn on "label" array|current SUB
apply(label:string, fn:function)
| calls "fn" passing the value of "label" then update "label" with the function result|current SUB
API to manage Current State
Name|Description|Return
----|-----------|------
checkNodeUpdated()
|check if node related to current SUB has been modified|bool
checkError()
|check if current SUB is in error|bool
resetError()
|remove error status to current SUB and to related ancestors|void
Note: the traverse functions returns a new StateUpdateBuilder linked to the caller SUB with a parent-child relationship. When a SUB generates an exception, an error status will be set and propagated to every parent SUB.
Generate object
Name|Description|Return
----|-----------|------
execute()
|generates the new object version|bool
TODO
- add more examples
- use a.b.c syntax in labels to navigate and update model at the same time