Immutable updater of POJO using MongoDB's operator, easier access to nested values.
const obj = foo: 1 bar: baz: 'abc' const newObj = // obj is unchanged. // assigned // assigned nested value
Installation
npm install power-assign
Using types with flow
For Flow annotations, just use /jsnext
entrypoint.
All the interfaces are defined in the depending module mongolike-operations.
Concept
OAD: Operations As Data
Operations As Data(OAD) is the concept of handling large JSON data that all the data operations (update/find) should be written as JSON format (≒ plain object). This power-assign handles UpdateOperation as data.
The previous example is also written as below.
const newObj = // this is UpdateOperation ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
The operation format is almost the same as MongoDB's Update Operators.
Here is another example using some more operators.
const obj = count: 11 arr: 'value1' bar: baz: 'abc' const newObj = assert
Phenyl Family
power-assign is one of Phenyl Family. Phenyl is a JavaScript Server/Client framework for State Synchronization over Environment(SSoE). UpdateOperation is the key to synchronize large JSON over environment. Thus power-assign plays one of the essential roles in Phenyl.
API Documentation
Definitions
For all flow type definitions, see mongolike-operations/update-operation.js.flow.
const operation = $set: 'foo.bar[0].baz': 123
operation
value is UpdateOperation.$set
is UpdateOperatorName.{ 'foo.bar[0].baz': 123 }
is UpdateOperator. In the example, it's SetOperator as the UpdateOperatorName is $set.foo.bar[0].baz
is DocumentPath.123
is Operand.
DocumentPath
The same definition as Amazon DynamoDB's DocumentPath.
DocumentPath expresses nested value location.
foo: arr: bar: 'baz'
The string 'baz'
is expressed as 'foo.arr[0].bar'
in DocumentPath format.
This DocumentPath is slightly different from Dot Notation in MongoDB which expresses 'baz'
as 'foo.arr.0.bar'
(array index expression is different).
power-assign incidentally supports Dot Notation in that an array is also an object. Still we recommend DocumentPath because Phenyl family prefers the expression.
assign()
Assign new values to object following the given operation(s).
: Object
Parameters
obj
Object to be copied and assigned new values. Note that obj is unchanged after the call. Unchanged values are shallowly copied to the returned object.
const obj = foo: bar: 1 baz: biz: 2 const newObj = // unchanged values are shallowly copied // changed values are not copied
uOps (variable arguments)
UpdateOperation, SetOperator. SetOperator is just a key-value pairs object.
All the operations are fulfilled in order.
// operations are applied in order: 1, 2, 3...
assignToProp()
Assign new values to the property of the obj located at the given documentPath following the given operation.
: Object
Parameters
obj
Object containing an object to be assigned new values. Note that obj is unchanged after the call.
uOp
UpdateOperation or SetOperator. See assign() API docs.
Example
const obj = foo: bar: 1 baz: biz: 2 const newObj =
retargetToProp()
Retarget the given UpdateOperation to the given docPath.
It helps realize loose coupling between parent object and child Object.
Even if a parent-object-handling layer doesn't know its child object's shape,
the layer can create an UpdateOperation to modify its child object using retargetToProp()
if only child-object-handling layer offers the child object's UpdateOperation.
: UpdateOperation
Parameters
docPath
DocumentPath of the new target object (target itself is not given).
operation
UpdateOperation or SetOperator. operation to be modified. Note that operation itself is unchanged. New operation object is returned.
Example
const parent = child: foo: bar: 123 const childOp = $mul: 'foo.bar': 2 const parentOp = const newParent = assert
assignWithRestoration()
Assign new values and create a new instance of the original class ( = Restoration).
assignWithRestoration<T: Restorable> obj: T uOp: SetOperator | UpdateOperation | Array<SetOperator | UpdateOperation>: T
obj must be Restorable.
What is "Restorable"?
Restorable is a characteristic of JavaScript class instances which meets the following requirement.
const jsonStr = JSONconst plain = JSONconst newInstance = plain assert
Roughly, Restorable object is an instance which can re-created by passing its JSON object to the class constructor.
See is-restorable module for more detail.
Parameters
obj
A Restorable instance.
uOp
UpdateOperation or SetOperator. See assign() API docs.
Example
{ thisfirst = paramsfirst thislast = paramslast } { thisname = paramsname thisage = paramsage }const person = name: first: 'Shin' last: 'Suzuki' age: 21 const personWithRealAge =
assignToPropWithRestoration()
The same arguments as assignToProp()
but it also restores the original object.
retargetToPropWithRestoration()
The same arguments as retargetToProp()
but it also restores the original object.
toJSON()
Convert UpdateOperation to Restorable JSON format.
{ thisfirst = paramsfirst thislast = paramslast } const person = name: first: 'Shin' last: 'Suzuki' const op = $restore: name: Name $set: 'name.first': 'Shun' assert // classes re converted to {} over serializationassert
mergeOperations()
[Experimental] Merge UpdateOperations into one UpdateOperation.
const merged = assert
normalizeOperation()
Convert SetOperator to normalized operation.
const op = 'baz.biz': 3 )assert
Update Operators
Almost the same as MongoDB's Update Operators.
$inc
An operator to increment number values.
const value =
$set
An operator to set values.
const value =
$set operator can be omitted when the whole operation is $set.
const value =
$min
An operator to compare the existing value with the given operand and set smaller one.
const value =
$max
An operator to compare the existing value with the given operand and set greater one.
const value =
$mul
An operator to multiply number values.
const value =
$addToSet
An operator to add element(s) to array values when the same value(s) doesn't exist.
const value = assert
$each
modifier can be available like MongoDB.
const value = assert
$pop
An operator to pop/shift an element from array values.
Pop:
const obj = categories: 'fashion' 'news' 'cooking-recipes' const newObj = assert
Shift:
const obj = categories: 'fashion' 'news' 'cooking-recipes' const newObj = assert
$pull
An operator to remove elements in array matching the given condition. For all condition definitions, see mongolike-operations/find-operation.js.flow.
They are almost compatible with MongoDB's Query Operators.
type PullOperator = field: DocumentPath: QueryCondition | EqCondition // type QueryCondition => See the link above.type EqCondition = Object | Array<Basic> | string | number | boolean
const obj = categories: 'fashion' 'news' 'cooking-recipes' const newObj = assert
$push
An operator to add/sort/slice/splice element(s) to array values.
Add a value:
const obj = users: id: 'user1' id: 'user2' id: 'user3' const newObj = assert
Add values:
const obj = users: id: 'user1' id: 'user2' id: 'user3' const newObj = assert
Add values to the specific position:
const obj = users: id: 'user1' id: 'user2' id: 'user3' const newObj = assert
Sort values:
const obj = users: id: 'user2' age: 31 id: 'user4' age: 35 id: 'user6' age: 24 const newObj = assert
Slice values:
const obj = users: id: 'user2' id: 'user4' id: 'user6' const newObj = assert
Slice with negative number:
const obj = users: id: 'user2' id: 'user4' id: 'user6' const newObj = assert
$bit
An operator to execute bitwise operations.
const obj = flags: const newObj =
$unset
An operator to remove values.
const obj = categories: 'fashion' 'news' 'cooking-recipes' name: first: 'Shin' last: 'Suzuki' const newObj = assert
$rename
An operator to rename field names.
const obj = ttle: 'October' names: first: 'Shin' lsat: 'Suzuki' const newObj = assert
Note that this operator is a bit different from MongoDB's $rename operator.
The operands are not 'Dot Notation' but field names. The following sample object in MongoDB
$rename: "name.first": "name.fname"
will be the following object in power-assign.
$rename: "name.first": "fname"
See that the value doesn't contain "name"
.
$restore
An operator to construct instance of the given path. New operator, Not defined at MongoDB.
type RestoreOperator = field: DocumentPath: '' | Class<Restorable>
Example:
const user = id: 'user1' name: first: 'Shin' last: 'Suzuki' age: value: 31 const newUser = const expectedNewUser = id: 'user001' name: first: 'Shinji' last: 'Suzuki' name2: first: 'Shinzo' last: 'Sasaki' age: value: 32 assert
Once RestoreOperator
is JSON.stringify-ed, the fields with Class<Restorable>
will be removed.
To avoid this, you can choose two alternatives.
- Implement static method
toJSON()
to classes.
static { return '' }
- Use
updateOperationToJSON()
function fromoad-utils
const operation = $restore: foo: Foo JSON // {"$restore":{"foo":""}}
oad-utils is also one of Phenyl family offering OAD-related utility functions.
LICENSE
Apache License 2.0