# Usage

## Declaration

```javascript
'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,
});
```

## Instanciation

```javascript
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);
```

## Modification

```javascript
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' }
}
*/
```

## Array helpers

```javascript
/* 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 }
]
*/
```
