New Case Study:See how Anthropic automated 95% of dependency reviews with Socket.Learn More
Socket
Sign inDemoInstall
Socket

mobx-decorated-models

Package Overview
Dependencies
Maintainers
1
Versions
49
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

mobx-decorated-models - npm Package Compare versions

Comparing version 0.3.3 to 0.4.0

13

.eslintrc.js

@@ -13,3 +13,14 @@ module.exports = {

"import/extensions": 0,
"import/no-extraneous-dependencies": [0, { devDependencies: true }]
"import/no-extraneous-dependencies": [0, { devDependencies: true }],
"key-spacing": [2, {
"singleLine": {
"beforeColon": false,
"afterColon": true
},
"multiLine": {
"beforeColon": false,
"afterColon": true,
"mode": "minimum"
}
}],
},

@@ -16,0 +27,0 @@ "globals": {

179

dist/build.full.js

@@ -22,3 +22,3 @@ (function (global, factory) {

var defaultRememberModel = function defaultRememberModel(model) {
ModelsMap[model.name] = model;
ModelsMap[model.identifiedBy || model.name] = model;
};

@@ -44,8 +44,8 @@ var rememberModel = defaultRememberModel;

function isSerializable(model, property) {
return !!(!model.$nonSerializable || -1 === model.$nonSerializable.indexOf(property));
return !!(!model.$nonSerializable || !model.$nonSerializable[property]);
}
function markNonserializable(model, property) {
model.$nonSerializable = model.$nonSerializable || [];
model.$nonSerializable.push(property);
model.$nonSerializable = model.$nonSerializable || {};
model.$nonSerializable[property] = true;
}

@@ -69,2 +69,13 @@

function objectSerializer() {
return {
serializer: function serializer(obj, prop, parent) {
return isSerializable(parent, prop) ? obj : undefined;
},
deserializer: function deserializer(json, cb) {
cb(null, json);
}
};
}
function addReference(parentModel, propName, options, cb) {

@@ -75,2 +86,3 @@ var model = findModel(propName, options);

} else {
serializr.getDefaultModelSchema(parentModel).props[propName] = objectSerializer();
PendingLookups.push({ parentModel: parentModel, propName: propName, options: options, cb: cb });

@@ -80,13 +92,2 @@ }

function objectSerializer() {
return {
serializer: function serializer(obj) {
return obj;
},
deserializer: function deserializer(json, cb) {
cb(null, json);
}
};
}
function getSerializer(options, defaultSerializer) {

@@ -126,11 +127,11 @@ var serializer = void 0;

var AsyncHandlers = {
hasMany: function hasMany(modelKlass) {
hasMany: function hasMany(modelKlass, options) {
var defaultSerializer = serializr.list(serializr.object(modelKlass));
return Object.assign(defaultSerializer, {
model: modelKlass
});
}, options);
},
belongsTo: function belongsTo(modelKlass, options, propName) {
var defaultSerializer = serializr.object(serializr.getDefaultModelSchema(modelKlass));
return {
return Object.assign({
model: modelKlass,

@@ -153,3 +154,3 @@ deserializer: function deserializer(value, cb, context) {

}
};
}, options);
}

@@ -174,3 +175,3 @@ };

function modelDecorator(model) {
function decorateModel(model, identifier$$1) {
Object.assign(model.prototype, MixedInInstanceMethods);

@@ -180,7 +181,4 @@ Object.assign(model, MixedInClassMethods);

var schema = getModelSchema(model);
registerModel(model);
var serializeSchema = {};
schema.forEach(function (_ref, name) {

@@ -194,5 +192,3 @@ var type = _ref.type,

});
serializr.createModelSchema(model, serializeSchema);
schema.forEach(function (_ref2, name) {

@@ -206,3 +202,2 @@ var type = _ref2.type,

});
for (var i = PendingLookups.length - 1; i >= 0; i -= 1) {

@@ -216,3 +211,2 @@ var _PendingLookups$i = PendingLookups[i],

var referencedModel = findModel(propName, options);
if (referencedModel) {

@@ -226,2 +220,21 @@ var parentModelSchema = serializr.getDefaultModelSchema(parentModel);

function modelDecorator(modelOrIdentifier) {
if (typeof modelOrIdentifier === 'function') {
modelOrIdentifier.identifiedBy = modelOrIdentifier.name;
return decorateModel(modelOrIdentifier);
}
return function (model) {
model.identifiedBy = modelOrIdentifier;
return decorateModel(model);
};
}
function unresolvedAssociations() {
return PendingLookups.map(function (_ref3) {
var model = _ref3.parentModel,
property = _ref3.propName;
return { model: model, property: property };
});
}
var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) {

@@ -297,3 +310,7 @@ return typeof obj;

var setupModel = mobx.action(function (_ref) {
function addLazyInitializer(target, fn) {
target.__mobxLazyInitializers.push(fn);
}
function setupModel(_ref) {
var attrs = _ref.attrs,

@@ -324,12 +341,50 @@ Klass = _ref.modelClass,

var model = Klass && !(attrs instanceof Klass) ? new Klass(attrs) : attrs;
markNonserializable(model, inverseOf);
if (inverseOf) {
markNonserializable(model, inverseOf);
}
return model;
});
}
function buildInterceptor(_ref2, parentModel, parentModelProp) {
function onBelongsToSet(change, _ref2) {
var modelClass = _ref2.modelClass,
className = _ref2.className,
defaultAttributes = _ref2.defaults,
inverseOf = _ref2.inverseOf;
defaultAttributes = _ref2.defaultAttributes,
inverseOf = _ref2.inverseOf,
parentModel = _ref2.parentModel,
parentModelProp = _ref2.parentModelProp;
change.newValue = setupModel({
attrs: change.newValue, modelClass: modelClass,
defaultAttributes: defaultAttributes, inverseOf: inverseOf, parentModel: parentModel, parentModelProp: parentModelProp
});
return change;
}
function onHasManySet(change, _ref3) {
var modelClass = _ref3.modelClass,
defaultAttributes = _ref3.defaultAttributes,
inverseOf = _ref3.inverseOf,
parentModel = _ref3.parentModel,
parentModelProp = _ref3.parentModelProp;
if (change.type !== 'update') {
return change;
}
var array = change.newValue;
for (var i = 0; i < array.length; i += 1) {
array[i] = setupModel({
attrs: array[i], array: array, modelClass: modelClass,
defaultAttributes: defaultAttributes, inverseOf: inverseOf, parentModel: parentModel, parentModelProp: parentModelProp
});
}
parentModel[parentModelProp].replace(array);
return null;
}
function onCollectionChangeInterceptor(_ref4, parentModel, parentModelProp) {
var modelClass = _ref4.modelClass,
className = _ref4.className,
defaultAttributes = _ref4.defaults,
inverseOf = _ref4.inverseOf;
return function (change) {

@@ -360,3 +415,3 @@ if (!change.newValue) {

if (options.className || options.modelClass) {
ary.intercept(buildInterceptor(options, parentModel, parentModelProp));
ary.intercept(onCollectionChangeInterceptor(options, parentModel, parentModelProp));
}

@@ -411,3 +466,29 @@ return ary;

var identifier$1 = function identifier$$1() {
function interceptingDecorator(interceptingFn) {
return function (type, target, property, descriptor) {
var options = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : {};
var decorator = addAttribute(type, target, property, descriptor, options);
addLazyInitializer(target, function (model) {
var schema = serializr.getDefaultModelSchema(target);
if (schema && schema.props[property]) {
(function () {
var schemaProps = schema.props[property];
mobx.intercept(model, property, function (change) {
return interceptingFn(change, {
inverseOf: schemaProps.inverseOf,
modelClass: schemaProps.model,
parentModel: model,
parentModelProp: property,
defaultAttributes: schemaProps.defaults
});
});
})();
}
});
return decorator;
};
}
var hasMany = function hasMany() {
for (var _len = arguments.length, args = Array(_len), _key = 0; _key < _len; _key++) {

@@ -417,5 +498,6 @@ args[_key] = arguments[_key];

return buildAttributeDecorator('identifier', args);
return buildAttributeDecorator('hasMany', args, interceptingDecorator(onHasManySet));
};
var field = function field() {
var belongsTo = function belongsTo() {
for (var _len2 = arguments.length, args = Array(_len2), _key2 = 0; _key2 < _len2; _key2++) {

@@ -425,5 +507,6 @@ args[_key2] = arguments[_key2];

return buildAttributeDecorator('field', args);
return buildAttributeDecorator('belongsTo', args, interceptingDecorator(onBelongsToSet));
};
var session = function session() {
var identifier$1 = function identifier$$1() {
for (var _len3 = arguments.length, args = Array(_len3), _key3 = 0; _key3 < _len3; _key3++) {

@@ -433,5 +516,5 @@ args[_key3] = arguments[_key3];

return buildAttributeDecorator('session', args);
return buildAttributeDecorator('identifier', args);
};
var belongsTo = function belongsTo() {
var field = function field() {
for (var _len4 = arguments.length, args = Array(_len4), _key4 = 0; _key4 < _len4; _key4++) {

@@ -441,10 +524,5 @@ args[_key4] = arguments[_key4];

return buildAttributeDecorator('belongsTo', args);
return buildAttributeDecorator('field', args);
};
var hasManyBuilder = function hasManyBuilder(type, target, property, descriptor) {
var options = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : {};
return addAttribute(type, target, property, descriptor, options);
};
var hasMany = function hasMany() {
var session = function session() {
for (var _len5 = arguments.length, args = Array(_len5), _key5 = 0; _key5 < _len5; _key5++) {

@@ -454,3 +532,3 @@ args[_key5] = arguments[_key5];

return buildAttributeDecorator('hasMany', args, hasManyBuilder);
return buildAttributeDecorator('session', args);
};

@@ -463,2 +541,3 @@

exports.modelDecorator = modelDecorator;
exports.unresolvedAssociations = unresolvedAssociations;
exports.field = field;

@@ -465,0 +544,0 @@ exports.session = session;

import { createModelSchema, deserialize, getDefaultModelSchema, identifier, list, object, primitive, serialize, update } from 'serializr';
import { action, observable } from 'mobx';
import { intercept, observable } from 'mobx';

@@ -19,3 +19,3 @@ var ModelsMap = new Map();

var defaultRememberModel = function defaultRememberModel(model) {
ModelsMap[model.name] = model;
ModelsMap[model.identifiedBy || model.name] = model;
};

@@ -41,8 +41,8 @@ var rememberModel = defaultRememberModel;

function isSerializable(model, property) {
return !!(!model.$nonSerializable || -1 === model.$nonSerializable.indexOf(property));
return !!(!model.$nonSerializable || !model.$nonSerializable[property]);
}
function markNonserializable(model, property) {
model.$nonSerializable = model.$nonSerializable || [];
model.$nonSerializable.push(property);
model.$nonSerializable = model.$nonSerializable || {};
model.$nonSerializable[property] = true;
}

@@ -66,2 +66,13 @@

function objectSerializer() {
return {
serializer: function serializer(obj, prop, parent) {
return isSerializable(parent, prop) ? obj : undefined;
},
deserializer: function deserializer(json, cb) {
cb(null, json);
}
};
}
function addReference(parentModel, propName, options, cb) {

@@ -72,2 +83,3 @@ var model = findModel(propName, options);

} else {
getDefaultModelSchema(parentModel).props[propName] = objectSerializer();
PendingLookups.push({ parentModel: parentModel, propName: propName, options: options, cb: cb });

@@ -77,13 +89,2 @@ }

function objectSerializer() {
return {
serializer: function serializer(obj) {
return obj;
},
deserializer: function deserializer(json, cb) {
cb(null, json);
}
};
}
function getSerializer(options, defaultSerializer) {

@@ -123,11 +124,11 @@ var serializer = void 0;

var AsyncHandlers = {
hasMany: function hasMany(modelKlass) {
hasMany: function hasMany(modelKlass, options) {
var defaultSerializer = list(object(modelKlass));
return Object.assign(defaultSerializer, {
model: modelKlass
});
}, options);
},
belongsTo: function belongsTo(modelKlass, options, propName) {
var defaultSerializer = object(getDefaultModelSchema(modelKlass));
return {
return Object.assign({
model: modelKlass,

@@ -150,3 +151,3 @@ deserializer: function deserializer(value, cb, context) {

}
};
}, options);
}

@@ -171,3 +172,3 @@ };

function modelDecorator(model) {
function decorateModel(model, identifier$$1) {
Object.assign(model.prototype, MixedInInstanceMethods);

@@ -177,7 +178,4 @@ Object.assign(model, MixedInClassMethods);

var schema = getModelSchema(model);
registerModel(model);
var serializeSchema = {};
schema.forEach(function (_ref, name) {

@@ -191,5 +189,3 @@ var type = _ref.type,

});
createModelSchema(model, serializeSchema);
schema.forEach(function (_ref2, name) {

@@ -203,3 +199,2 @@ var type = _ref2.type,

});
for (var i = PendingLookups.length - 1; i >= 0; i -= 1) {

@@ -213,3 +208,2 @@ var _PendingLookups$i = PendingLookups[i],

var referencedModel = findModel(propName, options);
if (referencedModel) {

@@ -223,2 +217,21 @@ var parentModelSchema = getDefaultModelSchema(parentModel);

function modelDecorator(modelOrIdentifier) {
if (typeof modelOrIdentifier === 'function') {
modelOrIdentifier.identifiedBy = modelOrIdentifier.name;
return decorateModel(modelOrIdentifier);
}
return function (model) {
model.identifiedBy = modelOrIdentifier;
return decorateModel(model);
};
}
function unresolvedAssociations() {
return PendingLookups.map(function (_ref3) {
var model = _ref3.parentModel,
property = _ref3.propName;
return { model: model, property: property };
});
}
var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) {

@@ -294,3 +307,7 @@ return typeof obj;

var setupModel = action(function (_ref) {
function addLazyInitializer(target, fn) {
target.__mobxLazyInitializers.push(fn);
}
function setupModel(_ref) {
var attrs = _ref.attrs,

@@ -321,12 +338,50 @@ Klass = _ref.modelClass,

var model = Klass && !(attrs instanceof Klass) ? new Klass(attrs) : attrs;
markNonserializable(model, inverseOf);
if (inverseOf) {
markNonserializable(model, inverseOf);
}
return model;
});
}
function buildInterceptor(_ref2, parentModel, parentModelProp) {
function onBelongsToSet(change, _ref2) {
var modelClass = _ref2.modelClass,
className = _ref2.className,
defaultAttributes = _ref2.defaults,
inverseOf = _ref2.inverseOf;
defaultAttributes = _ref2.defaultAttributes,
inverseOf = _ref2.inverseOf,
parentModel = _ref2.parentModel,
parentModelProp = _ref2.parentModelProp;
change.newValue = setupModel({
attrs: change.newValue, modelClass: modelClass,
defaultAttributes: defaultAttributes, inverseOf: inverseOf, parentModel: parentModel, parentModelProp: parentModelProp
});
return change;
}
function onHasManySet(change, _ref3) {
var modelClass = _ref3.modelClass,
defaultAttributes = _ref3.defaultAttributes,
inverseOf = _ref3.inverseOf,
parentModel = _ref3.parentModel,
parentModelProp = _ref3.parentModelProp;
if (change.type !== 'update') {
return change;
}
var array = change.newValue;
for (var i = 0; i < array.length; i += 1) {
array[i] = setupModel({
attrs: array[i], array: array, modelClass: modelClass,
defaultAttributes: defaultAttributes, inverseOf: inverseOf, parentModel: parentModel, parentModelProp: parentModelProp
});
}
parentModel[parentModelProp].replace(array);
return null;
}
function onCollectionChangeInterceptor(_ref4, parentModel, parentModelProp) {
var modelClass = _ref4.modelClass,
className = _ref4.className,
defaultAttributes = _ref4.defaults,
inverseOf = _ref4.inverseOf;
return function (change) {

@@ -357,3 +412,3 @@ if (!change.newValue) {

if (options.className || options.modelClass) {
ary.intercept(buildInterceptor(options, parentModel, parentModelProp));
ary.intercept(onCollectionChangeInterceptor(options, parentModel, parentModelProp));
}

@@ -408,3 +463,29 @@ return ary;

var identifier$1 = function identifier$$1() {
function interceptingDecorator(interceptingFn) {
return function (type, target, property, descriptor) {
var options = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : {};
var decorator = addAttribute(type, target, property, descriptor, options);
addLazyInitializer(target, function (model) {
var schema = getDefaultModelSchema(target);
if (schema && schema.props[property]) {
(function () {
var schemaProps = schema.props[property];
intercept(model, property, function (change) {
return interceptingFn(change, {
inverseOf: schemaProps.inverseOf,
modelClass: schemaProps.model,
parentModel: model,
parentModelProp: property,
defaultAttributes: schemaProps.defaults
});
});
})();
}
});
return decorator;
};
}
var hasMany = function hasMany() {
for (var _len = arguments.length, args = Array(_len), _key = 0; _key < _len; _key++) {

@@ -414,5 +495,6 @@ args[_key] = arguments[_key];

return buildAttributeDecorator('identifier', args);
return buildAttributeDecorator('hasMany', args, interceptingDecorator(onHasManySet));
};
var field = function field() {
var belongsTo = function belongsTo() {
for (var _len2 = arguments.length, args = Array(_len2), _key2 = 0; _key2 < _len2; _key2++) {

@@ -422,5 +504,6 @@ args[_key2] = arguments[_key2];

return buildAttributeDecorator('field', args);
return buildAttributeDecorator('belongsTo', args, interceptingDecorator(onBelongsToSet));
};
var session = function session() {
var identifier$1 = function identifier$$1() {
for (var _len3 = arguments.length, args = Array(_len3), _key3 = 0; _key3 < _len3; _key3++) {

@@ -430,5 +513,5 @@ args[_key3] = arguments[_key3];

return buildAttributeDecorator('session', args);
return buildAttributeDecorator('identifier', args);
};
var belongsTo = function belongsTo() {
var field = function field() {
for (var _len4 = arguments.length, args = Array(_len4), _key4 = 0; _key4 < _len4; _key4++) {

@@ -438,10 +521,5 @@ args[_key4] = arguments[_key4];

return buildAttributeDecorator('belongsTo', args);
return buildAttributeDecorator('field', args);
};
var hasManyBuilder = function hasManyBuilder(type, target, property, descriptor) {
var options = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : {};
return addAttribute(type, target, property, descriptor, options);
};
var hasMany = function hasMany() {
var session = function session() {
for (var _len5 = arguments.length, args = Array(_len5), _key5 = 0; _key5 < _len5; _key5++) {

@@ -451,6 +529,6 @@ args[_key5] = arguments[_key5];

return buildAttributeDecorator('hasMany', args, hasManyBuilder);
return buildAttributeDecorator('session', args);
};
export { registerModel, findModel, rememberModelUsing, lookupModelUsing, modelDecorator, field, session, belongsTo, hasMany, identifier$1 as identifier, buildCollection };
export { registerModel, findModel, rememberModelUsing, lookupModelUsing, modelDecorator, unresolvedAssociations, field, session, belongsTo, hasMany, identifier$1 as identifier, buildCollection };
//# sourceMappingURL=build.module.js.map

@@ -5,5 +5,2 @@ import {

} from 'serializr';
import {
observable,
} from 'mobx';

@@ -16,2 +13,13 @@ import { registerModel, findModel } from './model-lookup';

function objectSerializer() {
return {
serializer(obj, prop, parent) {
return isSerializable(parent, prop) ? obj : undefined;
},
deserializer(json, cb) {
cb(null, json);
},
};
}
function addReference(parentModel, propName, options, cb) {

@@ -22,2 +30,3 @@ const model = findModel(propName, options);

} else {
getDefaultModelSchema(parentModel).props[propName] = objectSerializer();
PendingLookups.push({ parentModel, propName, options, cb });

@@ -27,9 +36,2 @@ }

function objectSerializer() {
return {
serializer(obj) { return obj; },
deserializer(json, cb) { cb(null, json); },
};
}
function getSerializer(options, defaultSerializer) {

@@ -62,12 +64,11 @@ let serializer;

const AsyncHandlers = {
hasMany(modelKlass) {
hasMany(modelKlass, options) {
const defaultSerializer = list(object(modelKlass));
return Object.assign(defaultSerializer, {
model: modelKlass,
});
}, options);
},
belongsTo(modelKlass, options, propName) {
const defaultSerializer = object(getDefaultModelSchema(modelKlass));
return {
return Object.assign({
model: modelKlass,

@@ -88,3 +89,3 @@ deserializer(value, cb, context) {

},
};
}, options);
},

@@ -95,3 +96,2 @@ };

const MixedInInstanceMethods = {
serialize() {

@@ -101,18 +101,14 @@ const schema = getDefaultModelSchema(this.constructor);

},
update(json, callback) {
return update(getDefaultModelSchema(this.constructor), this, json, callback);
},
};
const MixedInClassMethods = {
deserialize(json, callback) {
return deserialize(getDefaultModelSchema(this), json, callback);
},
};
export function modelDecorator(model) {
function decorateModel(model, identifier) {
Object.assign(model.prototype, MixedInInstanceMethods);

@@ -122,7 +118,4 @@ Object.assign(model, MixedInClassMethods);

const schema = getSchema(model);
registerModel(model);
const serializeSchema = {};
schema.forEach(({ type, options }, name) => {

@@ -133,5 +126,3 @@ if (SimpleHandlers[type]) {

});
createModelSchema(model, serializeSchema);
schema.forEach(({ type, options }, name) => {

@@ -142,7 +133,5 @@ if (AsyncHandlers[type]) {

});
for (let i = PendingLookups.length - 1; i >= 0; i -= 1) {
const { parentModel, propName, options, cb } = PendingLookups[i];
const referencedModel = findModel(propName, options);
if (referencedModel) {

@@ -155,1 +144,18 @@ const parentModelSchema = getDefaultModelSchema(parentModel);

}
export function modelDecorator(modelOrIdentifier) {
if (typeof modelOrIdentifier === 'function') {
modelOrIdentifier.identifiedBy = modelOrIdentifier.name;
return decorateModel(modelOrIdentifier);
}
return (model) => {
model.identifiedBy = modelOrIdentifier;
return decorateModel(model);
};
}
export function unresolvedAssociations() {
return PendingLookups.map(({ parentModel: model, propName: property }) => (
{ model, property }
));
}

@@ -14,3 +14,3 @@ const ModelsMap = new Map();

const defaultRememberModel = (model) => {
ModelsMap[model.name] = model;
ModelsMap[model.identifiedBy || model.name] = model;
};

@@ -17,0 +17,0 @@ let rememberModel = defaultRememberModel;

@@ -1,5 +0,3 @@

import {
observable,
action,
} from 'mobx';
import { observable, intercept } from 'mobx';
import { getDefaultModelSchema } from 'serializr';

@@ -9,4 +7,10 @@ import { findModel } from './model-lookup';

import { markNonserializable } from './serializable'
const setupModel = action(function({
attrs, modelClass: Klass, array, defaultAttributes, inverseOf, parentModel, parentModelProp,
function addLazyInitializer(target, fn) {
target.__mobxLazyInitializers.push(fn);
}
function setupModel({
attrs, modelClass: Klass, array, defaultAttributes,
inverseOf, parentModel, parentModelProp,
}) {

@@ -30,8 +34,37 @@ if (defaultAttributes) {

const model = (Klass && !(attrs instanceof Klass)) ? new Klass(attrs) : attrs;
markNonserializable(model, inverseOf);
if (inverseOf) {
markNonserializable(model, inverseOf);
}
return model;
});
}
function buildInterceptor({ modelClass, className, defaults: defaultAttributes, inverseOf },
parentModel, parentModelProp) {
function onBelongsToSet(change,
{ modelClass, defaultAttributes, inverseOf,
parentModel, parentModelProp }) {
change.newValue = setupModel({
attrs: change.newValue, modelClass,
defaultAttributes, inverseOf, parentModel, parentModelProp,
});
return change;
}
function onHasManySet(change,
{ modelClass, defaultAttributes, inverseOf,
parentModel, parentModelProp }) {
if (change.type !== 'update') { return change; }
const { newValue: array } = change;
for (let i = 0; i < array.length; i += 1) {
array[i] = setupModel({
attrs: array[i], array, modelClass,
defaultAttributes, inverseOf, parentModel, parentModelProp,
});
}
parentModel[parentModelProp].replace(array);
return null;
}
function onCollectionChangeInterceptor(
{ modelClass, className, defaults: defaultAttributes, inverseOf },
parentModel, parentModelProp,
) {
return (change) => {

@@ -59,7 +92,6 @@ if (!change.newValue) {

function buildCollection(options, parentModel, parentModelProp) {
const ary = observable.array([]);
if (options.className || options.modelClass) {
ary.intercept(buildInterceptor(options, parentModel, parentModelProp));
ary.intercept(onCollectionChangeInterceptor(options, parentModel, parentModelProp));
}

@@ -104,11 +136,35 @@ return ary;

function interceptingDecorator(interceptingFn) {
return (type, target, property, descriptor, options = {}) => {
const decorator = addAttribute(type, target, property, descriptor, options);
addLazyInitializer(target, (model) => {
const schema = getDefaultModelSchema(target);
if (schema && schema.props[property]) {
const schemaProps = schema.props[property];
intercept(model, property, (change => interceptingFn(change, {
inverseOf: schemaProps.inverseOf,
modelClass: schemaProps.model,
parentModel: model,
parentModelProp: property,
defaultAttributes: schemaProps.defaults,
})));
}
});
return decorator;
};
}
const hasMany = (...args) => buildAttributeDecorator(
'hasMany', args, interceptingDecorator(onHasManySet),
);
const belongsTo = (...args) => buildAttributeDecorator(
'belongsTo', args, interceptingDecorator(onBelongsToSet),
);
const identifier = (...args) => buildAttributeDecorator('identifier', args);
const field = (...args) => buildAttributeDecorator('field', args);
const session = (...args) => buildAttributeDecorator('session', args);
const belongsTo = (...args) => buildAttributeDecorator('belongsTo', args);
const hasManyBuilder = (type, target, property, descriptor, options = {}) =>
addAttribute(type, target, property, descriptor, options);
const hasMany = (...args) => buildAttributeDecorator('hasMany', args, hasManyBuilder);
export { field, session, belongsTo, hasMany, identifier, buildCollection };
export function isSerializable(model, property) {
return !!(!model.$nonSerializable || -1 === model.$nonSerializable.indexOf(property));
return !!(!model.$nonSerializable || !model.$nonSerializable[property]);
}
export function markNonserializable(model, property) {
model.$nonSerializable = model.$nonSerializable || [];
model.$nonSerializable.push(property);
model.$nonSerializable = model.$nonSerializable || {};
model.$nonSerializable[property] = true;
}
{
"name": "mobx-decorated-models",
"version": "0.3.3",
"version": "0.4.0",
"description": "Decorators to make using Mobx for model type structures easier",

@@ -5,0 +5,0 @@ "main": "dist/build.full.js",

@@ -29,3 +29,3 @@ # Decorators for creating model type structures with mobx

@modelDecorator
@modelDecorator('box')
export class Box {

@@ -43,3 +43,3 @@ @identifier id;

@belongsTo container;
@belongsTo({ model: 'Address' }) warehouse;
@belongsTo({ model: 'address' }) warehouse;
}

@@ -63,3 +63,3 @@ ```

By default, the class `@modelDecorator` uses the `name` property of each class as a lookup key so
The class `@modelDecorator` uses either the `name` property of each class, or can be supplied with a unique string that should be used as a lookup key so
that `hasMany` and `belongsTo` relation ships can be established.

@@ -75,3 +75,3 @@

@modelDecorator
@modelDecorator('chair')
class Chair {

@@ -85,5 +85,5 @@ belongsTo 'table'

@modelDecorator
@modelDecorator('table')
class Table {
hasMany({ model: 'Chair' }) 'seats'
hasMany({ className: 'chair' }) 'seats'
}

@@ -154,2 +154,3 @@ ```

```javascript
@modelDecorator
class Foo {

@@ -179,2 +180,3 @@ @field({ type: 'object' }) options; // will default to an observable map

```javascript
@modelDecorator
class Person({

@@ -186,2 +188,3 @@ @identifier id;

@modelDecorator
class Pants {

@@ -221,2 +224,3 @@ @session color;

```javascript
@modelDecorator
class Tire {

@@ -227,2 +231,3 @@ @session numberInSet;

@modelDecorator
class Car {

@@ -234,2 +239,3 @@ @belongsTo home;

@modelDecorator
class Garage {

@@ -247,4 +253,32 @@ @session owner;

## unresolvedAssociations
mobx-decorated-models attempts to do lazy lookups for the model that **hasMany** and **belongsTo** should use. In order to do so, it keeps track of associations that are not immediatly resolved in the hope that the model for them will be decorated with **@modelDecorator** later.
However if the model is never decorated the association will continue to be set to a plain observable.object.
Properties that are not resolved can be listed using the `unresolvedAssociations` method, which will return an array of object with model and property keys.
**Example:**
import { model, field, session, belongsTo, hasMany, identifier } from 'mobx-decorated-models';
@modelDecorator
class Parallelogram {
}
@modelDecorator('box')
class Box {
hasMany sides;
}
unresolvedAssociations().forEach(({ model, property }) => {
console.log(`The model for ${model.identifiedBy}(${property}) cannot be found`);
});
// outputs: The model for box(sides) cannot be found
# Future plans
* Sessions: properties that will be set from JSON but won't be serialized. https://github.com/mobxjs/serializr/pull/32 is needed before this can be supported

@@ -1,3 +0,5 @@

import { Container, Box } from './test-models';
import { Container, Box, Ship } from './test-models';
import { unresolvedAssociations } from '../lib/class-decorator';
describe('Class Decorators', () => {

@@ -92,2 +94,13 @@ it('adds static deserialize method and serialize to prototype', () => {

});
it('reports on associations that are not resolved', () => {
const box = Box.deserialize({ vessel: { id: 1 } });
expect(box.vessel).toEqual({ id: 1 });
expect(box.vessel).not.toBeInstanceOf(Ship);
const pending = unresolvedAssociations();
expect(pending).toHaveLength(1);
expect(pending[0].model).toBe(Box);
expect(pending[0].property).toEqual('vessel');
});
});

@@ -0,4 +1,4 @@

import { autorun } from 'mobx';
import { Box, Container, Ship } from './test-models';
import { autorun, observable } from 'mobx';
import { update } from 'serializr';
import { isSerializable } from '../lib/serializable';

@@ -52,3 +52,5 @@ describe('Property Decorators', () => {

const ship = Ship.deserialize({ name: 'HMS Mobx', box: { width: 42 } });
expect(ship.box.container).toBe(ship);
expect(ship.box.depth).toEqual(1);
expect(isSerializable(ship, 'box')).toBe(true);
expect(isSerializable(ship.box, 'vessel')).toBe(false);
expect(ship.serialize()).toEqual({

@@ -58,3 +60,3 @@ name: 'HMS Mobx',

});
expect(ship.box.container_association_name).toEqual('box');
expect(ship.box.vessel_association_name).toEqual('box');
});

@@ -103,2 +105,22 @@

it('guards against setting a belongsTo', () => {
const ship = Ship.deserialize({ name: 'HMS Glory' });
ship.box = { width: 1, height: 1, depth: 1 };
expect(ship.box).toBeInstanceOf(Box);
expect(ship.box.vessel).toBe(ship);
});
it('guards against setting a hasMany', () => {
const container = Container.deserialize({ id: 1 });
const originalBoxes = container.boxes;
container.boxes = [
{ width: 1, height: 1, depth: 1 },
{ width: 2, height: 2, depth: 2 },
];
expect(container.boxes).toBe(originalBoxes);
expect(container.boxes[0]).toBeInstanceOf(Box);
expect(container.boxes[1].container).toBe(container);
});
});

@@ -11,10 +11,10 @@ import { observable, computed } from 'mobx';

@modelDecorator
@modelDecorator('boat')
export class Ship {
@identifier name;
@belongsTo({ inverseOf: 'container' }) box;
@belongsTo({ inverseOf: 'vessel' }) box;
}
@modelDecorator
@modelDecorator('box')
export class Box extends RectangularCuboid {

@@ -29,2 +29,3 @@ @identifier id;

@session color;
@session vessel_association_name;

@@ -34,7 +35,7 @@ @computed get volume() {

}
@belongsTo vessel;
@belongsTo container;
}
@modelDecorator
@modelDecorator('container')
export class Container extends RectangularCuboid {

@@ -54,3 +55,3 @@ @identifier id;

@hasMany({
className: 'Box',
className: 'box',
inverseOf: 'container',

@@ -57,0 +58,0 @@ defaults() {

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc