arrow-left

Only this pageAll pages
gitbookPowered by GitBook
1 of 18

Fractale

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Examples

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Introduction

Inspired from Mongoosearrow-up-right, it allows you to modeling your data to be explicit on data format.

It will test value of each fields and link model between them.

hashtag
Installation

npm install --save fractale

hashtag
Documentation

You can found more documentation and examples or .

hashtag
Dependencies

  • Usage of to generate a unique id for model instances.

Optional :

  • Usage of for date.

  • Usage of for color.

  • Usage of for bridge / provider.

hashtag
Contributing

Pull requests are welcome. For major changes, please open an issue first to discuss what you would like to change. Please make sure to update tests as appropriate.

See the and files for details

hashtag
License

This project is licensed under the MIT License - see the file for details

hashtag
Authors

  • Jocelyn Faihy - Web developer and Blob of Internets -

See also the list of who participated in this project.

hashtag
Thanks

Usage of for bridge.
herearrow-up-right
wikiarrow-up-right
uuidarrow-up-right
momentarrow-up-right
teintearrow-up-right
mongoosearrow-up-right
contributingarrow-up-right
code of conductarrow-up-right
LICENSEarrow-up-right
Jochlainarrow-up-right
contributorsarrow-up-right
Thanks BP
prop-typesarrow-up-right

Philosophy

Usage

hashtag
Declaration

'use strict';

const Fractale = require('fractale');

const KeyValuePair = Fractale.create(
    'KeyValuePair', /* Name of your model (required) */
    { /* Model's schema */
        key: String,
        value: undefined,
    }
);

/* More complete example */
const Model = Fractale.create(
    'Model',
    {
        mixed: undefined,
        boolean: Boolean,
        number: Number,
        string: String,
        date: Date,
        boards: [String],
        metadata: { key: String },
        inception: KeyValuePair,
        collection: [{ key: String, value: null }],
        self: Fractale.SELF, // the Model itself
    }
);

/* Full example */
const Full = Fractale.create(
    'Full',
    Model, // Full inherit Model
    {
        declareAfter: Fractale.from('After'),
        withOption: Fractale.with(String, { validator: { in: ['Foo','Bar'] } }),
    }
);

const After = Fractale.create('After', {
    start: Fractale.with(Date, { required: true, default: '2000-01-01' }),
    end: Date,
});

hashtag
Instanciation

const instance = new Model({
    mixed: 'Great !',
    boolean: true,
    number: 42,
    string: 'Hello world',
    boards: ['Lorem ipsum', 'dolores sit amet'],
    metadata: { key: 'AZERTYUIOP' },
    inception: { key: 'key', value: 1 },
    collections: [
        { key: 'foo', value: 123 },
        { key: 'bar', value: 456 }
    ]
});

console.log(instance.serialize());
/* 
> { 
    mixed: 'Great !',
    boolean: true,
    number: 42,
    string: 'Hello world',
    boards: ['Lorem ipsum', 'dolores sit amet'],
    metadata: { key: 'AZERTYUIOP' },
    inception: { key: 'key', value: 1 },
    collections: [
        { key: 'foo', value: 123 },
        { key: 'bar', value: 456 }
    ]
}
*/

/* Copy props to another instance */
// Method 1
const full = Full.from(instance);

// Method 2
const serialized = instance.serialize();
delete serialized.uuid;
const clone = new Full(serialized);

hashtag
Modification

hashtag
Array helpers

/* Array methods use */
instance.collections.push({ key: 'azertyuiop', value: 2 });
instance.collections = instance.collections.concat([{ key: 'new_key', value: 3 }, { key: 'N3W_K3Y', value: 4 }]);
console.log(instance.serialize().collections);
/*
> [
    { key: 'pass', value: 789 },
    { key: 'bar', value: 456 },
    { key: 'qwerty', value: 1 },
    { key: 'new_key', value: 3 },
    { key: 'N3W_K3Y', value: 4 }
]
*/
console.log(instance.mixed); // > true
instance.mixed = 123;
console.log(instance.mixed); // > 123

console.log(instance.boolean); // > true
instance.boolean = false;
console.log(instance.boolean); // > false

console.log(instance.number); // > 42
instance.number = 12;
console.log(instance.number); // > 12

console.log(instance.string); // > 'Hello world'
instance.string = 'Lorem ipsum';
console.log(instance.string); // > 'Lorem ipsum'

console.log(instance.boards[0]); // > 'Lorem ipsum'
instance.boards[0] = 'Hello world';
console.log(instance.boards[0]); // > 'Hello World'

console.log(instance.metadata.key); // > 'AZERTYUIOP' 
instance.metadata.key = 'foo';
console.log(instance.metadata.key); // > 'foo' 

console.log(instance.inception); // > KeyValuePair { key: 'key', value: 1 }
instance.inception = new KeyValuePair({ key: 'new_key', value: 'new_value' });
console.log(instance.inception); // > KeyValuePair { key: 'new_key', value: 'new_value' }

console.log(instance.inception); // > KeyValuePair { key: 'new_key', value: 'new_value' }
instance.inception.value = 'updated_value';
console.log(instance.inception); // > KeyValuePair { key: 'new_key', value: 'updated_value' }

console.log(instance.collections[0].key); // > 'foo'
instance.collections[0].key = 'pass';
instance.collections[0] = { value: 789 };
console.log(instance.collections[0].key); // > 'pass'
console.log(instance.collections[0].value); // > 789

console.log(instance.serialize());
/* 
> { 
    mixed: 123,
    boolean: false,
    number: 12,
    string: 'Lorem ipsum',
    boards: ['Hello world', 'dolores sit amet'],
    metadata: { key: 'foo' },
    collections: [
        { key: 'pass', value: 789 },
        { key: 'bar', value: 456 }
    ],
    inception: { key: 'new_key', value: 'updated_value' }
}
*/

Inheritance model

hashtag
Models

const Inheritance_Child = Fractale.create("Inheritance_Child", {
    value: String
});

const Inheritance_Parent = Fractale.create("Inheritance_Parent", Inheritance_Child, {
    children: [
        Inheritance_Child
    ]
});

hashtag
Run

const { Inheritance_Parent } = module.exports.get();
const instance = new Inheritance_Parent({
    value: 'Hello',
    children: [
        { value: 'world' },
        { value: 'you' },
    ]
});

_.test(instance.sayHelloTo(0), 'Hello world', `Expected "Hello world" got "${instance.sayHelloTo(0)}"`);
_.test(instance.sayHelloTo(1), 'Hello you', 'Error on parent method call');
_.test(instance.toUpperCase(), 'HELLO', 'Error on method inheritance');

resolve(instance);

hashtag
Results

Options

hashtag
Field options

hashtag
Field validators

Simple model

hashtag
Models

hashtag
Run

Plugin

Fractale add other custom types which need other optional modules

hashtag
Color

Need npm i -S teinte

{
    "uuid": "095ee570-53b7-418e-856d-1cb869b7f8cd",
    "value": "Hello",
    "children": [
        {
            "uuid": "d01623e5-8c49-4fc9-b7a8-94ae79a87dff",
            "value": "world"
        },
        {
            "uuid": "2c54c27b-b05b-4344-9e49-29985e8b8383",
            "value": "you"
        }
    ]
}
'use strict';

const Fractale = require('fractale');

Fractale.setOptions({
    use_moment: () => { try { require('moment'); return true; } catch (error) { return false; }}, // Specify to fractale to transform date to moment instance
});
'use strict';

const Fractale = require('fractale');

const Child = Fractale.create('Child', {
    mixed: undefined,
    boolean: Boolean,
    number: Number,
    string: String,
});

const Parent = Fractale.create('Parent', Child, {
    parent: Fractale.with(Fractale.SELF, {
        // Pass number of parent to number of great-parent
        through: ['number'],
    }),
    children: [
        Fractale.with(Child, {
            // Pass number of parent to mixed of child
            // Pass string of parent to string of child
            through: { number: 'mixed', string: 'string' },
        })      
    ],
});

Provider

Fractale lets you possibility to save and retrieve values in a storage

// To use Web localStorage
Fractale.memory.setProvider('local');

// To use Web sessionStorage
Fractale.memory.setProvider('session');

// To use Web cookie
Fractale.memory.setProvider('cookie', { expires: 6048e5 });

// To use Web IndexedDB
Fractale.memory.setProvider('idb', { database: 'Ć’_database' });
hashtag
Results
const Simple = Fractale.create("Simple", {
    mixed: undefined,
    boolean: Boolean,
    number: Number,
    bigint: BigInt,
    string: String,
    color: Color,
    date: Date,
    regexp: RegExp,
    buffer: ArrayBuffer,
    int8: Int8Array,
    uint8: Uint8Array,
    "uint8_clamped": Uint8ClampedArray,
    int16: Int16Array,
    uint16: Uint16Array,
    int32: Int32Array,
    uint32: Uint32Array,
    float32: Float32Array,
    float64: Float64Array,
    bigint64: BigInt64Array,
    biguint64: BigUint64Array
});
hashtag
Moment

If moment module is installed Date will be automatically transform to moment instance

Need npm i -S moment

const Colored = Fractale.create('Colored', {
    color: Fractale.Color
});

const colored = new Colored({ color: '#0f0f0f' });
console.log(colored.hsl());
const Article = Fractale.create('Article', {
    content: String,
    created_at: Date,
    updated_at: Date,
});

const article = new Article({
    content: 'This module is awesome',
    created_at: '2000-01-01',
    updated_at: '2000-01-01',
});
console.log(article.created_at.format('DD/MM/YYYY'));
'use strict';

const Fractale = require('fractale');

const Simple = Fractale.create('Simple', {
    anyway: Fractale.with(undefined, {
        validator: (value) => value !== 'A value'
    }),
    mixed: Fractale.with(undefined, {
        validator: {
            in: ['foo', 'bar', 42]
        }
    }),
    number: Fractale.with(Number, {
        validator: {
            gt: 17,
            gte: 18,
            lt: 51,
            lte: 50,
            between: [18, 50]
        }
    }),
    date: Fractale.with(Date, {
        validator: {
            gt: '2019-11-17',
            gte: new Date('2019-11-18'),
            lte: moment('2019-11-20'),
            lt: moment(),
            between: [18] // If one value is between ... and today or today and ...
        }
    }),
    string: Fractale.with(String, {
        validator: {
            like: /bar$/
        }
    }),
});
const { Simple } = module.exports.get();

const instance = new Simple({
    mixed: 'It\'s dangerous to go alone! Take this.',
    buffer: 'RnJhY3RhbGUgYnVmZmVyIHNhdmU=',
    int8: 'RnJhY3RhbGUgSW50OEFycmF5IHNhdmU=',
    uint8: 'RnJhY3RhbGUgVWludDhBcnJheSBzYXZl',
    uint8_clamped: 'RnJhY3RhbGUgVWludDhDbGFtcGVkQXJyYXkgc2F2ZQ==',
    int16: 'RnJhY3RhbGUgSW50MTZBcnJheSBzYXZl',
    uint16: 'RnJhY3RhbGUgVWludDE2QXJyYXkgdW5pdCB0ZXN0',
    int32: 'RnJhY3RhbGUgSW50MzJBcnJheSB0ZXN0',
    uint32: 'RnJhY3RhbGUgVUludDMyQXJyYXkgdGVzdGluZw==',
    float32: 'RnJhY3RhbGUgRmxvYXQzMkFycmF5IHVuaXRzIHRlc3Q=',
    float64: 'RnJhY3RhbGUgRmxvYXQ2NEFycmF5IHVuaXRzIHRlc3Q=',
    bigint64: 'RnJhY3RhbGUgQmlnSW50NjRBcnJheSB1bml0IHRlc3Q=',
    biguint64: 'RnJhY3RhbGUgQmlnVUludDY0QXJyYXkgdGVzdGluZ3M=',
});

_.test(instance.mixed, 'It\'s dangerous to go alone! Take this.', 'Error on simple accessor with type mixed');
_.test(instance.boolean, false, 'Error on simple accessor with type boolean');
_.test(instance.number, 31, 'Error on simple accessor with type number');
_.test(instance.bigint, 31n, 'Error on simple accessor with type bigint');
_.test(instance.string, 'Lorem ipsum', 'Error on simple accessor with type string');
_.test(instance.color.hex(), '#AA0000', 'Error on simple accessor with type color');
_.test(instance.date.format('DD/MM/YYYY'), '01/01/2000', 'Error on simple accessor with type date');
_.test(instance.regexp.toString(), /toto/g.toString(), 'Error on simple accessor with type bigint');
_.test(base64.encode(instance.buffer), 'RnJhY3RhbGUgYnVmZmVyIHNhdmU=', 'Error on simple accessor with type buffer');
_.test(base64.encode(instance.int8.buffer), 'RnJhY3RhbGUgSW50OEFycmF5IHNhdmU=', 'Error on simple accessor with type int8');
_.test(base64.encode(instance.uint8.buffer), 'RnJhY3RhbGUgVWludDhBcnJheSBzYXZl', 'Error on simple accessor with type uint8');
_.test(base64.encode(instance.uint8_clamped.buffer), 'RnJhY3RhbGUgVWludDhDbGFtcGVkQXJyYXkgc2F2ZQ==', 'Error on simple accessor with type uint8_clamped');
_.test(base64.encode(instance.int16.buffer), 'RnJhY3RhbGUgSW50MTZBcnJheSBzYXZl', 'Error on simple accessor with type int16');
_.test(base64.encode(instance.uint16.buffer), 'RnJhY3RhbGUgVWludDE2QXJyYXkgdW5pdCB0ZXN0', 'Error on simple accessor with type uint16');
_.test(base64.encode(instance.int32.buffer), 'RnJhY3RhbGUgSW50MzJBcnJheSB0ZXN0', 'Error on simple accessor with type int32');
_.test(base64.encode(instance.uint32.buffer), 'RnJhY3RhbGUgVUludDMyQXJyYXkgdGVzdGluZw==', 'Error on simple accessor with type uint32');
_.test(base64.encode(instance.float32.buffer), 'RnJhY3RhbGUgRmxvYXQzMkFycmF5IHVuaXRzIHRlc3Q=', 'Error on simple accessor with type float32');
_.test(base64.encode(instance.float64.buffer), 'RnJhY3RhbGUgRmxvYXQ2NEFycmF5IHVuaXRzIHRlc3Q=', 'Error on simple accessor with type float64');
_.test(base64.encode(instance.bigint64.buffer), 'RnJhY3RhbGUgQmlnSW50NjRBcnJheSB1bml0IHRlc3Q=', 'Error on simple accessor with type bigint64');
_.test(base64.encode(instance.biguint64.buffer), 'RnJhY3RhbGUgQmlnVUludDY0QXJyYXkgdGVzdGluZ3M=', 'Error on simple accessor with type biguint64');

instance.mixed = -1;
instance.boolean = true;
instance.number = 42;
instance.bigint = 42n;
instance.string = 'Dolor sit amet';
instance.color = 'rgba(0, 0, 255, 0)';

_.test(instance.mixed, -1, 'Error on simple accessor with type mixed after change');
_.test(instance.boolean, true, 'Error on simple accessor with type boolean after change');
_.test(instance.number, 42, 'Error on simple accessor with type number after change');
_.test(instance.bigint, 42n, 'Error on simple accessor with type number after change');
_.test(instance.string, 'Dolor sit amet', 'Error on simple accessor with type string after change');
_.test(instance.color.hex(), '#0000FF00', 'Error on simple accessor with type string after change');

resolve(instance);
{
    "uuid": "764a4649-6de0-4ae3-ab0c-7009cc16fcc8",
    "mixed": -1,
    "boolean": true,
    "number": 42,
    "bigint": "42",
    "string": "Dolor sit amet",
    "color": "#0000FF00",
    "date": "2000-01-01T02:00:00.000Z",
    "regexp": "/toto/g",
    "buffer": "RnJhY3RhbGUgYnVmZmVyIHNhdmU=",
    "int8": "RnJhY3RhbGUgSW50OEFycmF5IHNhdmU=",
    "uint8": "RnJhY3RhbGUgVWludDhBcnJheSBzYXZl",
    "uint8_clamped": "RnJhY3RhbGUgVWludDhDbGFtcGVkQXJyYXkgc2F2ZQ==",
    "int16": "RnJhY3RhbGUgSW50MTZBcnJheSBzYXZl",
    "uint16": "RnJhY3RhbGUgVWludDE2QXJyYXkgdW5pdCB0ZXN0",
    "int32": "RnJhY3RhbGUgSW50MzJBcnJheSB0ZXN0",
    "uint32": "RnJhY3RhbGUgVUludDMyQXJyYXkgdGVzdGluZw==",
    "float32": "RnJhY3RhbGUgRmxvYXQzMkFycmF5IHVuaXRzIHRlc3Q=",
    "float64": "RnJhY3RhbGUgRmxvYXQ2NEFycmF5IHVuaXRzIHRlc3Q=",
    "bigint64": "RnJhY3RhbGUgQmlnSW50NjRBcnJheSB1bml0IHRlc3Q=",
    "biguint64": "RnJhY3RhbGUgQmlnVUludDY0QXJyYXkgdGVzdGluZ3M="
}

Form usage

hashtag
Models

hashtag
Run

RegExp key model

hashtag
Models

hashtag
Run

hashtag
Results
const Form_Parent = Fractale.create("Form_Parent", {
    value: String
});

const Form_Child = Fractale.create("Form_Child", {
    parent: Form_Parent,
    value: String
});
const { Form_Parent, Form_Child } = module.exports.get();
const parent = new Form_Parent({ value: 'foo' });
const child = new Form_Child({ parent: parent.uuid, value: 'bar' });

_.test(child.value, 'bar', 'Error on form setter');
_.test(child.parent.value, 'foo', 'Error on form setter');

resolve(child);
hashtag
Results
const ModelWithRegExpAsKey = Fractale.create("ModelWithRegExpAsKey", {
    "/item_\\d+/i": String
});
const { ModelWithRegExpAsKey } = module.exports.get();
const instance = new ModelWithRegExpAsKey({
    item_1: 'Foo',
    item_2: 'Bar',
});

_.test(instance.item_1, 'Foo', 'Error on regexp key accessor with type string');
_.test(instance.item_2, 'Bar', 'Error on regexp key accessor with type string');

resolve(instance);
{
    "uuid": "250940e8-d1a4-4476-89e9-fcc882f55c64",
    "parent": {
        "uuid": "ab7cde95-30ed-4bdf-8872-0b03a537e3a2",
        "value": "foo"
    },
    "value": "bar"
}
{
    "uuid": "1e35cacd-193c-4cff-bbbb-d687f6023426",
    "item_1": "Foo",
    "item_2": "Bar"
}

Metadata model

hashtag
Models

const Metadata = Fractale.create("Metadata", {
    metadata: {
        key: String,
        data: {
            key: String,
            value: undefined
        }
    }
});

hashtag
Run

const { Metadata } = module.exports.get();
const instance = new Metadata({
    metadata: { key: 'Foo', data: { key: 'Bar', value: 12 } }
});

_.test(instance.metadata.key, 'Foo', 'Error on metadata accessor');

const metadata = instance.metadata;
metadata.key = 'decomposition';

_.test(instance.metadata.key, 'decomposition', 'Error on metadata accessor with decomposition');

instance.metadata.key = 'dot';
_.test(instance.metadata.key, 'dot', 'Error on metadata accessor with dot');

instance.metadata = { key: 'assign' };
_.test(instance.metadata.key, 'assign', 'Error on metadata accessor with assign');
_.test(instance.metadata.data.key, 'Bar', 'Error on metadata accessor with assign');

instance.metadata = { data: { key: 'after', value: 13 } };
_.test(instance.metadata.key, 'assign', 'Error on metadata accessor with bracket');
_.test(instance.metadata.data.key, 'after', 'Error on metadata accessor with bracket');
_.test(instance.metadata.data.value, 13, 'Error on metadata accessor with bracket');

resolve(instance);

hashtag
Results

Inception model

hashtag
Models

const Inception_Parent = Fractale.create("Inception_Parent", {
    value: String
});

const Inception_Child = Fractale.create("Inception_Child", {
    parent: Inception_Parent,
    value: String
});

hashtag
Run

const { Inception_Child } = module.exports.get();
const child = new Inception_Child({
    parent: { value: 'foo' },
    value: 'bar',
});

_.test(child.parent.value, 'foo', 'Error on inception setter with dot');

const parent = child.parent;
const value = 'hello world';
parent.value = value;
_.test(child.parent.value, value, 'Error on inception setter with dot');

child.parent.value = 'foo';
_.test(child.parent.value, 'foo', 'Error on deep setter with dot');

resolve(child);

hashtag
Results

{
    "uuid": "6c63fcf6-323a-4cb7-8bd1-afdb4d73c086",
    "metadata": {
        "uuid": "daf1d856-b57c-41a7-9a5e-407188f5f24f",
        "key": "assign",
        "data": {
            "uuid": "c22f5b47-3434-45cb-86e7-fba5134347d5",
            "key": "after",
            "value": 13
        }
    }
}
{
    "uuid": "d2dd4dd1-f369-4ed8-821e-5040deed075b",
    "parent": {
        "uuid": "33ba3961-cc86-4dbc-9945-b0691bd36d93",
        "value": "foo"
    },
    "value": "bar"
}

Collection model

hashtag
Models

const Collection_Item = Fractale.create("Collection_Item", {
    value: String
});

const Collection_Category = Fractale.create("Collection_Category", {
    items: [
        Collection_Item
    ]
});

hashtag
Run

const { Collection_Category, Collection_Item } = module.exports.get();
const item = new Collection_Item({ value: 'foo' });
const category = new Collection_Category({ items: [item, { value: 'bar' }] });

_.test(category.items[0].value, 'foo', 'Error on collection accessor with brace');
_.test(category.items[1].value, 'bar', 'Error on collection accessor with brace');

let changed = false;
category.addEventListener('change', () => changed = true);
category.items[0].value = 'hello';

if (!changed) {
    throw new Error('Error on collection change event');
}
_.test(category.items[0].value, 'hello', 'Error on collection accessor with brace after change');
_.test(category.items.first.value, 'hello', 'Error on collection method first accessor');

category.items.push({ value: 'world' });

_.test(category.items.last.value, 'world', 'Error on collection method last accessor');
_.test(category.items.map(item => item.value).join(', '), 'hello, bar, world', 'Error on array method map accessor');
_.test(category.items.filter(item => item.value === 'hello').map(item => item.value).join(', '), 'hello', 'Error on array method filter accessor');
_.test(category.items.reduce((accu, item) => `${accu} ${item.value}`, '').trim(), 'hello bar world', 'Error on array method reduce accessor');

category.items.remove(item);
if (category.items.length !== 2) throw new Error('Error on array method remove accessor');

resolve(category);

hashtag
Results

Bridge

/! Experimental

Fractale lets you possibility to transform models to other types

hashtag
Transform to Mongoose Model

Need npm i -S mongoose

const model = Model.toMongoose();

hashtag
Transform to PropTypes

Need npm i -S prop-types

{
    "uuid": "269189c4-9f16-47db-bfe0-094ed8a2a676",
    "items": [
        {
            "uuid": "6edf2663-1fb9-4b76-8c4d-724f5ef70da1",
            "value": "bar"
        },
        {
            "uuid": "522ec9e9-2920-415d-a239-79fb620227fa",
            "value": "world"
        }
    ]
}
const propTypes = Model.toPropTypes();

Performance

From a JSON of 10.45M:

  • Deserialization: ~0.895s => 11.68Mo/s

  • Read: ~0.001s

  • Serialization: ~0.304s => 34.37Mo/s

From a JSON of 339.06M:

  • Deserialization: ~3.301s => 102.71Mo/s

  • Read: ~0.001s

  • Serialization: ~1.173s => 289.05Mo/s

From a JSON of 1.27G:

  • Deserialization: ~12.942s => 98.22Mo/s

  • Read: ~0s

  • Serialization: ~6.089s => 208.77Mo/s

Self-reference model

hashtag
Models

const Self = Fractale.create("Self", {
    self: Self,
    value: String
});

hashtag
Run

const { Self } = module.exports.get();
const instance_1 = new Self({ value: 'foo' });
const instance_2 = new Self({ self: { self: instance_1, value: 'bar' }, value: 'hello' });

_.test(instance_1.value, 'foo', 'Error on deep accessor variable name');
_.test(instance_2.self.value, 'bar', 'Error on self-reference accessor');
_.test(instance_2.self.self.value, 'foo', 'Error on double self-reference accessor');
_.test(instance_2.self.self.self, undefined, 'Error infinite self-reference accessor');

resolve(instance_2);

hashtag
Results

{
    "uuid": "9ad98dd3-6e65-41e0-a592-998c68aafe95",
    "self": {
        "uuid": "3365521f-4db8-4856-a5a2-5dacda8648ba",
        "self": {
            "uuid": "49e72f5e-faa3-4948-a162-3f4abdb792f6",
            "value": "foo"
        },
        "value": "bar"
    },
    "value": "hello"
}

Global options

hashtag
Models

const Global_Options = Fractale.create("Global_Options", {
    transformed: Number
});

hashtag
Run

const { Global_Options } = module.exports.get();

const instance = new Global_Options({
    transformed: 39,
});

_.test(instance.transformed, 39, 'Error on global option transform accessor with type percentage');

instance.transformed = '10%';

_.test(instance.transformed, 0.1, 'Error on global option transform accessor with type percentage');

resolve(instance);

hashtag
Results

{
    "uuid": "325dda13-7f10-4bc1-a212-c7eaa7e9beb6",
    "transformed": 0.1
}
Graph - Complexity x Rate
Graph - Size x Rate