Huge News!Announcing our $40M Series B led by Abstract Ventures.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.4.4 to 0.4.5

lib/collection.js

119

dist/build.full.js

@@ -208,9 +208,5 @@ (function (global, factory) {

function modelDecorator(modelOrIdentifier) {
if (typeof modelOrIdentifier === 'function') {
modelOrIdentifier.identifiedBy = modelOrIdentifier.name;
return decorateModel(modelOrIdentifier);
}
function identifiedBy(modelId) {
return function (model) {
model.identifiedBy = modelOrIdentifier;
Object.defineProperty(model, 'identifiedBy', { value: modelId, writable: false });
return decorateModel(model);

@@ -298,6 +294,2 @@ };

function addLazyInitializer(target, fn) {
target.__mobxLazyInitializers.push(fn);
}
function setupModel(_ref) {

@@ -338,9 +330,48 @@ var attrs = _ref.attrs,

function onBelongsToSet(change, _ref2) {
var modelClass = _ref2.modelClass,
defaultAttributes = _ref2.defaultAttributes,
inverseOf = _ref2.inverseOf,
parentModel = _ref2.parentModel,
parentModelProp = _ref2.parentModelProp;
function onCollectionChangeInterceptor(_ref, parentModel, parentModelProp) {
var modelClass = _ref.modelClass,
model = _ref.model,
defaultAttributes = _ref.defaults,
inverseOf = _ref.inverseOf;
return function (change) {
if (!change.newValue) {
change.newValue = {};
}
if (!modelClass) {
modelClass = findModel(model, parentModelProp);
}
if (change.type === 'splice') {
for (var i = 0; i < change.added.length; i += 1) {
change.added[i] = setupModel({
attrs: change.added[i], array: change.object, modelClass: modelClass,
defaultAttributes: defaultAttributes, inverseOf: inverseOf, parentModel: parentModel, parentModelProp: parentModelProp });
}
} else if (change.type === 'update') {
change.newValue = setupModel({
attrs: change.newValue, array: change.object, modelClass: modelClass,
defaultAttributes: defaultAttributes, inverseOf: inverseOf, parentModel: parentModel, parentModelProp: parentModelProp });
}
return change;
};
}
function createCollection(options, parentModel, parentModelProp) {
var ary = mobx.observable.array([]);
if (options && options.model) {
ary.intercept(onCollectionChangeInterceptor(options, parentModel, parentModelProp));
}
return ary;
}
function addLazyInitializer(target, fn) {
target.__mobxLazyInitializers.push(fn);
}
function onBelongsToSet(change, _ref) {
var modelClass = _ref.modelClass,
defaultAttributes = _ref.defaultAttributes,
inverseOf = _ref.inverseOf,
parentModel = _ref.parentModel,
parentModelProp = _ref.parentModelProp;
change.newValue = setupModel({

@@ -353,8 +384,8 @@ attrs: change.newValue, modelClass: modelClass,

function onHasManySet(change, _ref3) {
var modelClass = _ref3.modelClass,
defaultAttributes = _ref3.defaultAttributes,
inverseOf = _ref3.inverseOf,
parentModel = _ref3.parentModel,
parentModelProp = _ref3.parentModelProp;
function onHasManySet(change, _ref2) {
var modelClass = _ref2.modelClass,
defaultAttributes = _ref2.defaultAttributes,
inverseOf = _ref2.inverseOf,
parentModel = _ref2.parentModel,
parentModelProp = _ref2.parentModelProp;

@@ -383,38 +414,2 @@ if (change.type !== 'update' || !change.newValue) {

function onCollectionChangeInterceptor(_ref4, parentModel, parentModelProp) {
var modelClass = _ref4.modelClass,
model = _ref4.model,
defaultAttributes = _ref4.defaults,
inverseOf = _ref4.inverseOf;
return function (change) {
if (!change.newValue) {
change.newValue = {};
}
if (!modelClass) {
modelClass = findModel(model, parentModelProp);
}
if (change.type === 'splice') {
for (var i = 0; i < change.added.length; i += 1) {
change.added[i] = setupModel({
attrs: change.added[i], array: change.object, modelClass: modelClass,
defaultAttributes: defaultAttributes, inverseOf: inverseOf, parentModel: parentModel, parentModelProp: parentModelProp });
}
} else if (change.type === 'update') {
change.newValue = setupModel({
attrs: change.newValue, array: change.object, modelClass: modelClass,
defaultAttributes: defaultAttributes, inverseOf: inverseOf, parentModel: parentModel, parentModelProp: parentModelProp });
}
return change;
};
}
function buildCollection(options, parentModel, parentModelProp) {
var ary = mobx.observable.array([]);
if (options.classId || options.model) {
ary.intercept(onCollectionChangeInterceptor(options, parentModel, parentModelProp));
}
return ary;
}
var Initializers = {

@@ -424,7 +419,7 @@ object: function object$$1() {

},
array: buildCollection
array: createCollection
};
var TypeInitializers = {
hasMany: buildCollection
hasMany: createCollection
};

@@ -534,3 +529,3 @@

exports.lookupModelUsing = lookupModelUsing;
exports.modelDecorator = modelDecorator;
exports.identifiedBy = identifiedBy;
exports.unresolvedAssociations = unresolvedAssociations;

@@ -542,3 +537,3 @@ exports.field = field;

exports.identifier = identifier$1;
exports.buildCollection = buildCollection;
exports.createCollection = createCollection;

@@ -545,0 +540,0 @@ Object.defineProperty(exports, '__esModule', { value: true });

@@ -205,9 +205,5 @@ import { createModelSchema, deserialize, getDefaultModelSchema, identifier, list, object, primitive, serialize, update } from 'serializr';

function modelDecorator(modelOrIdentifier) {
if (typeof modelOrIdentifier === 'function') {
modelOrIdentifier.identifiedBy = modelOrIdentifier.name;
return decorateModel(modelOrIdentifier);
}
function identifiedBy(modelId) {
return function (model) {
model.identifiedBy = modelOrIdentifier;
Object.defineProperty(model, 'identifiedBy', { value: modelId, writable: false });
return decorateModel(model);

@@ -295,6 +291,2 @@ };

function addLazyInitializer(target, fn) {
target.__mobxLazyInitializers.push(fn);
}
function setupModel(_ref) {

@@ -335,9 +327,48 @@ var attrs = _ref.attrs,

function onBelongsToSet(change, _ref2) {
var modelClass = _ref2.modelClass,
defaultAttributes = _ref2.defaultAttributes,
inverseOf = _ref2.inverseOf,
parentModel = _ref2.parentModel,
parentModelProp = _ref2.parentModelProp;
function onCollectionChangeInterceptor(_ref, parentModel, parentModelProp) {
var modelClass = _ref.modelClass,
model = _ref.model,
defaultAttributes = _ref.defaults,
inverseOf = _ref.inverseOf;
return function (change) {
if (!change.newValue) {
change.newValue = {};
}
if (!modelClass) {
modelClass = findModel(model, parentModelProp);
}
if (change.type === 'splice') {
for (var i = 0; i < change.added.length; i += 1) {
change.added[i] = setupModel({
attrs: change.added[i], array: change.object, modelClass: modelClass,
defaultAttributes: defaultAttributes, inverseOf: inverseOf, parentModel: parentModel, parentModelProp: parentModelProp });
}
} else if (change.type === 'update') {
change.newValue = setupModel({
attrs: change.newValue, array: change.object, modelClass: modelClass,
defaultAttributes: defaultAttributes, inverseOf: inverseOf, parentModel: parentModel, parentModelProp: parentModelProp });
}
return change;
};
}
function createCollection(options, parentModel, parentModelProp) {
var ary = observable.array([]);
if (options && options.model) {
ary.intercept(onCollectionChangeInterceptor(options, parentModel, parentModelProp));
}
return ary;
}
function addLazyInitializer(target, fn) {
target.__mobxLazyInitializers.push(fn);
}
function onBelongsToSet(change, _ref) {
var modelClass = _ref.modelClass,
defaultAttributes = _ref.defaultAttributes,
inverseOf = _ref.inverseOf,
parentModel = _ref.parentModel,
parentModelProp = _ref.parentModelProp;
change.newValue = setupModel({

@@ -350,8 +381,8 @@ attrs: change.newValue, modelClass: modelClass,

function onHasManySet(change, _ref3) {
var modelClass = _ref3.modelClass,
defaultAttributes = _ref3.defaultAttributes,
inverseOf = _ref3.inverseOf,
parentModel = _ref3.parentModel,
parentModelProp = _ref3.parentModelProp;
function onHasManySet(change, _ref2) {
var modelClass = _ref2.modelClass,
defaultAttributes = _ref2.defaultAttributes,
inverseOf = _ref2.inverseOf,
parentModel = _ref2.parentModel,
parentModelProp = _ref2.parentModelProp;

@@ -380,38 +411,2 @@ if (change.type !== 'update' || !change.newValue) {

function onCollectionChangeInterceptor(_ref4, parentModel, parentModelProp) {
var modelClass = _ref4.modelClass,
model = _ref4.model,
defaultAttributes = _ref4.defaults,
inverseOf = _ref4.inverseOf;
return function (change) {
if (!change.newValue) {
change.newValue = {};
}
if (!modelClass) {
modelClass = findModel(model, parentModelProp);
}
if (change.type === 'splice') {
for (var i = 0; i < change.added.length; i += 1) {
change.added[i] = setupModel({
attrs: change.added[i], array: change.object, modelClass: modelClass,
defaultAttributes: defaultAttributes, inverseOf: inverseOf, parentModel: parentModel, parentModelProp: parentModelProp });
}
} else if (change.type === 'update') {
change.newValue = setupModel({
attrs: change.newValue, array: change.object, modelClass: modelClass,
defaultAttributes: defaultAttributes, inverseOf: inverseOf, parentModel: parentModel, parentModelProp: parentModelProp });
}
return change;
};
}
function buildCollection(options, parentModel, parentModelProp) {
var ary = observable.array([]);
if (options.classId || options.model) {
ary.intercept(onCollectionChangeInterceptor(options, parentModel, parentModelProp));
}
return ary;
}
var Initializers = {

@@ -421,7 +416,7 @@ object: function object$$1() {

},
array: buildCollection
array: createCollection
};
var TypeInitializers = {
hasMany: buildCollection
hasMany: createCollection
};

@@ -527,3 +522,3 @@

export { registerModel, findModel, rememberModelUsing, lookupModelUsing, modelDecorator, unresolvedAssociations, field, session, belongsTo, hasMany, identifier$1 as identifier, buildCollection };
export { registerModel, findModel, rememberModelUsing, lookupModelUsing, identifiedBy, unresolvedAssociations, field, session, belongsTo, hasMany, identifier$1 as identifier, createCollection };
//# sourceMappingURL=build.module.js.map

@@ -134,9 +134,5 @@ import {

export function modelDecorator(modelOrIdentifier) {
if (typeof modelOrIdentifier === 'function') {
modelOrIdentifier.identifiedBy = modelOrIdentifier.name;
return decorateModel(modelOrIdentifier);
}
export function identifiedBy(modelId) {
return (model) => {
model.identifiedBy = modelOrIdentifier;
Object.defineProperty(model, 'identifiedBy', { value: modelId, writable: false });
return decorateModel(model);

@@ -143,0 +139,0 @@ };

import { observable, intercept } from 'mobx';
import { getDefaultModelSchema } from 'serializr';
import { findModel } from './model-lookup';
import getModelSchema from './schema';
import { markNonserializable } from './serializable'

@@ -11,32 +9,5 @@ function addLazyInitializer(target, fn) {

}
import createCollection from './collection';
function setupModel({
attrs, modelClass: Klass, array, defaultAttributes,
inverseOf, parentModel, parentModelProp,
}) {
if (!attrs || typeof attrs !== 'object') {
return attrs;
}
if (defaultAttributes) {
if (typeof defaultAttributes === 'function') {
defaultAttributes = defaultAttributes.call(parentModel, array, parentModel);
}
Object.keys(defaultAttributes).forEach((key) => {
if (!attrs[key]) {
attrs[key] = defaultAttributes[key];
}
});
}
if (inverseOf) {
if (parentModelProp) {
attrs[`${inverseOf}_association_name`] = parentModelProp;
}
attrs[inverseOf] = parentModel;
}
const model = (Klass && !(attrs instanceof Klass)) ? new Klass(attrs) : attrs;
if (inverseOf) {
markNonserializable(model, inverseOf);
}
return model;
}
import setupModel from './setup-model';

@@ -75,43 +46,10 @@ function onBelongsToSet(change,

function onCollectionChangeInterceptor(
{ modelClass, model, defaults: defaultAttributes, inverseOf },
parentModel, parentModelProp,
) {
return (change) => {
if (!change.newValue) {
change.newValue = {};
}
if (!modelClass) {
modelClass = findModel(model, parentModelProp);
}
if (change.type === 'splice') {
for (let i = 0; i < change.added.length; i += 1) {
change.added[i] = setupModel({
attrs: change.added[i], array: change.object, modelClass,
defaultAttributes, inverseOf, parentModel, parentModelProp });
}
} else if (change.type === 'update') {
change.newValue = setupModel({
attrs: change.newValue, array: change.object, modelClass,
defaultAttributes, inverseOf, parentModel, parentModelProp });
}
return change;
};
}
function buildCollection(options, parentModel, parentModelProp) {
const ary = observable.array([]);
if (options.classId || options.model) {
ary.intercept(onCollectionChangeInterceptor(options, parentModel, parentModelProp));
}
return ary;
}
const Initializers = {
object: () => observable.object({}),
array: buildCollection,
array: createCollection,
};
const TypeInitializers = {
hasMany: buildCollection,
hasMany: createCollection,
};

@@ -178,2 +116,2 @@

export { field, session, belongsTo, hasMany, identifier, buildCollection };
export { field, session, belongsTo, hasMany, identifier, createCollection };
{
"name": "mobx-decorated-models",
"version": "0.4.4",
"version": "0.4.5",
"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('box')
@identifiedBy('box')
export class Box {

@@ -62,4 +62,4 @@ @identifier id;

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.
The class `@identifiedBy` accepts a unique string that should be used as a lookup key so
that `hasMany` and `belongsTo` relationships can be established.

@@ -72,5 +72,5 @@ This allows things like the below mappings to still work even though the two files can't easily include each other:

import { modelDecorator, belongsTo } from 'mobx-decorated-models';
import { identifiedBy, belongsTo } from 'mobx-decorated-models';
@modelDecorator('chair')
@identifiedBy('chair')
class Chair {

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

// table.js
import { model, hasMany } from 'mobx-decorated-models';
import { identifiedBy, hasMany } from 'mobx-decorated-models';
@modelDecorator('table')
@identifiedBy('table')
class Table {

@@ -91,5 +91,26 @@ hasMany({ model: 'chair' }) 'seats'

### Collections
The same logic that is used for belongsTo can also build a stand-alone collection. Collections built this way are instances of mobx `observable.array` with an interceptor that converts assigment into model creation.
A collecton can be created like so:
```javascript
import { createCollection } from 'mobx-decorated-models';
class Foo {
constructor(attrs) { Object.assign(this, attrs); }
myName() { return this.name; }
}
const collection = createCollection({ model: ModelInCollection });
collection.push({ name: 'bar' });
collection[0].myName(); // will return "bar", since it's coerced into an instance of Foo
```
Note that the "model" objects a collection is set to do not have to be decorated by the `@identifiedBy` decorator if they're given directly as shown in the exmple above. However if they were, then the identifier could be given to 'model' instead of the class.
### Decorators
#### model
#### identifiedBy('<identifier>')

@@ -101,2 +122,3 @@ Marks a class as serializable.

* static `deserialize` method. Used to turn JSON structure into a model (or collection of models)
* a read-only static `identifiedBy` value that matches the string provided to the decorator
* an `update` method. Updates a model's attributes and child associations.

@@ -121,3 +143,3 @@ * `serialize`. Converts the model's attributes and it's associations to JSON.

```javascript
@modelDecorator
@identifiedBy('foo')
class Foo {

@@ -137,9 +159,9 @@ @field({ type: 'object' }) options; // will default to an observable map

Makes a property as referring to another model. Will attempt to map
the referenced class based on the name, i.e. a property named `box` will
look for a class named `Box`.
Makes a property as referring to another model. Will map to
the referenced class based on it's identifiedBy and the property name, i.e. a property named `box` will
look for a class identified by `box`.
Optionally can be given an option object with a `model` property to control the mapping.
`model` can be either a string which matches a value given to the modelDecorator, or a reference to the model itself.
`model` can be either a string which matches a value given to the identifiedBy decorator, or a reference to the model itself.

@@ -149,3 +171,3 @@ *example:*

```javascript
@modelDecorator
@identifiedBy('person')
class Person({

@@ -161,3 +183,3 @@ @identifier id;

@modelDecorator('pants')
@identifiedBy('pants')
class Pants {

@@ -208,3 +230,3 @@ @session color;

```javascript
@modelDecorator
@identifiedBy('tire')
class Tire {

@@ -215,3 +237,3 @@ @session numberInSet;

@modelDecorator
@identifiedBy('car')
class Car {

@@ -223,3 +245,3 @@ @belongsTo home;

@modelDecorator
@identifiedBy('garage')
class Garage {

@@ -239,3 +261,3 @@ @session owner;

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.
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 **@identifiedBy** later.

@@ -247,5 +269,7 @@ However if the model is never decorated the association will continue to be set to a plain observable.object.

**Example:**
```javascript
import { model, field, session, belongsTo, hasMany, identifier } from 'mobx-decorated-models';
@modelDecorator
@identifiedBy('shape')
class Parallelogram {

@@ -255,3 +279,3 @@

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

@@ -266,2 +290,3 @@ hasMany sides;

// outputs: The model for box(sides) cannot be found
```

@@ -268,0 +293,0 @@

@@ -95,5 +95,6 @@ import { Container, Box, Ship } from './test-models';

it('uses string identifier with decorator', () => {
it('sets identifier from decorator', () => {
expect(Ship.identifiedBy).toEqual('boat');
expect(findModel('ship', 'boat')).toBe(Ship)
expect(() => (Ship.identifiedBy = 'bar')).toThrow();
expect(findModel('ship', 'boat')).toBe(Ship);
});

@@ -100,0 +101,0 @@

import { Container, Box } from './test-models';
import { modelDecorator } from '../index';
import { identifiedBy } from '../index';
import * as ModelLookup from '../lib/model-lookup';

@@ -22,3 +22,3 @@

ModelLookup.rememberModelUsing(spy);
@modelDecorator
@identifiedBy('foo')
class ThisIsTest { }

@@ -25,0 +25,0 @@ expect(spy).toHaveBeenCalledWith(ThisIsTest);

import { observable, computed } from 'mobx';
import { modelDecorator, field, session, belongsTo, hasMany, identifier } from '../index';
import { identifiedBy, field, session, belongsTo, hasMany, identifier } from '../index';

@@ -11,3 +11,3 @@ class RectangularCuboid {

@modelDecorator('boat')
@identifiedBy('boat')
export class Ship {

@@ -19,3 +19,3 @@ @identifier name;

@modelDecorator('box')
@identifiedBy('box')
export class Box extends RectangularCuboid {

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

@modelDecorator('container')
@identifiedBy('container')
export class Container extends RectangularCuboid {

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

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