persistent-clazz
A collection of utilities for making lightweight persistent objects (and hierarchies of such) in JS.
This library facilitates a specific style of OOP which favours composition over inheritance and immutable over mutable.
Motivation/About
Making a user friendly persistent API is tricky, especially when dealing with nested structures. You have to explicitly construct a new object on each change. You cannot just call a method of an object you reference - you have to update the reference with the new version.
However fluent persistent API's are also a real pleasure to use and they work as a very nice alternative to functional composition. JavaScript already has facilities for creating immmutable datastructures - the Object.freeze
method so all it takes to finish up the job is to define a couple of very simple helpers.
Example
The following example defines two types, Point
and Circle
, where both of them are persistent.
const clazz getter setter alias lens assign = const number = { if typeof val === 'number' return val else throw val + ' is not a number' } //Define a class-like object using the 'clazz' helper (or with any other)const Point = exports { // Create the object as you normally would. point = Pointx:1 y:2 // Apply transformations to an object to get a new one newPoint = point // The reference to the new object is updated // Old value remains unchanged // Validation functions passed in to the setter are automatically called // The properties you pass in the constructor are validated against the default values in the prototype // ""x" is set to a value of type "string" in the constructor, but it is a "number" in the object prototype." } const Circle = exports { // When there is no constructor defined, you just pass a plain object that you want to use: const circle = // You can use methods for both the host and member objects. biggerCircle = circle // //lenses and aliases cannot be created if there are no default values for the properties // The property "unexistingProperty" is undefined in the clazz please set a default value for the property before making an lens //lenses and aliases cannot be created if there are no default values for the properties // The object that is stored in "center" does not have a method "unexistingMethod" You cannot create an lens for an unexisting method }
Functions
- clazz(proto) ⇒
function
Creates a class-like object constructor.
- assign(source, target) ⇒
object
Applies a transformation to one or several properties of an object and returns a transformed object with the same prototype and the same values of non-altered properties.
- remove(source, target) ⇒
object
Applies a transformation to one or several properties of an object and returns a transformed object with the same prototype and the same values of non-altered properties.
- getter(key) ⇒
function
Creates a method that retrieves the value of a property.
- setter(key) ⇒
function
Creates a method that changes the value of a property (by creating a new version of the object).
- alias(key, methodName) ⇒
function
Creates a method that calls another method on one of the values stored in the object and returns the result. May be used for creating shorthands for calling a
getter
.- lens(key, methodName) ⇒
function
A combination between
set
andalias
. Creates a method that modifies an object's key and returns a new version of the object with the new version of the key. Can be for creating shorthands for calling asetter
.
function
clazz(proto) ⇒ Creates a class-like object constructor.
Kind: global function
Returns: function
- An object constructor which calls the prototype's constructor
method and then sets the prototype of
the resulting object to proto
.
Param | Type | Description |
---|---|---|
proto | object |
The prototype. It can contain a key called constructor with function which must return an object. If it does, this function is used as the object's constructor. If it does not, a default constructor is used. It can also contain a key called properties with a plain object specifying all properties that the object can have: default , lens , alias . See below. |
object
assign(source, target) ⇒ Applies a transformation to one or several properties of an object and returns a transformed object with the same prototype and the same values of non-altered properties.
Kind: global function
Returns: object
- A new version of the instance object.
Param | Type | Description |
---|---|---|
source | object |
The object which you want to transform. |
target | object |
A plain object containing one or several keys which are to be changed or added to the instance, along with their new values. Multiple targets are also supported. |
object
remove(source, target) ⇒ Applies a transformation to one or several properties of an object and returns a transformed object with the same prototype and the same values of non-altered properties.
Kind: global function
Returns: object
- A new version of the instance object.
Param | Type | Description |
---|---|---|
source | object |
The object which you want to transform. |
target | object |
A plain object containing one or several keys which are to be changed or added to the instance, along with their new values. Multiple targets are also supported. |
function
getter(key) ⇒ Creates a method that retrieves the value of a property.
Kind: global function
Returns: function
- A function which when attached to an object returns the current value of the property.
Param | Type | Description |
---|---|---|
key | string |
The key of the property. |
function
setter(key) ⇒ Creates a method that changes the value of a property (by creating a new version of the object).
Kind: global function
Returns: function
- A function which when attached to an object returns a new version of the object to which it is attached,
where the value of key
is changed changed to the one passed as an argument.
Param | Type | Description |
---|---|---|
key | string |
The key of the property. |
function
alias(key, methodName) ⇒ Creates a method that calls another method on one of the values stored in the object and returns the result.
May be used for creating shorthands for calling a getter
.
Kind: global function
Returns: function
- A function which when attached to an object calls the aliased method with the arguments given to it and returns the result.
Param | Type | Description |
---|---|---|
key | string |
The key where the aliased object is stored. |
methodName | string |
The name of the method. |
function
lens(key, methodName) ⇒ A combination between set
and alias
. Creates a method that modifies an object's key and returns a new version
of the object with the new version of the key. Can be for creating shorthands for calling a setter
.
Kind: global function
Returns: function
- A function which when attached to an object calls the aliased method with the arguments given to it and returns a new version of the object where the value of key
is replaced with the result of the method.
Param | Type | Description |
---|---|---|
key | string |
The key where the aliased object is stored. |
methodName | string |
The name of the method. The method should return a new version of the object. |