UNPKG

js-abstract-synchronizer

Version:
215 lines (185 loc) 8.12 kB
'use strict'; Object.defineProperty(exports, "__esModule", { value: true }); var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); var _InvalidIdError = require('js-abstract-synchronizer/errors/InvalidIdError'); var _InvalidIdError2 = _interopRequireDefault(_InvalidIdError); var _NotFoundError = require('js-abstract-synchronizer/errors/NotFoundError'); var _NotFoundError2 = _interopRequireDefault(_NotFoundError); var _lodash = require('lodash'); var _lodash2 = _interopRequireDefault(_lodash); var _addMethods = require('js-abstract-synchronizer/objectManipulation/addMethods'); var _addMethods2 = _interopRequireDefault(_addMethods); var _uuid = require('uuid'); var _uuid2 = _interopRequireDefault(_uuid); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } function _toConsumableArray(arr) { if (Array.isArray(arr)) { for (var i = 0, arr2 = Array(arr.length); i < arr.length; i++) { arr2[i] = arr[i]; } return arr2; } else { return Array.from(arr); } } function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } var privates = Symbol('privates'); var createData = Symbol('createData'); var getDataToSerialize = Symbol('getDataToSerialize'); var addMethodsToThis = Symbol('addMethodsToThis'); var validateId = Symbol('validateId'); var createSerializedData = Symbol('createSerializedData'); exports.default = function (serializer) { return function () { function SerializableObject(_ref) { var object = _ref.object, prototypeName = _ref.prototypeName; _classCallCheck(this, SerializableObject); var id = _lodash2.default.isUndefined(object.id) ? _uuid2.default.v4() : object.id; this[validateId](id); this[privates] = { id: id, isBeingSaved: false, prototypeName: prototypeName, storedData: null }; this[privates].currentData = this[createData](object); this[addMethodsToThis](prototypeName); if (this.validate) { this.validate(object); } } _createClass(SerializableObject, [{ key: validateId, value: function value(id) { if (typeof id !== 'string') { throw new _InvalidIdError2.default('id must be a string'); } if (id === '') { throw new _InvalidIdError2.default('id cannot be empty'); } } }, { key: addMethodsToThis, value: function value(prototypeName) { var _this = this; var proto = serializer.getPrototype(prototypeName); if (proto) { (0, _addMethods2.default)({ getTargetInnerObject: function getTargetInnerObject() { return _this[privates].currentData.data; }, prototype: proto, target: this }); } } }, { key: createData, value: function value(object) { return { data: _lodash2.default.cloneDeep(_lodash2.default.omit(object, 'id')), id: this[privates].id, prototypeName: this[privates].prototypeName }; } }, { key: 'saveWithoutReferences', value: function saveWithoutReferences() { var _this2 = this; var data = this[getDataToSerialize](); return (_lodash2.default.isUndefined(data.prototypeName) ? this.reload().then(function () { return _this2[getDataToSerialize](); }) : Promise.resolve(data)).catch(function (error) { return error instanceof _NotFoundError2.default ? data : Promise.reject(error); }).then(function (dataToSave) { return serializer.save(dataToSave); }).then(function () { _this2[privates].storedData = _this2[createData](_this2[privates].currentData.data); _this2[privates].isBeingSaved = false; }); } }, { key: getDataToSerialize, value: function value() { return this[createSerializedData](this[privates].currentData); } }, { key: 'save', value: function save() { var _this3 = this; var objectsToSave = []; _lodash2.default.map(this[privates].currentData.data, function (value, key) { if ((typeof value === 'undefined' ? 'undefined' : _typeof(value)) === 'object' && !(value instanceof SerializableObject && value.isBeingSaved())) { var child = value instanceof SerializableObject ? value : serializer.create(value); child.setIsBeingSaved(); objectsToSave.push(child); _this3[privates].currentData.data[key] = child; } }); return Promise.all([this.saveWithoutReferences()].concat(_toConsumableArray(objectsToSave.map(function (object) { return object.save(); })))); } }, { key: 'reload', value: function reload() { var _this4 = this; return serializer.reload(this[privates].currentData.id).then(function (newObject) { var filteredObject = _lodash2.default.pick(newObject, ['id', 'data', 'prototypeName']); var newObjectWithReferences = Object.assign(filteredObject, { data: _lodash2.default.mapValues(filteredObject.data, function (value, key) { var oldValue = _this4[privates].currentData.data[key]; return oldValue instanceof SerializableObject && value.id === oldValue.getId() ? oldValue : serializer.create(value); }) }); _this4[privates].storedData = _lodash2.default.cloneDeep(newObjectWithReferences); _this4[privates].currentData = _lodash2.default.cloneDeep(newObjectWithReferences); _this4[addMethodsToThis](filteredObject.prototypeName); }); } }, { key: 'reset', value: function reset() { this[privates].currentData = _lodash2.default.cloneDeep(this[privates].storedData); } }, { key: 'isDirty', value: function isDirty() { return !_lodash2.default.isEqual(this[privates].currentData, this[privates].storedData); } }, { key: 'setIsBeingSaved', value: function setIsBeingSaved() { this[privates].isBeingSaved = true; } }, { key: 'isBeingSaved', value: function isBeingSaved() { return this[privates].isBeingSaved; } }, { key: 'getId', value: function getId() { return this[privates].id; } }, { key: createSerializedData, value: function value(data) { if (!data || !data.data) { return data; } return Object.assign({}, data, { data: _lodash2.default.mapValues(data.data, function (value) { return value instanceof SerializableObject ? { id: value.getId() } : value; }) }); } }, { key: 'getSerializedStoredData', value: function getSerializedStoredData() { return JSON.stringify(this[createSerializedData](this[privates].storedData)); } }, { key: 'getSerializedCurrentData', value: function getSerializedCurrentData() { return JSON.stringify(this[createSerializedData](this[privates].currentData)); } }]); return SerializableObject; }(); };