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

backbone-data

Package Overview
Dependencies
Maintainers
1
Versions
10
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

backbone-data - npm Package Compare versions

Comparing version 0.0.5 to 0.0.6

tests/DS.spec.js

50

apidocs.md
API Documentation
=================
## Overview
## The Global DS
The global `DS` variable is a `Backbone.Model` singleton for you to get/set arbitrary data that you may need in several places of your application.
```js
DS.set('isLoggedIn', true);
DS.get('isLoggedIn'); // true
DS instanceof Backbone.Model // true
```
## Data Store Resources
A resource is the data and meta data associated with a particular RESTful resource. In this library, a resource is broken out into two types: collection resources and model resources. A collection resource is when there can be 1 to many items for a resource. For example, an application could have 1 to many orders. A model resource on the other hand is when you only ever have one instance of something, like a `UserProfile` model tied to the logged-in user's session.

@@ -10,3 +20,3 @@

##### Synchronous Methods
The following methods are synchronous:

@@ -22,6 +32,4 @@ * DS.defineResource(resourceDefinition) - Create a new resource for the store to manage

##### Asynchronous Methods
The following methods are asynchronous and return a promise:
These methods return a promise
* DS.find(resourceName, id [, options]) - Resolves with the model retrieved and injected into the store

@@ -35,3 +43,3 @@ * DS.findAll(resourceName [, options]) - Resolves with the collection instance managed by the store for _resourceName_

##### Synchronous Methods
The following methods are synchronous:

@@ -42,3 +50,3 @@ * DS.defineResource(resourceDefinition)

##### Asynchronous Methods
The following methods are asynchronous and return a promise:

@@ -49,6 +57,4 @@ * DS.find(resourceName) - Makes a request for a model only once and resolves with the model

#### Collection Resource
To create a a collection resource, specify a collection, a unique name, and `idAttribute` which is the property name that uniquely identifies the models for this resource type (the primary key). If no collection is passed in, `Backbone.Collection` will be used.
Create a collection resource by specifying a Backbone model, collection, a unique name, and the property name that uniquely identifies the models for this resource type (the primary key).
```js

@@ -68,3 +74,2 @@ var Person = Backbone.Model.extend({

idAttribute: 'id', // 'id' is the default
model: Person,
collection: PersonCollection

@@ -74,6 +79,24 @@ });

#### Model Resource
The model associated with the collection will be used to create new objects. Alternatively, you can pass in a model and that will be used instead.
Create a model resource by specifying a Backbone model and a unique name.
```js
var Person = Backbone.Model.extend({
url: function() {
return '/people/' + this.get('id')
}
});
var PersonCollection = Backbone.Collection.extend();
DS.defineResource({
name: 'person',
idAttribute: 'id', // 'id' is the default
collection: PersonCollection,
model: Person
});
```
To create a model resource, specify a Backbone model and a unique name. If no model is passed in, `Backbone.Model` will be used.
```js

@@ -286,2 +309,1 @@ var UserProfile = Backbone.Model.extend();

```
{
"name": "backbone-data",
"description": "A simple data store for backbone models and collections inspired by Ember Data and angular-data.",
"version": "0.0.5",
"version": "0.0.6",
"homepage": "https://github.com/skaterdav85/backbone-data",

@@ -6,0 +6,0 @@ "authors": [

(function(window, undefined) {
var DS = {};
var resources = {};
var store = {};
var incomplete = {};
var collectionStatus = {};
var modelFetched = {};
/**
* @param {String} resourceName The name of the resource when defined
* @param {Array|Object} data A array of object or just a plain json object
*/
function addIncomplete(resourceName, data) {
var idAttribute = resources[resourceName].idAttribute;
var id;
var factory = function(Backbone) {
var DS = new Backbone.Model();
var resources = {};
var store = {};
var incomplete = {};
var collectionStatus = {};
var modelFetched = {};
/**
* @param {String} resourceName The name of the resource when defined
* @param {Array|Object} data A array of object or just a plain json object
*/
function addIncomplete(resourceName, data) {
var idAttribute = resources[resourceName].idAttribute;
var id;
incomplete[resourceName] = incomplete[resourceName] || {};
incomplete[resourceName] = incomplete[resourceName] || {};
if (_.isArray(data)) {
data.forEach(function(item) {
var id = item[idAttribute];
if (_.isArray(data)) {
data.forEach(function(item) {
var id = item[idAttribute];
incomplete[resourceName][id] = true;
});
} else {
id = data[idAttribute];
incomplete[resourceName][id] = true;
});
} else {
id = data[idAttribute];
incomplete[resourceName][id] = true;
}
}
}
/**
* Determine if a model if incomplete or not
* @param {String} resourceName The name of the resource when defined
* @param {Number|String} id The unique ID of the model to find
* @return {Boolean} True if the model is incomplete, false if complete
*/
function isIncomplete(resourceName, id) {
if (incomplete[resourceName]) {
return incomplete[resourceName][id];
/**
* Determine if a model if incomplete or not
* @param {String} resourceName The name of the resource when defined
* @param {Number|String} id The unique ID of the model to find
* @return {Boolean} True if the model is incomplete, false if complete
*/
function isIncomplete(resourceName, id) {
if (incomplete[resourceName]) {
return incomplete[resourceName][id];
}
return false;
}
return false;
}
function isModelResource(resourceName) {
if (resources[resourceName].collection) {
return false;
function isModelResource(resourceName) {
if (resources[resourceName].collection) {
return false;
}
return true;
}
return true;
}
/**
* Define a resource for the store
* @param {Object} resourceDefinition An object containing idAttribute, name, collection, and model
*/
DS.defineResource = function(resourceDefinition) {
if (!resourceDefinition.hasOwnProperty('name') || !resourceDefinition['name']) {
throw new Error('name must be specified when defining a resource');
}
if (!resourceDefinition.hasOwnProperty('idAttribute') || !resourceDefinition['idAttribute']) {
if (resourceDefinition.collection) {
throw new Error('idAttribute must be specified when defining a resource');
}
}
/**
* Define a resource for the store
* @param {Object} resourceDefinition An object containing idAttribute, name, collection, and model
*/
DS.defineResource = function(resourceDefinition) {
if (!resourceDefinition.hasOwnProperty('name') || !resourceDefinition['name']) {
throw new Error('name must be specified when defining a resource');
}
if (resources[resourceDefinition.name]) {
throw new Error(resourceDefinition.name + ' resource has already been defined!');
}
if (!resourceDefinition.hasOwnProperty('model') || !_.isFunction(resourceDefinition['model'])) {
throw new Error('model must be specified when defining a resource');
}
if (!resourceDefinition.hasOwnProperty('idAttribute') || !resourceDefinition['idAttribute']) {
if (resourceDefinition.collection) {
throw new Error('idAttribute must be specified when defining a resource');
if (!resourceDefinition.model && resourceDefinition.collection) {
resourceDefinition.model = resourceDefinition.collection.prototype.model;
}
}
if (resources[resourceDefinition.name]) {
throw new Error(resourceDefinition.name + ' resource has already been defined!');
}
if (resourceDefinition.hasOwnProperty('idAttribute') && !resourceDefinition.hasOwnProperty('collection')) {
resourceDefinition.collection = Backbone.Collection;
}
resources[resourceDefinition.name] = resourceDefinition;
if (!store[resourceDefinition.name]) {
if (resourceDefinition.collection) {
store[resourceDefinition.name] = new resourceDefinition.collection();
} else {
store[resourceDefinition.name] = new resourceDefinition.model();
resources[resourceDefinition.name] = resourceDefinition;
if (!store[resourceDefinition.name]) {
if (resourceDefinition.collection) {
store[resourceDefinition.name] = new resourceDefinition.collection();
} else {
resourceDefinition.model = resourceDefinition.model || Backbone.Model;
store[resourceDefinition.name] = new resourceDefinition.model();
}
}
}
return this;
};
return this;
};
/**
* Create a new instance of a resource
* @param {String} resourceName The name of the resource when defined
* @return {Backbone.Model}
*/
DS.createInstance = function(resourceName) {
return new resources[resourceName].model();
};
/**
* Create a new instance of a resource
* @param {String} resourceName The name of the resource when defined
* @return {Backbone.Model}
*/
DS.createInstance = function(resourceName) {
return new resources[resourceName].model();
};
/**
* Inject data into the store for a given resource
* @param {String} resourceName The name of the resource when defined
* @param {Array|Object} data A array of object or just a plain json object
* @return {Array|Backbone.Model} The added models
*/
DS.inject = function(resourceName, data, options) {
var collection, model;
/**
* Inject data into the store for a given resource
* @param {String} resourceName The name of the resource when defined
* @param {Array|Object} data A array of object or just a plain json object
* @return {Array|Backbone.Model} The added models
*/
DS.inject = function(resourceName, data, options) {
var collection, model;
if (store[resourceName] instanceof Backbone.Collection) {
options = _.extend({ incomplete: false }, options);
collection = store[resourceName];
if (store[resourceName] instanceof Backbone.Collection) {
options = _.extend({ incomplete: false }, options);
collection = store[resourceName];
if (options.incomplete) {
addIncomplete(resourceName, data);
if (options.incomplete) {
addIncomplete(resourceName, data);
}
return collection.add(data);
} else {
model = store[resourceName];
return model.set(data);
}
};
/**
* Synchronously return a model from the store
* @param {String} resourceName The name of the resource when defined
* @param {Number|String} id The unique ID of the model to find
* @return {Backbone.Model} The Backbone model, or null otherwise
*/
DS.get = function(resourceName, id) {
var model;
var collection;
var idAttribute;
var attr = {};
if (arguments[0] in this.attributes) {
return this.attributes[arguments[0]];
}
return collection.add(data);
} else {
model = store[resourceName];
return model.set(data);
}
};
/**
* Synchronously return a model from the store
* @param {String} resourceName The name of the resource when defined
* @param {Number|String} id The unique ID of the model to find
* @return {Backbone.Model} The Backbone model, or null otherwise
*/
DS.get = function(resourceName, id) {
var model;
var collection;
var idAttribute;
var attr = {};
if (isModelResource(resourceName)) {
return store[resourceName];
} else {
idAttribute = resources[resourceName].idAttribute;
collection = store[resourceName];
if (isModelResource(resourceName)) {
if (collection) {
attr[idAttribute] = id;
model = collection.findWhere(attr);
if (model) {
return model;
}
}
}
return null;
};
/**
* Synchronously return all items from the store for a given resource
* @param {String} resourceName The name of the resource when defined
* @return {Backbone.Collection} The collection associated with resourceName
*/
DS.getAll = function(resourceName) {
return store[resourceName];
} else {
idAttribute = resources[resourceName].idAttribute;
collection = store[resourceName];
};
/**
* Reset all models for a resource
* @param {String} resourceName The name of the resource when defined
*/
DS.ejectAll = function(resourceName) {
var collection = store[resourceName];
if (collection) {
attr[idAttribute] = id;
model = collection.findWhere(attr);
collection.reset();
}
};
if (model) {
return model;
}
}
}
function findModelResource(resourceName) {
var dfd = new $.Deferred();
var model = this.get(resourceName);
return null;
};
if (modelFetched[resourceName]) {
dfd.resolve(model);
} else {
model.fetch().then(function() {
modelFetched[resourceName] = true;
dfd.resolve(model);
});
}
/**
* Synchronously return all items from the store for a given resource
* @param {String} resourceName The name of the resource when defined
* @return {Backbone.Collection} The collection associated with resourceName
*/
DS.getAll = function(resourceName) {
return store[resourceName];
};
/**
* Reset all models for a resource
* @param {String} resourceName The name of the resource when defined
*/
DS.ejectAll = function(resourceName) {
var collection = store[resourceName];
if (collection) {
collection.reset();
return dfd.promise();
}
};
function findModelResource(resourceName) {
var dfd = new $.Deferred();
var model = this.get(resourceName);
function findCollectionResource(resourceName, id) {
var attr = {};
var idAttribute;
var newModel;
var dfd = $.Deferred();
var model;
if (modelFetched[resourceName]) {
dfd.resolve(model);
} else {
model.fetch().then(function() {
modelFetched[resourceName] = true;
dfd.resolve(model);
});
}
model = this.get(resourceName, id);
idAttribute = resources[resourceName].idAttribute;
return dfd.promise();
}
function findCollectionResource(resourceName, id) {
var attr = {};
var idAttribute;
var newModel;
var dfd = $.Deferred();
var model;
if (model) {
if (isIncomplete(resourceName, id)) {
return model.fetch().then(function() {
delete incomplete[resourceName][id];
return model;
});
}
model = this.get(resourceName, id);
idAttribute = resources[resourceName].idAttribute;
dfd.resolve(model);
return dfd.promise();
}
attr[idAttribute] = id;
newModel = new resources[resourceName].model(attr);
if (model) {
if (isIncomplete(resourceName, id)) {
return model.fetch().then(function() {
delete incomplete[resourceName][id];
return model;
});
}
dfd.resolve(model);
return dfd.promise();
return newModel.fetch().then(function() {
DS.inject(resourceName, newModel);
return newModel;
}, function() {
throw new Error('error fetching model: ' + id);
});
}
attr[idAttribute] = id;
newModel = new resources[resourceName].model(attr);
/**
* Find a model from the store. If not in store, fetches it asynchronously
* and puts the model in the store
*
* @param {String} resourceName The name of the resource when defined
* @param {Number|String} id The unique ID of the model to find
* @return {promise} Returns a jQuery promise
*/
DS.find = function(resourceName, id) {
if (isModelResource(resourceName)) {
return findModelResource.call(this, resourceName);
} else {
return findCollectionResource.call(this, resourceName, id);
}
};
return newModel.fetch().then(function() {
DS.inject(resourceName, newModel);
return newModel;
}, function() {
throw new Error('error fetching model: ' + id);
});
}
/**
* Request a collection from the server once and inject models in store.
* This does reset the collection for resourceName.
*/
DS.findAll = function(resourceName, options) {
var collection = store[resourceName];
var dfd = $.Deferred();
/**
* Find a model from the store. If not in store, fetches it asynchronously
* and puts the model in the store
*
* @param {String} resourceName The name of the resource when defined
* @param {Number|String} id The unique ID of the model to find
* @return {promise} Returns a jQuery promise
*/
DS.find = function(resourceName, id) {
if (isModelResource(resourceName)) {
return findModelResource.call(this, resourceName);
} else {
return findCollectionResource.call(this, resourceName, id);
}
};
if (collectionStatus.hasOwnProperty(resourceName)) {
dfd.resolve(collection);
return dfd.promise();
}
/**
* Request a collection from the server once and inject models in store.
* This does reset the collection for resourceName.
*/
DS.findAll = function(resourceName, options) {
var collection = store[resourceName];
var dfd = $.Deferred();
return collection.fetch().then(function(models) {
DS.inject(resourceName, models, options);
collectionStatus[resourceName] = 'completed';
return collection;
}, function() {
throw new Error('error fetching collection: ' + resourceName);
});
};
if (collectionStatus.hasOwnProperty(resourceName)) {
dfd.resolve(collection);
return dfd.promise();
}
/**
* Proxies to Backbone.Collection.prototype.where
* @param {String} resourceName The name of the resource when defined
* @param {Object} attributes Attributes property that is passed to collection.where()
* @return {Collection} A new filtered resource collection
*/
DS.where = function(resourceName, attributes) {
var collection = store[resourceName];
var Collection = resources[resourceName].collection;
var filteredCollection = new Collection();
var models = collection.where(attributes);
return collection.fetch().then(function(models) {
DS.inject(resourceName, models, options);
collectionStatus[resourceName] = 'completed';
return collection;
}, function() {
throw new Error('error fetching collection: ' + resourceName);
});
};
filteredCollection.add(models);
return filteredCollection;
};
/**
* Proxies to Backbone.Collection.prototype.where
* @param {String} resourceName The name of the resource when defined
* @param {Object} attributes Attributes property that is passed to collection.where()
* @return {Collection} A new filtered resource collection
*/
DS.where = function(resourceName, attributes) {
var collection = store[resourceName];
var Collection = resources[resourceName].collection;
var filteredCollection = new Collection();
var models = collection.where(attributes);
DS.filter = function(resourceName, predicate) {
var collection = store[resourceName];
var Collection = resources[resourceName].collection;
var filteredCollection = new Collection();
filteredCollection.add(models);
return filteredCollection;
};
var models = collection.filter(predicate);
filteredCollection.add(models);
DS.filter = function(resourceName, predicate) {
var collection = store[resourceName];
var Collection = resources[resourceName].collection;
var filteredCollection = new Collection();
return filteredCollection;
};
var models = collection.filter(predicate);
filteredCollection.add(models);
DS.update = function(resourceName, id, properties) {
var model = this.get(resourceName, id);
return filteredCollection;
};
model.set(properties);
return model.save().then(function() {
return model;
});
};
DS.update = function(resourceName, id, properties) {
var model = this.get(resourceName, id);
/**
* Saves and injects model into the store
* @param {String} resourceName The name of the resource when defined
* @param {Backbone.Model} model The model to save, probably from DS.createInstance
* @return {Promise} A promise that resolves with the model being saved
*/
DS.create = function(resourceName, model) {
var id = resources[resourceName].idAttribute;
model.set(properties);
return model.save().then(function() {
return model;
});
};
return model.save().then(function(json) {
store[resourceName].add(model);
return model;
});
};
/**
* Saves and injects model into the store
* @param {String} resourceName The name of the resource when defined
* @param {Backbone.Model} model The model to save, probably from DS.createInstance
* @return {Promise} A promise that resolves with the model being saved
*/
DS.create = function(resourceName, model) {
var id = resources[resourceName].idAttribute;
DS.destroy = function(resourceName, id) {
var model = this.get(resourceName, id);
return model.save().then(function(json) {
store[resourceName].add(model);
return model;
});
};
return model.destroy();
};
DS.destroy = function(resourceName, id) {
var model = this.get(resourceName, id);
/**
* Clear out the entire store and all resources
* @return {Object} Return the DS instance
*/
DS.reset = function() {
store = {};
resources = {};
incomplete = {};
collectionStatus = {};
modelFetched = {};
return model.destroy();
};
return this;
};
/**
* Clear out the entire store and all resources
* @return {Object} Return the DS instance
*/
DS.reset = function() {
store = {};
resources = {};
incomplete = {};
collectionStatus = {};
modelFetched = {};
return this;
window.DS = DS;
return DS;
};
window.DS = DS;
if (typeof define === "function" && define.amd) {
define(['backbone'], function(Backbone) {
return DS;
return factory(Backbone);
});
} else {
factory(window.Backbone);
}
})(window);

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

!function(e){function n(e,n){var t,r=u[e].idAttribute;a[e]=a[e]||{},_.isArray(n)?n.forEach(function(n){var t=n[r];a[e][t]=!0}):(t=n[r],a[e][t]=!0)}function t(e,n){return a[e]?a[e][n]:!1}function r(e){return u[e].collection?!1:!0}function i(e){var n=new $.Deferred,t=this.get(e);return l[e]?n.resolve(t):t.fetch().then(function(){l[e]=!0,n.resolve(t)}),n.promise()}function o(e,n){var r,i,o,f={},d=$.Deferred();return o=this.get(e,n),r=u[e].idAttribute,o?t(e,n)?o.fetch().then(function(){return delete a[e][n],o}):(d.resolve(o),d.promise()):(f[r]=n,i=new u[e].model(f),i.fetch().then(function(){return c.inject(e,i),i},function(){throw new Error("error fetching model: "+n)}))}var c={},u={},f={},a={},d={},l={};c.defineResource=function(e){if(!e.hasOwnProperty("name")||!e.name)throw new Error("name must be specified when defining a resource");if(!e.hasOwnProperty("model")||!_.isFunction(e.model))throw new Error("model must be specified when defining a resource");if((!e.hasOwnProperty("idAttribute")||!e.idAttribute)&&e.collection)throw new Error("idAttribute must be specified when defining a resource");if(u[e.name])throw new Error(e.name+" resource has already been defined!");return u[e.name]=e,f[e.name]||(f[e.name]=e.collection?new e.collection:new e.model),this},c.createInstance=function(e){return new u[e].model},c.inject=function(e,t,r){var i,o;return f[e]instanceof Backbone.Collection?(r=_.extend({incomplete:!1},r),i=f[e],r.incomplete&&n(e,t),i.add(t)):(o=f[e],o.set(t))},c.get=function(e,n){var t,i,o,c={};return r(e)?f[e]:(o=u[e].idAttribute,i=f[e],i&&(c[o]=n,t=i.findWhere(c))?t:null)},c.getAll=function(e){return f[e]},c.ejectAll=function(e){var n=f[e];n&&n.reset()},c.find=function(e,n){return r(e)?i.call(this,e):o.call(this,e,n)},c.findAll=function(e,n){var t=f[e],r=$.Deferred();return d.hasOwnProperty(e)?(r.resolve(t),r.promise()):t.fetch().then(function(r){return c.inject(e,r,n),d[e]="completed",t},function(){throw new Error("error fetching collection: "+e)})},c.where=function(e,n){var t=f[e],r=u[e].collection,i=new r,o=t.where(n);return i.add(o),i},c.filter=function(e,n){var t=f[e],r=u[e].collection,i=new r,o=t.filter(n);return i.add(o),i},c.update=function(e,n,t){var r=this.get(e,n);return r.set(t),r.save().then(function(){return r})},c.create=function(e,n){u[e].idAttribute;return n.save().then(function(){return f[e].add(n),n})},c.destroy=function(e,n){var t=this.get(e,n);return t.destroy()},c.reset=function(){return f={},u={},a={},d={},l={},this},e.DS=c,"function"==typeof define&&define.amd&&define(["backbone"],function(){return c})}(window);
!function(e){var n=function(n){function t(e,n){var t,r=f[e].idAttribute;a[e]=a[e]||{},_.isArray(n)?n.forEach(function(n){var t=n[r];a[e][t]=!0}):(t=n[r],a[e][t]=!0)}function r(e,n){return a[e]?a[e][n]:!1}function o(e){return f[e].collection?!1:!0}function i(e){var n=new $.Deferred,t=this.get(e);return s[e]?n.resolve(t):t.fetch().then(function(){s[e]=!0,n.resolve(t)}),n.promise()}function c(e,n){var t,o,i,c={},l=$.Deferred();return i=this.get(e,n),t=f[e].idAttribute,i?r(e,n)?i.fetch().then(function(){return delete a[e][n],i}):(l.resolve(i),l.promise()):(c[t]=n,o=new f[e].model(c),o.fetch().then(function(){return u.inject(e,o),o},function(){throw new Error("error fetching model: "+n)}))}var u=new n.Model,f={},l={},a={},d={},s={};return u.defineResource=function(e){if(!e.hasOwnProperty("name")||!e.name)throw new Error("name must be specified when defining a resource");if((!e.hasOwnProperty("idAttribute")||!e.idAttribute)&&e.collection)throw new Error("idAttribute must be specified when defining a resource");if(f[e.name])throw new Error(e.name+" resource has already been defined!");return!e.model&&e.collection&&(e.model=e.collection.prototype.model),e.hasOwnProperty("idAttribute")&&!e.hasOwnProperty("collection")&&(e.collection=n.Collection),f[e.name]=e,l[e.name]||(e.collection?l[e.name]=new e.collection:(e.model=e.model||n.Model,l[e.name]=new e.model)),this},u.createInstance=function(e){return new f[e].model},u.inject=function(e,r,o){var i,c;return l[e]instanceof n.Collection?(o=_.extend({incomplete:!1},o),i=l[e],o.incomplete&&t(e,r),i.add(r)):(c=l[e],c.set(r))},u.get=function(e,n){var t,r,i,c={};return arguments[0]in this.attributes?this.attributes[arguments[0]]:o(e)?l[e]:(i=f[e].idAttribute,r=l[e],r&&(c[i]=n,t=r.findWhere(c))?t:null)},u.getAll=function(e){return l[e]},u.ejectAll=function(e){var n=l[e];n&&n.reset()},u.find=function(e,n){return o(e)?i.call(this,e):c.call(this,e,n)},u.findAll=function(e,n){var t=l[e],r=$.Deferred();return d.hasOwnProperty(e)?(r.resolve(t),r.promise()):t.fetch().then(function(r){return u.inject(e,r,n),d[e]="completed",t},function(){throw new Error("error fetching collection: "+e)})},u.where=function(e,n){var t=l[e],r=f[e].collection,o=new r,i=t.where(n);return o.add(i),o},u.filter=function(e,n){var t=l[e],r=f[e].collection,o=new r,i=t.filter(n);return o.add(i),o},u.update=function(e,n,t){var r=this.get(e,n);return r.set(t),r.save().then(function(){return r})},u.create=function(e,n){f[e].idAttribute;return n.save().then(function(){return l[e].add(n),n})},u.destroy=function(e,n){var t=this.get(e,n);return t.destroy()},u.reset=function(){return l={},f={},a={},d={},s={},this},e.DS=u,u};"function"==typeof define&&define.amd?define(["backbone"],function(e){return n(e)}):n(e.Backbone)}(window);

@@ -5,3 +5,3 @@ {

"description": "A simple data store for backbone models and collections inspired by Ember Data and angular-data.",
"version": "0.0.5",
"version": "0.0.6",
"repository": {

@@ -8,0 +8,0 @@ "type": "git",

(function(window, undefined) {
var DS = {};
var resources = {};
var store = {};
var incomplete = {};
var collectionStatus = {};
var modelFetched = {};
/**
* @param {String} resourceName The name of the resource when defined
* @param {Array|Object} data A array of object or just a plain json object
*/
function addIncomplete(resourceName, data) {
var idAttribute = resources[resourceName].idAttribute;
var id;
var factory = function(Backbone) {
var DS = new Backbone.Model();
var resources = {};
var store = {};
var incomplete = {};
var collectionStatus = {};
var modelFetched = {};
/**
* @param {String} resourceName The name of the resource when defined
* @param {Array|Object} data A array of object or just a plain json object
*/
function addIncomplete(resourceName, data) {
var idAttribute = resources[resourceName].idAttribute;
var id;
incomplete[resourceName] = incomplete[resourceName] || {};
incomplete[resourceName] = incomplete[resourceName] || {};
if (_.isArray(data)) {
data.forEach(function(item) {
var id = item[idAttribute];
if (_.isArray(data)) {
data.forEach(function(item) {
var id = item[idAttribute];
incomplete[resourceName][id] = true;
});
} else {
id = data[idAttribute];
incomplete[resourceName][id] = true;
});
} else {
id = data[idAttribute];
incomplete[resourceName][id] = true;
}
}
}
/**
* Determine if a model if incomplete or not
* @param {String} resourceName The name of the resource when defined
* @param {Number|String} id The unique ID of the model to find
* @return {Boolean} True if the model is incomplete, false if complete
*/
function isIncomplete(resourceName, id) {
if (incomplete[resourceName]) {
return incomplete[resourceName][id];
/**
* Determine if a model if incomplete or not
* @param {String} resourceName The name of the resource when defined
* @param {Number|String} id The unique ID of the model to find
* @return {Boolean} True if the model is incomplete, false if complete
*/
function isIncomplete(resourceName, id) {
if (incomplete[resourceName]) {
return incomplete[resourceName][id];
}
return false;
}
return false;
}
function isModelResource(resourceName) {
if (resources[resourceName].collection) {
return false;
function isModelResource(resourceName) {
if (resources[resourceName].collection) {
return false;
}
return true;
}
return true;
}
/**
* Define a resource for the store
* @param {Object} resourceDefinition An object containing idAttribute, name, collection, and model
*/
DS.defineResource = function(resourceDefinition) {
if (!resourceDefinition.hasOwnProperty('name') || !resourceDefinition['name']) {
throw new Error('name must be specified when defining a resource');
}
if (!resourceDefinition.hasOwnProperty('idAttribute') || !resourceDefinition['idAttribute']) {
if (resourceDefinition.collection) {
throw new Error('idAttribute must be specified when defining a resource');
}
}
/**
* Define a resource for the store
* @param {Object} resourceDefinition An object containing idAttribute, name, collection, and model
*/
DS.defineResource = function(resourceDefinition) {
if (!resourceDefinition.hasOwnProperty('name') || !resourceDefinition['name']) {
throw new Error('name must be specified when defining a resource');
}
if (resources[resourceDefinition.name]) {
throw new Error(resourceDefinition.name + ' resource has already been defined!');
}
if (!resourceDefinition.hasOwnProperty('model') || !_.isFunction(resourceDefinition['model'])) {
throw new Error('model must be specified when defining a resource');
}
if (!resourceDefinition.hasOwnProperty('idAttribute') || !resourceDefinition['idAttribute']) {
if (resourceDefinition.collection) {
throw new Error('idAttribute must be specified when defining a resource');
if (!resourceDefinition.model && resourceDefinition.collection) {
resourceDefinition.model = resourceDefinition.collection.prototype.model;
}
}
if (resources[resourceDefinition.name]) {
throw new Error(resourceDefinition.name + ' resource has already been defined!');
}
if (resourceDefinition.hasOwnProperty('idAttribute') && !resourceDefinition.hasOwnProperty('collection')) {
resourceDefinition.collection = Backbone.Collection;
}
resources[resourceDefinition.name] = resourceDefinition;
if (!store[resourceDefinition.name]) {
if (resourceDefinition.collection) {
store[resourceDefinition.name] = new resourceDefinition.collection();
} else {
store[resourceDefinition.name] = new resourceDefinition.model();
resources[resourceDefinition.name] = resourceDefinition;
if (!store[resourceDefinition.name]) {
if (resourceDefinition.collection) {
store[resourceDefinition.name] = new resourceDefinition.collection();
} else {
resourceDefinition.model = resourceDefinition.model || Backbone.Model;
store[resourceDefinition.name] = new resourceDefinition.model();
}
}
}
return this;
};
return this;
};
/**
* Create a new instance of a resource
* @param {String} resourceName The name of the resource when defined
* @return {Backbone.Model}
*/
DS.createInstance = function(resourceName) {
return new resources[resourceName].model();
};
/**
* Create a new instance of a resource
* @param {String} resourceName The name of the resource when defined
* @return {Backbone.Model}
*/
DS.createInstance = function(resourceName) {
return new resources[resourceName].model();
};
/**
* Inject data into the store for a given resource
* @param {String} resourceName The name of the resource when defined
* @param {Array|Object} data A array of object or just a plain json object
* @return {Array|Backbone.Model} The added models
*/
DS.inject = function(resourceName, data, options) {
var collection, model;
/**
* Inject data into the store for a given resource
* @param {String} resourceName The name of the resource when defined
* @param {Array|Object} data A array of object or just a plain json object
* @return {Array|Backbone.Model} The added models
*/
DS.inject = function(resourceName, data, options) {
var collection, model;
if (store[resourceName] instanceof Backbone.Collection) {
options = _.extend({ incomplete: false }, options);
collection = store[resourceName];
if (store[resourceName] instanceof Backbone.Collection) {
options = _.extend({ incomplete: false }, options);
collection = store[resourceName];
if (options.incomplete) {
addIncomplete(resourceName, data);
if (options.incomplete) {
addIncomplete(resourceName, data);
}
return collection.add(data);
} else {
model = store[resourceName];
return model.set(data);
}
};
/**
* Synchronously return a model from the store
* @param {String} resourceName The name of the resource when defined
* @param {Number|String} id The unique ID of the model to find
* @return {Backbone.Model} The Backbone model, or null otherwise
*/
DS.get = function(resourceName, id) {
var model;
var collection;
var idAttribute;
var attr = {};
if (arguments[0] in this.attributes) {
return this.attributes[arguments[0]];
}
return collection.add(data);
} else {
model = store[resourceName];
return model.set(data);
}
};
/**
* Synchronously return a model from the store
* @param {String} resourceName The name of the resource when defined
* @param {Number|String} id The unique ID of the model to find
* @return {Backbone.Model} The Backbone model, or null otherwise
*/
DS.get = function(resourceName, id) {
var model;
var collection;
var idAttribute;
var attr = {};
if (isModelResource(resourceName)) {
return store[resourceName];
} else {
idAttribute = resources[resourceName].idAttribute;
collection = store[resourceName];
if (isModelResource(resourceName)) {
if (collection) {
attr[idAttribute] = id;
model = collection.findWhere(attr);
if (model) {
return model;
}
}
}
return null;
};
/**
* Synchronously return all items from the store for a given resource
* @param {String} resourceName The name of the resource when defined
* @return {Backbone.Collection} The collection associated with resourceName
*/
DS.getAll = function(resourceName) {
return store[resourceName];
} else {
idAttribute = resources[resourceName].idAttribute;
collection = store[resourceName];
};
/**
* Reset all models for a resource
* @param {String} resourceName The name of the resource when defined
*/
DS.ejectAll = function(resourceName) {
var collection = store[resourceName];
if (collection) {
attr[idAttribute] = id;
model = collection.findWhere(attr);
collection.reset();
}
};
if (model) {
return model;
}
}
}
function findModelResource(resourceName) {
var dfd = new $.Deferred();
var model = this.get(resourceName);
return null;
};
if (modelFetched[resourceName]) {
dfd.resolve(model);
} else {
model.fetch().then(function() {
modelFetched[resourceName] = true;
dfd.resolve(model);
});
}
/**
* Synchronously return all items from the store for a given resource
* @param {String} resourceName The name of the resource when defined
* @return {Backbone.Collection} The collection associated with resourceName
*/
DS.getAll = function(resourceName) {
return store[resourceName];
};
/**
* Reset all models for a resource
* @param {String} resourceName The name of the resource when defined
*/
DS.ejectAll = function(resourceName) {
var collection = store[resourceName];
if (collection) {
collection.reset();
return dfd.promise();
}
};
function findModelResource(resourceName) {
var dfd = new $.Deferred();
var model = this.get(resourceName);
function findCollectionResource(resourceName, id) {
var attr = {};
var idAttribute;
var newModel;
var dfd = $.Deferred();
var model;
if (modelFetched[resourceName]) {
dfd.resolve(model);
} else {
model.fetch().then(function() {
modelFetched[resourceName] = true;
dfd.resolve(model);
});
}
model = this.get(resourceName, id);
idAttribute = resources[resourceName].idAttribute;
return dfd.promise();
}
function findCollectionResource(resourceName, id) {
var attr = {};
var idAttribute;
var newModel;
var dfd = $.Deferred();
var model;
if (model) {
if (isIncomplete(resourceName, id)) {
return model.fetch().then(function() {
delete incomplete[resourceName][id];
return model;
});
}
model = this.get(resourceName, id);
idAttribute = resources[resourceName].idAttribute;
dfd.resolve(model);
return dfd.promise();
}
attr[idAttribute] = id;
newModel = new resources[resourceName].model(attr);
if (model) {
if (isIncomplete(resourceName, id)) {
return model.fetch().then(function() {
delete incomplete[resourceName][id];
return model;
});
}
dfd.resolve(model);
return dfd.promise();
return newModel.fetch().then(function() {
DS.inject(resourceName, newModel);
return newModel;
}, function() {
throw new Error('error fetching model: ' + id);
});
}
attr[idAttribute] = id;
newModel = new resources[resourceName].model(attr);
/**
* Find a model from the store. If not in store, fetches it asynchronously
* and puts the model in the store
*
* @param {String} resourceName The name of the resource when defined
* @param {Number|String} id The unique ID of the model to find
* @return {promise} Returns a jQuery promise
*/
DS.find = function(resourceName, id) {
if (isModelResource(resourceName)) {
return findModelResource.call(this, resourceName);
} else {
return findCollectionResource.call(this, resourceName, id);
}
};
return newModel.fetch().then(function() {
DS.inject(resourceName, newModel);
return newModel;
}, function() {
throw new Error('error fetching model: ' + id);
});
}
/**
* Request a collection from the server once and inject models in store.
* This does reset the collection for resourceName.
*/
DS.findAll = function(resourceName, options) {
var collection = store[resourceName];
var dfd = $.Deferred();
/**
* Find a model from the store. If not in store, fetches it asynchronously
* and puts the model in the store
*
* @param {String} resourceName The name of the resource when defined
* @param {Number|String} id The unique ID of the model to find
* @return {promise} Returns a jQuery promise
*/
DS.find = function(resourceName, id) {
if (isModelResource(resourceName)) {
return findModelResource.call(this, resourceName);
} else {
return findCollectionResource.call(this, resourceName, id);
}
};
if (collectionStatus.hasOwnProperty(resourceName)) {
dfd.resolve(collection);
return dfd.promise();
}
/**
* Request a collection from the server once and inject models in store.
* This does reset the collection for resourceName.
*/
DS.findAll = function(resourceName, options) {
var collection = store[resourceName];
var dfd = $.Deferred();
return collection.fetch().then(function(models) {
DS.inject(resourceName, models, options);
collectionStatus[resourceName] = 'completed';
return collection;
}, function() {
throw new Error('error fetching collection: ' + resourceName);
});
};
if (collectionStatus.hasOwnProperty(resourceName)) {
dfd.resolve(collection);
return dfd.promise();
}
/**
* Proxies to Backbone.Collection.prototype.where
* @param {String} resourceName The name of the resource when defined
* @param {Object} attributes Attributes property that is passed to collection.where()
* @return {Collection} A new filtered resource collection
*/
DS.where = function(resourceName, attributes) {
var collection = store[resourceName];
var Collection = resources[resourceName].collection;
var filteredCollection = new Collection();
var models = collection.where(attributes);
return collection.fetch().then(function(models) {
DS.inject(resourceName, models, options);
collectionStatus[resourceName] = 'completed';
return collection;
}, function() {
throw new Error('error fetching collection: ' + resourceName);
});
};
filteredCollection.add(models);
return filteredCollection;
};
/**
* Proxies to Backbone.Collection.prototype.where
* @param {String} resourceName The name of the resource when defined
* @param {Object} attributes Attributes property that is passed to collection.where()
* @return {Collection} A new filtered resource collection
*/
DS.where = function(resourceName, attributes) {
var collection = store[resourceName];
var Collection = resources[resourceName].collection;
var filteredCollection = new Collection();
var models = collection.where(attributes);
DS.filter = function(resourceName, predicate) {
var collection = store[resourceName];
var Collection = resources[resourceName].collection;
var filteredCollection = new Collection();
filteredCollection.add(models);
return filteredCollection;
};
var models = collection.filter(predicate);
filteredCollection.add(models);
DS.filter = function(resourceName, predicate) {
var collection = store[resourceName];
var Collection = resources[resourceName].collection;
var filteredCollection = new Collection();
return filteredCollection;
};
var models = collection.filter(predicate);
filteredCollection.add(models);
DS.update = function(resourceName, id, properties) {
var model = this.get(resourceName, id);
return filteredCollection;
};
model.set(properties);
return model.save().then(function() {
return model;
});
};
DS.update = function(resourceName, id, properties) {
var model = this.get(resourceName, id);
/**
* Saves and injects model into the store
* @param {String} resourceName The name of the resource when defined
* @param {Backbone.Model} model The model to save, probably from DS.createInstance
* @return {Promise} A promise that resolves with the model being saved
*/
DS.create = function(resourceName, model) {
var id = resources[resourceName].idAttribute;
model.set(properties);
return model.save().then(function() {
return model;
});
};
return model.save().then(function(json) {
store[resourceName].add(model);
return model;
});
};
/**
* Saves and injects model into the store
* @param {String} resourceName The name of the resource when defined
* @param {Backbone.Model} model The model to save, probably from DS.createInstance
* @return {Promise} A promise that resolves with the model being saved
*/
DS.create = function(resourceName, model) {
var id = resources[resourceName].idAttribute;
DS.destroy = function(resourceName, id) {
var model = this.get(resourceName, id);
return model.save().then(function(json) {
store[resourceName].add(model);
return model;
});
};
return model.destroy();
};
DS.destroy = function(resourceName, id) {
var model = this.get(resourceName, id);
/**
* Clear out the entire store and all resources
* @return {Object} Return the DS instance
*/
DS.reset = function() {
store = {};
resources = {};
incomplete = {};
collectionStatus = {};
modelFetched = {};
return model.destroy();
};
return this;
};
/**
* Clear out the entire store and all resources
* @return {Object} Return the DS instance
*/
DS.reset = function() {
store = {};
resources = {};
incomplete = {};
collectionStatus = {};
modelFetched = {};
return this;
window.DS = DS;
return DS;
};
window.DS = DS;
if (typeof define === "function" && define.amd) {
define(['backbone'], function(Backbone) {
return DS;
return factory(Backbone);
});
} else {
factory(window.Backbone);
}
})(window);

@@ -12,10 +12,38 @@ describe('defineResource()', function() {

it('should throw an error if model is not provided', function() {
afterEach(function() {
DS.ejectAll('person');
DS.reset();
});
it('should use the model associated with the collection if a collection resource', function() {
var Person = Backbone.Model.extend();
var People = Backbone.Collection.extend({
model: Person
});
DS.defineResource({
name: 'person',
idAttribute: 'id',
collection: People
});
var david = DS.createInstance('person');
expect(david).to.be.an.instanceof(Person);
});
it('should use Backbone.Collection if no collection is specified and idAttribute is present', function() {
DS.defineResource({
name: 'employee',
idAttribute: 'id'
});
expect(DS.getAll('employee')).to.be.an.instanceof(Backbone.Collection);
});
it('should use Backbone.Model for model resources if none is specified', function() {
expect(function() {
DS.defineResource({
name: 'person',
idAttribute: 'id',
collection: Backbone.Collection
name: 'user'
});
}).to.throw(Error);
}).not.to.throw(Error);
});

@@ -22,0 +50,0 @@

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