fluxtuate
Version:
a javascript ES7 library for handling complex data transactions
252 lines (217 loc) • 10.4 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = undefined;
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 _retainEventDispatcher = require("../event-dispatcher/retain-event-dispatcher");
var _retainEventDispatcher2 = _interopRequireDefault(_retainEventDispatcher);
var _internals = require("./_internals");
var _internals2 = require("../event-dispatcher/_internals");
var _model = require("./model");
var _model2 = _interopRequireDefault(_model);
var _modelWrapper = require("./model-wrapper");
var _modelWrapper2 = _interopRequireDefault(_modelWrapper);
var _lang = require("lodash/lang");
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }
var models = Symbol("fluxtuateStore_models");
var modelsRetainCount = Symbol("fluxtuateStore_modelCount");
var Store = function (_RetainEventDispatche) {
_inherits(Store, _RetainEventDispatche);
function Store() {
_classCallCheck(this, Store);
var _this = _possibleConstructorReturn(this, (Store.__proto__ || Object.getPrototypeOf(Store)).call(this));
_this[models] = {};
_this[modelsRetainCount] = {};
return _this;
}
_createClass(Store, [{
key: "merge",
value: function merge(store) {
var modelKeys = Object.getOwnPropertyDescriptors(store[models]);
for (var key in modelKeys) {
if (modelKeys.hasOwnProperty(key)) this[models][key] = store[models][key];
}
}
}, {
key: "onUpdate",
value: function onUpdate(callback) {
return this.addListener("update", function (ev, payload) {
callback(payload);
});
}
}, {
key: "getModel",
value: function getModel(key, context) {
if (!(0, _lang.isString)(key)) throw new Error("You must provide a key to get a model!");
if (!context) {
throw new Error("Context must be provided to get model " + key);
}
var modelsList = this[models][key];
if (!modelsList) return;
var l = modelsList.length;
for (var i = 0; i < l; i++) {
if (modelsList[i].context === context || context.hasParent(modelsList[i].context)) {
return modelsList[i];
}
}
}
}, {
key: "useModel",
value: function useModel(key, context) {
var model = this.getModel(key, context);
if (model) {
model.retainCount++;
return model;
}
}
}, {
key: "mapModel",
value: function mapModel(modelClass, context) {
var self = this;
return {
toKey: function toKey(key) {
var model = self.useModel(key, context);
if (model) {
if (model.modelClass !== modelClass) {
throw new Error("You are trying to swap the model key " + key + " with a different model value, model keys are global and must be unique in the context-tree!");
}
return model;
}
var mi = _model2.default.getInstance(modelClass, key);
model = { modelInstance: mi, storeWrapper: new _modelWrapper2.default(mi), modelClass: modelClass, context: context, retainCount: 1 };
if (!self[models][key]) self[models][key] = [];
self[models][key].push(model);
return model;
}
};
}
}, {
key: "unmapModelKey",
value: function unmapModelKey(key, context) {
var model = this.getModel(key, context);
if (!model) return;
model.retainCount--;
var isDestroyed = false;
if (model.retainCount <= 0 || model.context === context) {
model.retainCount = 0;
if (model) {
isDestroyed = true;
if (model.modelInstance.destroy) model.modelInstance.destroy();
if (model.storeWrapper.destroy) model.storeWrapper.destroy();
}
var modelIndex = this[models][key].indexOf(model);
this[models][key].splice(modelIndex, 1);
if (this[models][key].length === 0) {
delete this[models][key];
}
}
return Object.assign({}, model, { isDestroyed: isDestroyed });
}
}, {
key: "clearStore",
value: function clearStore(responsibleElement) {
var modelKeys = Object.keys(this[models]);
for (var i = 0; i < modelKeys.length; i++) {
var key = modelKeys[i];
var modelsList = this[models][key];
for (var j = 0; i < modelsList.length; j++) {
var model = modelsList[j];
if (model.storeWrapper.destroy) model.storeWrapper.destroy();
if (model.modelInstance.destroy) model.modelInstance.destroy();
model.modelInstance = undefined;
}
}
this[models] = {};
this[modelsRetainCount] = {};
}
}, {
key: "setData",
value: function setData(modelData) {
for (var key in modelData) {
if (modelData.hasOwnProperty(key)) {
if (this[models][key]) {
for (var i = 0; i < modelData[key].length; i++) {
if (this[models][key][i]) this[models][key][i].modelInstance.setValue(modelData[key][i]);
}
}
}
}
}
}, {
key: "setStore",
value: function setStore(modelClasses) {
var modelData = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
var eventMaps = {};
var modelKeys = Object.keys(this[models]);
for (var i = 0; i < modelKeys.length; i++) {
var key = modelKeys[i];
for (var j = 0; j < this[models][key].length; j++) {
var model = this[models][key][j];
if (modelClasses[key]) {
if (!eventMaps[key]) eventMaps[key] = [];
eventMaps[key][i] = model.modelInstance[_internals2.eventMap];
} else {
model.modelInstance.clear();
if (model.retainCount <= 0) {
model.retainCount = 1;
this.unmapModelKey(key, model.context);
}
}
}
}
for (var _key in modelClasses) {
if (modelClasses.hasOwnProperty(_key)) {
if (!this[models][_key]) {
this[models][_key] = [];
}
for (var _i = 0; _i < modelClasses[_key].length; _i++) {
this[models][_key][_i].modelClass = modelClasses[_key];
this[models][_key][_i].modelInstance = new modelClasses[_key](_key);
setTimeout(function (key, i) {
this[models][key][i].modelInstance.update(modelData[key] ? modelData[key][i] || {} : {});
}.bind(this, _key, _i), 0);
if (eventMaps[_key] && eventMaps[_key][_i]) this[models][_key][_i].modelInstance[_internals2.eventMap] = eventMaps[_key][_i];
}
}
}
}
}, {
key: "destroy",
value: function destroy() {
this[_internals2.destroy]();
this.clearStore();
}
}, {
key: "models",
get: function get() {
var modelClasses = {};
var modelKeys = Object.keys(this[models]);
for (var i = 0; i < modelKeys.length; i++) {
var key = modelKeys[i];
modelClasses[key] = this[models][key].map(function (modelObject) {
return modelObject.modelClass;
});
}
return modelClasses;
}
}, {
key: "data",
get: function get() {
var modelData = {};
var modelKeys = Object.keys(this[models]);
for (var i = 0; i < modelKeys.length; i++) {
var key = modelKeys[i];
modelData[key] = this[models][key].map(function (modelObject) {
return modelObject.storeWrapper.modelData;
});
}
return modelData;
}
}]);
return Store;
}(_retainEventDispatcher2.default);
exports.default = Store;