janus
Version:
the two-faced application library-framework
287 lines (251 loc) • 8.69 kB
JavaScript
// Generated by CoffeeScript 1.12.2
(function() {
var Base, Map, Model, Nothing, Varying, cases, deepGet, deepSet, isFunction, isString, match, otherwise, ref, ref1, ref2, types,
extend = function(child, parent) { for (var key in parent) { if (hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; },
hasProp = {}.hasOwnProperty,
slice = [].slice;
Base = require('../core/base').Base;
cases = require('../core/types').from;
ref = require('../core/case'), match = ref.match, otherwise = ref.otherwise;
types = require('../core/types');
ref1 = require('../collection/map'), Map = ref1.Map, Nothing = ref1.Nothing;
Varying = require('../core/varying').Varying;
ref2 = require('../util/util'), deepGet = ref2.deepGet, deepSet = ref2.deepSet, isFunction = ref2.isFunction, isString = ref2.isString;
Model = (function(superClass) {
var mergeSchema;
extend(Model, superClass);
Model.prototype.isModel = true;
function Model(data, options) {
if (data == null) {
data = {};
}
this._attributes = {};
Model.__super__.constructor.call(this, data, options);
this._bind();
}
Model.prototype.get = function(key) {
var binding, varying;
if ((this._bindings != null) && ((binding = this._bindings[key]) != null)) {
varying = binding.parent;
if (varying.__owner == null) {
varying.__owner = this;
}
return varying;
} else {
return Model.__super__.get.call(this, key);
}
};
Model.prototype.get_ = function(key) {
var attribute, value;
value = deepGet(this.data, key);
if ((value == null) || (value === Nothing)) {
attribute = this.attribute(key);
}
if ((value == null) && (this._parent != null)) {
value = this._parent.get_(key);
if ((value != null ? value.isEnumerable : void 0) === true && ((attribute != null ? attribute.shadow : void 0) !== false)) {
value = value.shadow();
this.set(key, value);
}
}
if (value === Nothing) {
value = null;
}
if ((value == null) && (attribute != null)) {
value = attribute.initial();
if ((attribute.writeInitial === true) && (value !== void 0)) {
this.set(key, value);
}
}
return value != null ? value : null;
};
Model.prototype.attributes = function() {
var key, results;
results = [];
for (key in this.constructor.schema.attributes) {
results.push(this.attribute(key));
}
return results;
};
Model.prototype.attribute = function(key) {
var base, base1;
return (base = this._attributes)[key] != null ? base[key] : base[key] = typeof (base1 = this.constructor.schema.attributes[key]) === "function" ? new base1(this, key) : void 0;
};
Model.prototype._bind = function() {
var binding, key, pointer, ref3;
this._bindings = {};
pointer = this.pointer();
ref3 = this.constructor.schema.bindings;
for (key in ref3) {
binding = ref3[key];
this._bindings[key] = this.reactTo(binding.all.point(pointer), this.set(key));
}
};
Model.prototype.pointer = function() {
return this.pointer$ != null ? this.pointer$ : this.pointer$ = match(cases.dynamic((function(_this) {
return function(x) {
if (isFunction(x)) {
return Varying.of(x(_this));
} else if (isString(x)) {
return _this.get(x);
} else {
return Varying.of(x);
}
};
})(this)), cases.get((function(_this) {
return function(x) {
return _this.get(x);
};
})(this)), cases.subject((function(_this) {
return function(x) {
if (x != null) {
return _this.get('subject').flatMap(function(s) {
return s != null ? s.get(x) : void 0;
});
} else {
return _this.get('subject');
}
};
})(this)), cases.attribute((function(_this) {
return function(x) {
return new Varying(_this.attribute(x));
};
})(this)), cases.varying((function(_this) {
return function(x) {
if (isFunction(x)) {
return Varying.of(x(_this));
} else {
return Varying.of(x);
}
};
})(this)), cases.app((function(_this) {
return function(x) {
var app;
if ((app = _this.options.app) != null) {
if (x != null) {
return app.get(x);
} else {
return new Varying(app);
}
} else {
return cases.app();
}
};
})(this)), cases.self((function(_this) {
return function(x) {
if (isFunction(x)) {
return Varying.of(x(_this));
} else {
return Varying.of(_this);
}
};
})(this)));
};
Model.prototype.validations = function() {
return (this._validations$ != null ? this._validations$ : this._validations$ = Base.managed((function(_this) {
return function() {
var List, result;
List = require('../collection/list').List;
result = new List(_this.constructor.schema.validations).flatMap(function(binding) {
return binding.all.point(_this.pointer());
});
result.destroyWith(_this);
return result;
};
})(this)))();
};
Model.prototype.errors = function() {
return (this._errors$ != null ? this._errors$ : this._errors$ = Base.managed((function(_this) {
return function() {
return _this.validations().filter(types.validity.error.match).map(function(error) {
return error.getError();
});
};
})(this)))();
};
Model.prototype.valid = function() {
return this._valid$ != null ? this._valid$ : this._valid$ = Varying.managed(((function(_this) {
return function() {
return _this.errors();
};
})(this)), function(errors) {
return errors.length.map(function(length) {
return length === 0;
});
});
};
Model.prototype.valid_ = function() {
return this.errors().length_ === 0;
};
Model.prototype._parentChanged = function(key, newValue, oldValue) {
if (this._bindings[key] == null) {
return Model.__super__._parentChanged.call(this, key, newValue, oldValue);
}
};
Model.prototype.__destroy = function() {
var _, attribute, ref3;
Model.__super__.__destroy.call(this);
ref3 = this._attributes;
for (_ in ref3) {
attribute = ref3[_];
if (attribute != null) {
attribute.destroy();
}
}
this._attributes = null;
};
Model.schema = {
attributes: {},
bindings: {},
validations: []
};
Model.deserialize = function(data) {
var attribute, key, prop, ref3;
ref3 = this.schema.attributes;
for (key in ref3) {
attribute = ref3[key];
prop = deepGet(data, key);
if (prop != null) {
deepSet(data, key)(attribute.deserialize(prop, this));
}
}
return new this(data);
};
mergeSchema = function(x, y) {
return {
attributes: Object.assign(x.attributes, y.attributes),
bindings: Object.assign(x.bindings, y.bindings),
validations: x.validations.concat(y.validations)
};
};
Model.build = function() {
var i, len, part, parts, ref3, schema;
parts = 1 <= arguments.length ? slice.call(arguments, 0) : [];
schema = mergeSchema({
attributes: {},
bindings: {},
validations: []
}, this.schema);
for (i = 0, len = parts.length; i < len; i++) {
part = parts[i];
if ((part != null ? (ref3 = part.prototype) != null ? ref3.isModel : void 0 : void 0) === true) {
schema = mergeSchema(schema, part.schema);
} else {
part(schema);
}
}
return (function(superClass1) {
extend(_Class, superClass1);
function _Class() {
return _Class.__super__.constructor.apply(this, arguments);
}
_Class.schema = schema;
return _Class;
})(this);
};
return Model;
})(Map);
module.exports = {
Model: Model
};
}).call(this);