'use strict';

/**
 * FluxexObject is an object can be serialized and be constructed with the serialized status.
 * @class
 * @param {Object=} state - Serialized state
 */
var FluxexObject = function FluxexObject(state) {
    var copy = {};

    if ((state !== null) && ('object' === typeof state)) {
        this._context = state;
    } else {
        this._context = {};
    }
    
    if ('function' === typeof this.initialize) {
        Object.assign(copy, state);
        this.initialize();
        Object.assign(this._context, copy);
    }

};

Object.assign(FluxexObject.prototype,
/** @lends FluxexObject# */
{
    /**
     * Get a value or an object by name
     * @param {String} name - a simple key name
     * @return {Object|Number|String|Null} the value
     */
    _get: function (name) {
        return this._context[name];
    },

    /**
     * Restore the FluxexObject status by provided status object
     * @param {Object} state - the status to restore
     */
    _restore: function (state) {
        this._context = state;
    },

    /**
     * Set value by name
     * @param {String} name - a simple key name or json path
     * @return {FluxexObject} Self
     */
    _set: function (name, value) {
        this._context[name] = value;
        return this;
    },

    /**
     * Get serialized state
     * @return {String} A JSON string of current status
     */
    toString: function () {
        return JSON.stringify(this._context, function (K, V) {
            if (V === undefined) {
               console.warn('[Fluxex] undefined detected on key `' + K + '`! Please fix your store implementation to prevent store undefined into it, or you will see React client side error: `Invariant Violation: You\'re trying to render a component to the document using server rendering but the checksum was invalid.`');
            }
            return V;
        });
    }
});

module.exports = FluxexObject;

'use strict';

var stringify = function (V) {
    if ((typeof V === 'number') || (typeof V === 'boolean') || (V === undefined) || (V === null)) {
        return V;
    }

    if (V instanceof Date) {
        return 'new Date(' + V.toISOString() + ')';
    }

    if (Array.isArray(V)) {
        return '[' + V.map(function (v) {
            return stringify(V);
        }).join(',') + ']';
    }

    if (V === Object(V)) {
        return '{' + Object.keys(V).map(function (k) {
            return stringify(k) + ':' + stringify(V[k]);
        }).join(',') + '}';
    }

    return '"' + V.replace(/"/g, '\\\"') + '"';
};

/**
 * FluxexObject is an object can be serialized and be constructed with the serialized status.
 * @class
 * @param {Object=} state - Serialized state
 */
var FluxexObject = function FluxexObject(state) {
    var copy = {};

    if ((state !== null) && ('object' === typeof state)) {
        this._context = state;
    } else {
        this._context = {};
    }
    
    if ('function' === typeof this.initialize) {
        Object.assign(copy, state);
        this.initialize();
        Object.assign(this._context, copy);
    }

};

Object.assign(FluxexObject.prototype,
/** @lends FluxexObject# */
{
    /**
     * Get a value or an object by name
     * @param {String} name - a simple key name
     * @return {Object|Number|String|Null} the value
     */
    _get: function (name) {
        return this._context[name];
    },

    /**
     * Restore the FluxexObject status by provided status object
     * @param {Object} state - the status to restore
     */
    _restore: function (state) {
        this._context = state;
    },

    /**
     * Set value by name
     * @param {String} name - a simple key name or json path
     * @return {FluxexObject} Self
     */
    _set: function (name, value) {
        this._context[name] = value;
        return this;
    },

    /**
     * Get serialized state
     * @return {String} A JSON string of current status
     */
    toString: function () {
        return stringify(this._context);
    }
});

module.exports = FluxexObject;

use homemade stringify