Minim
A library for interacting with Refract elements
Install
npm install minim
About
In working with the XML-based DOM, there is a limitation on what types are available in the document. Element attributes may only be strings, and element values can only be strings, mixed types, and nested elements.
JSON provides additional types, which include objects, arrays, booleans, and nulls. A plain JSON document, though, provides no structure and no attributes for each property and value in the document.
Refract is a JSON structure for JSON documents to make a more flexible document object model. In Refract, each element has three components:
- Name of the element
- Metadata
- Attributes
- Content (which can be of different elements depending on the element)
An element ends up looking like this:
var el = {
element: 'string',
meta: {},
attributes: {},
content: 'bar'
};
Usage
Converting Javascript Values into Elements
var minim = require('minim');
var arrayElement = minim.convertToElement([1, 2, 3]);
var refract = arrayElement.toRefract();
The refract
variable above has the following JSON value.
{
"element": "array",
"meta": {},
"attributes": {},
"content": [
{
"element": "number",
"meta": {},
"attributes": {},
"content": 1
},
{
"element": "number",
"meta": {},
"attributes": {},
"content": 2
},
{
"element": "number",
"meta": {},
"attributes": {},
"content": 3
}
]
}
Converting Serialized Refract into Elements
Serialized Refract can be converted back to Minim elements to make a roundtrip.
var arrayElement1 = minim.convertToElement([1, 2, 3]);
var refracted = arrayElement1.toRefract();
var arrayElement2 = minim.convertFromRefract(refracted);
Extending elements
You can extend elements using the extend
static method.
var NewElement = StringElement.extend({
constructor: function() {
this.__super();
},
customMethod: function() {
}
})
See the Uptown library for usage with .extend
.
Element Attributes
Each Minim element provides the following attributes:
- element (string) - The name of the element
- meta (object) - The element's metadata
- attributes (object) - The element's attributes
- content - The element's content, e.g. a list of other elements.
Additionally, convenience attributes are exposed on the element:
- id (string) - Shortcut for
.meta.get('id').toValue()
. - name (string) - Shortcut for
.meta.get('name').toValue()
. - classes (ArrayElement) - Shortcut for
.meta.get('classes')
. - title (string) - Shortcut for
.meta.get('title').toValue()
. - description (string) - Shortcut for
.meta.get('description').toValue()
.
Note that simple types like string
are exposed through their .toValue()
result, while more complex types like the array for the classes
attribute are exposed as ArrayElement
or ObjectElement
instances.
Element Methods
Each Minim element provides the following the methods.
toValue
The toValue
method returns the JSON value of the Minim element.
var arrayElement = minim.convertToElement([1, 2, 3]);
var arrayValue = arrayElement.toValue();
toRefract
The toRefract
method returns the Refract value of the Minim element.
var arrayElement = minim.convertToElement([1, 2, 3]);
var refract = arrayElement.toRefract();
toCompactRefract
The toCompactRefract
method returns the Compact Refract value of the Minim element.
var stringElement = minim.convertToElement("foobar");
var compact = stringElement.toCompactRefract();
equals
Allows for testing equality with the content of the element.
var stringElement = minim.convertToElement("foobar");
stringElement.equals('abcd');
clone
Creates a clone of the given instance.
var stringElement = minim.convertToElement("foobar");
var stringElementClone = stringElement.clone();
Minim Elements
Minim supports the following primitive elements
NullElement
This is an element for representing the null
value.
StringElement
This is an element for representing string values.
set
The set
method sets the value of the StringElement
instance.
var stringElement = new minim.StringElement();
stringElement.set('foobar');
var value = stringElement.get()
NumberElement
This is an element for representing number values.
set
The set
method sets the value of the NumberElement
instance.
var numberElement = new minim.NumberElement();
numberElement.set(4);
var value = numberElement.get()
BooleanElement
This is an element for representing boolean values.
set
The set
method sets the value of the BooleanElement
instance.
var booleanElement = new minim.BooleanElement();
booleanElement.set(true);
var value = booleanElement.get()
ArrayElement
This is an element for representing arrays.
Iteration
The array element is iterable if the environment supports the iteration protocol. You can then use the element in for ... of
loops, use the spread operator, yield*
, and destructuring assignment.
const arrayElement = new minim.ArrayElement(['a', 'b', 'c']);
for (let item of arrayElement) {
console.log(item);
}
get
The get
method returns the item of the ArrayElement
instance at the given index.
var arrayElement = new minim.ArrayElement(['a', 'b', 'c']);
var value = arrayElement.get(0)
getValue
The getValue
method returns the value of the item of the ArrayElement
instance at the given index.
var arrayElement = new minim.ArrayElement(['a', 'b', 'c']);
var value = arrayElement.getValue(0)
getIndex
The getIndex
method returns the item of the array at a given index.
var arrayElement = new minim.ArrayElement(['a', 'b', 'c']);
var value = arrayElement.getIndex(0)
set
The set
method sets the value of the ArrayElement
instance.
var arrayElement = new minim.ArrayElement();
arrayElement.set(0, 'z');
var value = arrayElement.get(0)
map
The map
method may be used to map over an array. Each item given is a Minim instance.
var arrayElement = new minim.ArrayElement(['a', 'b', 'c']);
var newArray = arrayElement.map(function(item) {
return item.element;
});
filter
The filter
method may be used to filter a Minim array. This method returns a Minim array itself rather than a JavaScript array instance.
var arrayElement = new minim.ArrayElement(['a', 'b', 'c']);
var newArray = arrayElement.filter(function(item) {
return item.get() === 'a'
});
reduce
The reduce
method may be used to reduce over a Minim array or object. The method takes a function and an optional beginning value.
var numbers = new minim.ArrayElement([1, 2, 3, 4]);
var total = numbers.reduce(function(result, item) {
return result.toValue() + item.toValue();
});
The reduce
method also takes an initial value, which can either be a value or Minim element.
var numbers = new minim.ArrayElement([1, 2, 3, 4]);
var total = numbers.reduce(function(result, item) {
return result.toValue() + item.toValue();
}, 10);
The reduce
method also works with objects:
var objNumbers = new minim.ObjectElement({a: 1, b:2, c:3, d:4});
var total = objNumbers.reduce(function(result, item) {
return result.toValue() + item.toValue();
}, 10);
The function passed to reduce
can accept up to five optional parameters and depends on whether you are using an array element or object element:
Array
result
: the reduced value thus faritem
: the current item in the arrayindex
: the zero-based index of the current item in the arrayarrayElement
: the array element which contains item
(e.g. numbers
above)
Object
result
: the reduced value thus faritem
: the value element of the current item in the objectkey
: the key element of the current item in the objectmemberElement
: the member element which contains key
and value
objectElement
: the object element which contains memberElement
(e.g. objNumbers
above)
forEach
The forEach
method may be used to iterate over a Minim array.
var arrayElement = new minim.ArrayElement(['a', 'b', 'c']);
arrayElement.forEach(function(item) {
console.log(item.toValue())
});
push
The push
method may be used to add items to a Minim array.
var arrayElement = new minim.ArrayElement(['a', 'b', 'c']);
arrayElement.push('d');
console.log(arrayElement.toValue());
find
The find
method traverses the entire descendent element tree and returns an ArrayElement
of all elements that match the conditional function given.
var arrayElement = new minim.ArrayElement(['a', [1, 2], 'b', 3]);
var numbers = arrayElement.find(function(el) {
return el.element === 'number'
}).toValue();
findByClass
The findByClass
method traverses the entire descendent element tree and returns an ArrayElement
of all elements that match the given element name.
findByElement
The findByElement
method traverses the entire descendent element tree and returns an ArrayElement
of all elements that match the given class.
children
The children
method traverses direct descendants and returns an ArrayElement
of all elements that match the condition function given.
var arrayElement = new minim.ArrayElement(['a', [1, 2], 'b', 3]);
var numbers = arrayElement.children(function(el) {
return el.element === 'number';
}).toValue();
Because only children are tested with the condition function, the values [1, 2]
are seen as an array
type whose content is never tested. Thus, the only direct child which is a number element is 3
.
getById
Search the entire tree to find a matching ID.
elTree.getById('some-id');
contains
Test to see if a collection contains the value given. Does a deep equality check.
var arrayElement = new minim.ArrayElement(['a', [1, 2], 'b', 3]);
arrayElement.contains('a');
first
Returns the first element in the collection.
var arrayElement = new minim.ArrayElement(['a', [1, 2], 'b', 3]);
arrayElement.first();
second
Returns the second element in the collection.
var arrayElement = new minim.ArrayElement(['a', [1, 2], 'b', 3]);
arrayElement.second();
last
Returns the last element in the collection.
var arrayElement = new minim.ArrayElement(['a', [1, 2], 'b', 3]);
arrayElement.last();
ObjectElement
This is an element for representing objects. Objects store their items as an ordered array, so they inherit most of the methods above from the ArrayElement
.
get
The get
method returns the ObjectElement
instance at the given name.
See getKey
and getMember
for ways to get more instances around a key-value pair.
var objectElement = new minim.ObjectElement({ foo: 'bar' });
var value = objectElement.get('foo')
getValue
The getValue
method returns the value of the ObjectElement
instance at the given name.
var objectElement = new minim.ObjectElement({ foo: 'bar' });
var value = objectElement.getValue('foo')
getKey
The getKey
method returns the key element of a key-value pair.
var objectElement = new minim.ObjectElement({ foo: 'bar' });
var key = objectElement.getKey('foo')
getMember
The getMember
method returns the entire member for a key-value pair.
var objectElement = new minim.ObjectElement({ foo: 'bar' });
var member = objectElement.getMember('foo')
var key = member.key;
var value = member.value;
set
The set
method sets the value of the ObjectElement
instance.
var objectElement = new minim.ObjectElement();
objectElement.set('foo', 'hello world');
var value = objectElement.get('foo')
keys
The keys
method returns an array of keys.
var objectElement = new minim.ObjectElement({ foo: 'bar' });
var keys = objectElement.keys()
values
The values
method returns an array of keys.
var objectElement = new minim.ObjectElement({ foo: 'bar' });
var values = objectElement.values()
items
The items
method returns an array of key value pairs which can make iteration simpler.
const objectElement = new minim.ObjectElement({ foo: 'bar' });
for (let [key, value] of objectElement.items()) {
console.log(key, value);
}
map, filter, reduce, and forEach
The map
, filter
, and forEach
methods work similar to the ArrayElement
map function, but the callback receives the value, key, and member element instances. The reduce
method receives the reduced value, value, key, member, and object element instances.
See getMember
to see more on how to interact with member elements.
const objectElement = new minim.ObjectElement({ foo: 'bar' });
const values = objectElement.map((value, key, member) => {
return [key.toValue(), value.toValue()];
});
Element Registry
Minim allows you to register custom elements. For example, if the element name you wish to handle is called category
and it should be handled like an array:
var minim = require('minim');
minim.registry.register('category', minim.ArrayElement);
var elements = minim.fromCompactRefract(['category', {}, {}, [
['string', {}, {}, 'hello, world']
]]);
console.log(elements.get(0).content);
minim.registry.unregister('category');
Chaining
Methods may also be chained when using getters and setters.
var objectElement = new minim.ObjectElement()
.set('name', 'John Doe')
.set('email', 'john@example.com')
.set('id', 4)