dist/globals/ember-data.prod.js in ember-data-source-2.11.3 vs dist/globals/ember-data.prod.js in ember-data-source-2.12.0.beta.1
- old
+ new
@@ -4,11 +4,11 @@
/*!
* @overview Ember Data
* @copyright Copyright 2011-2016 Tilde Inc. and contributors.
* Portions Copyright 2011 LivingSocial Inc.
* @license Licensed under MIT license (see license.js)
- * @version 2.11.3
+ * @version 2.12.0-beta.1
*/
var loader, define, requireModule, require, requirejs;
(function(global) {
@@ -476,11 +476,11 @@
Builds a URL for a `store.findAll(type)` call.
Example:
```app/adapters/comment.js
import DS from 'ember-data';
export default DS.JSONAPIAdapter.extend({
- urlForFindAll(id, modelName, snapshot) {
+ urlForFindAll(modelName, snapshot) {
return 'data/comments.json';
}
});
```
@method urlForFindAll
@@ -1226,73 +1226,10 @@
});
});
/**
@module ember-data
*/
-define('ember-data/-private/system/debug/debug-info', ['exports', 'ember'], function (exports, _ember) {
- exports.default = _ember.default.Mixin.create({
-
- /**
- Provides info about the model for debugging purposes
- by grouping the properties into more semantic groups.
- Meant to be used by debugging tools such as the Chrome Ember Extension.
- - Groups all attributes in "Attributes" group.
- - Groups all belongsTo relationships in "Belongs To" group.
- - Groups all hasMany relationships in "Has Many" group.
- - Groups all flags in "Flags" group.
- - Flags relationship CPs as expensive properties.
- @method _debugInfo
- @for DS.Model
- @private
- */
- _debugInfo: function () {
- var attributes = ['id'];
- var relationships = {};
- var expensiveProperties = [];
-
- this.eachAttribute(function (name, meta) {
- return attributes.push(name);
- });
-
- var groups = [{
- name: 'Attributes',
- properties: attributes,
- expand: true
- }];
-
- this.eachRelationship(function (name, relationship) {
- var properties = relationships[relationship.kind];
-
- if (properties === undefined) {
- properties = relationships[relationship.kind] = [];
- groups.push({
- name: relationship.name,
- properties: properties,
- expand: true
- });
- }
- properties.push(name);
- expensiveProperties.push(name);
- });
-
- groups.push({
- name: 'Flags',
- properties: ['isLoaded', 'hasDirtyAttributes', 'isSaving', 'isDeleted', 'isError', 'isNew', 'isValid']
- });
-
- return {
- propertyInfo: {
- // include all other mixins / properties (not just the grouped ones)
- includeOtherProperties: true,
- groups: groups,
- // don't pre-calculate unless cached
- expensiveProperties: expensiveProperties
- }
- };
- }
- });
-});
define("ember-data/-private/system/empty-object", ["exports"], function (exports) {
exports.default = EmptyObject;
// This exists because `Object.create(null)` is absurdly slow compared
// to `new EmptyObject()`. In either case, you want a null prototype
// when you're treating the object instances as arbitrary dictionaries
@@ -1310,10 +1247,72 @@
function EmptyObject() {}
EmptyObject.prototype = proto;
});
+define('ember-data/-private/system/identity-map', ['exports', 'ember-data/-private/system/record-map'], function (exports, _emberDataPrivateSystemRecordMap) {
+ var _createClass = (function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ('value' in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })();
+
+ function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }
+
+ /**
+ `IdentityMap` is a custom storage map for records by modelName
+ used by `DS.Store`.
+
+ @class IdentityMap
+ @private
+ */
+
+ var IdentityMap = (function () {
+ function IdentityMap() {
+ this._map = Object.create(null);
+ }
+
+ /**
+ Retrieves the `RecordMap` for a given modelName,
+ creating one if one did not already exist. This is
+ similar to `getWithDefault` or `get` on a `MapWithDefault`
+ @method retrieve
+ @param modelName a previously normalized modelName
+ @returns {RecordMap} the RecordMap for the given modelName
+ */
+
+ _createClass(IdentityMap, [{
+ key: 'retrieve',
+ value: function retrieve(modelName) {
+ var recordMap = this._map[modelName];
+
+ if (!recordMap) {
+ recordMap = this._map[modelName] = new _emberDataPrivateSystemRecordMap.default(modelName);
+ }
+
+ return recordMap;
+ }
+
+ /**
+ Clears the contents of all known `RecordMaps`, but does
+ not remove the RecordMap instances.
+ @method clear
+ */
+ }, {
+ key: 'clear',
+ value: function clear() {
+ var recordMaps = this._map;
+ var keys = Object.keys(recordMaps);
+
+ for (var i = 0; i < keys.length; i++) {
+ var key = keys[i];
+ recordMaps[key].clear();
+ }
+ }
+ }]);
+
+ return IdentityMap;
+ })();
+
+ exports.default = IdentityMap;
+});
define('ember-data/-private/system/is-array-like', ['exports', 'ember'], function (exports, _ember) {
exports.default = isArrayLike;
/*
We're using this to detect arrays and "array-like" objects.
@@ -1473,16 +1472,11 @@
},
flushCanonical: function () {
var isInitialized = arguments.length <= 0 || arguments[0] === undefined ? true : arguments[0];
- // TODO make this smarter, currently its plenty stupid
- // TODO this filtering was re-introduced as a bugfix, but seems unneeded in 2.13
- // with the changes to internalModel cleanup in that version.
- var toSet = this.canonicalState.filter(function (internalModel) {
- return internalModel.currentState.stateName !== 'root.deleted.saved';
- });
+ var toSet = this.canonicalState;
//a hack for not removing new records
//TODO remove once we have proper diffing
var newRecords = this.currentState.filter(
// only add new records which are not yet in the canonical state of this
@@ -1645,199 +1639,10 @@
exports.default = _emberDataPrivateSystemModelModel.default;
});
/**
@module ember-data
*/
-define("ember-data/-private/system/model/attr", ["exports", "ember", "ember-data/-private/debug"], function (exports, _ember, _emberDataPrivateDebug) {
-
- var get = _ember.default.get;
- var Map = _ember.default.Map;
-
- /**
- @module ember-data
- */
-
- /**
- @class Model
- @namespace DS
- */
-
- var AttrClassMethodsMixin = _ember.default.Mixin.create({
- /**
- A map whose keys are the attributes of the model (properties
- described by DS.attr) and whose values are the meta object for the
- property.
- Example
- ```app/models/person.js
- import DS from 'ember-data';
- export default DS.Model.extend({
- firstName: attr('string'),
- lastName: attr('string'),
- birthday: attr('date')
- });
- ```
- ```javascript
- import Ember from 'ember';
- import Person from 'app/models/person';
- var attributes = Ember.get(Person, 'attributes')
- attributes.forEach(function(meta, name) {
- console.log(name, meta);
- });
- // prints:
- // firstName {type: "string", isAttribute: true, options: Object, parentType: function, name: "firstName"}
- // lastName {type: "string", isAttribute: true, options: Object, parentType: function, name: "lastName"}
- // birthday {type: "date", isAttribute: true, options: Object, parentType: function, name: "birthday"}
- ```
- @property attributes
- @static
- @type {Ember.Map}
- @readOnly
- */
- attributes: _ember.default.computed(function () {
- var map = Map.create();
-
- this.eachComputedProperty(function (name, meta) {
- if (meta.isAttribute) {
-
- meta.name = name;
- map.set(name, meta);
- }
- });
-
- return map;
- }).readOnly(),
-
- /**
- A map whose keys are the attributes of the model (properties
- described by DS.attr) and whose values are type of transformation
- applied to each attribute. This map does not include any
- attributes that do not have an transformation type.
- Example
- ```app/models/person.js
- import DS from 'ember-data';
- export default DS.Model.extend({
- firstName: attr(),
- lastName: attr('string'),
- birthday: attr('date')
- });
- ```
- ```javascript
- import Ember from 'ember';
- import Person from 'app/models/person';
- var transformedAttributes = Ember.get(Person, 'transformedAttributes')
- transformedAttributes.forEach(function(field, type) {
- console.log(field, type);
- });
- // prints:
- // lastName string
- // birthday date
- ```
- @property transformedAttributes
- @static
- @type {Ember.Map}
- @readOnly
- */
- transformedAttributes: _ember.default.computed(function () {
- var map = Map.create();
-
- this.eachAttribute(function (key, meta) {
- if (meta.type) {
- map.set(key, meta.type);
- }
- });
-
- return map;
- }).readOnly(),
-
- /**
- Iterates through the attributes of the model, calling the passed function on each
- attribute.
- The callback method you provide should have the following signature (all
- parameters are optional):
- ```javascript
- function(name, meta);
- ```
- - `name` the name of the current property in the iteration
- - `meta` the meta object for the attribute property in the iteration
- Note that in addition to a callback, you can also pass an optional target
- object that will be set as `this` on the context.
- Example
- ```javascript
- import DS from 'ember-data';
- var Person = DS.Model.extend({
- firstName: attr('string'),
- lastName: attr('string'),
- birthday: attr('date')
- });
- Person.eachAttribute(function(name, meta) {
- console.log(name, meta);
- });
- // prints:
- // firstName {type: "string", isAttribute: true, options: Object, parentType: function, name: "firstName"}
- // lastName {type: "string", isAttribute: true, options: Object, parentType: function, name: "lastName"}
- // birthday {type: "date", isAttribute: true, options: Object, parentType: function, name: "birthday"}
- ```
- @method eachAttribute
- @param {Function} callback The callback to execute
- @param {Object} [binding] the value to which the callback's `this` should be bound
- @static
- */
- eachAttribute: function (callback, binding) {
- get(this, 'attributes').forEach(function (meta, name) {
- callback.call(binding, name, meta);
- });
- },
-
- /**
- Iterates through the transformedAttributes of the model, calling
- the passed function on each attribute. Note the callback will not be
- called for any attributes that do not have an transformation type.
- The callback method you provide should have the following signature (all
- parameters are optional):
- ```javascript
- function(name, type);
- ```
- - `name` the name of the current property in the iteration
- - `type` a string containing the name of the type of transformed
- applied to the attribute
- Note that in addition to a callback, you can also pass an optional target
- object that will be set as `this` on the context.
- Example
- ```javascript
- import DS from 'ember-data';
- var Person = DS.Model.extend({
- firstName: attr(),
- lastName: attr('string'),
- birthday: attr('date')
- });
- Person.eachTransformedAttribute(function(name, type) {
- console.log(name, type);
- });
- // prints:
- // lastName string
- // birthday date
- ```
- @method eachTransformedAttribute
- @param {Function} callback The callback to execute
- @param {Object} [binding] the value to which the callback's `this` should be bound
- @static
- */
- eachTransformedAttribute: function (callback, binding) {
- get(this, 'transformedAttributes').forEach(function (type, name) {
- callback.call(binding, name, type);
- });
- }
- });
-
- exports.AttrClassMethodsMixin = AttrClassMethodsMixin;
- var AttrInstanceMethodsMixin = _ember.default.Mixin.create({
- eachAttribute: function (callback, binding) {
- this.constructor.eachAttribute(callback, binding);
- }
- });
- exports.AttrInstanceMethodsMixin = AttrInstanceMethodsMixin;
-});
define('ember-data/-private/system/model/errors', ['exports', 'ember', 'ember-data/-private/debug'], function (exports, _ember, _emberDataPrivateDebug) {
var get = _ember.default.get;
var set = _ember.default.set;
var isEmpty = _ember.default.isEmpty;
@@ -2274,10 +2079,12 @@
}
// this (and all heimdall instrumentation) will be stripped by a babel transform
// https://github.com/heimdalljs/babel5-plugin-strip-heimdall
+ var InternalModelReferenceId = 1;
+
/*
`InternalModel` is the Model class that we use internally inside Ember Data to represent models.
Internal ED methods should only deal with `InternalModel` objects. It is a fast, plain Javascript class.
We expose `DS.Model` to application code, by materializing a `DS.Model` from `InternalModel` lazily, as
@@ -2292,16 +2099,16 @@
@private
@class InternalModel
*/
var InternalModel = (function () {
- function InternalModel(modelClass, id, store, data) {
- this.modelClass = modelClass;
+ function InternalModel(modelName, id, store, data) {
this.id = id;
+ this._internalId = InternalModelReferenceId++;
this.store = store;
this._data = data || new _emberDataPrivateSystemEmptyObject.default();
- this.modelName = modelClass.modelName;
+ this.modelName = modelName;
this.dataHasInitialized = false;
this._loadingPromise = null;
this._recordArrays = undefined;
this._record = null;
this.currentState = _emberDataPrivateSystemModelStates.default.empty;
@@ -2309,10 +2116,11 @@
this._isDestroyed = false;
this.isError = false;
this.error = null;
// caches for lazy getters
+ this._modelClass = null;
this.__deferredTriggers = null;
this._references = null;
this._recordReference = null;
this.__inFlightAttributes = null;
this.__relationships = null;
@@ -2386,11 +2194,11 @@
setOwner(createOptions, (0, _emberDataPrivateUtils.getOwner)(this.store));
} else {
createOptions.container = this.store.container;
}
- this._record = this.store.modelFactoryFor(this.modelName).create(createOptions);
+ this._record = this.modelClass._create(createOptions);
this._triggerDeferredTriggers();
}
return this._record;
@@ -2927,11 +2735,11 @@
*/
}, {
key: "updateRecordArrays",
value: function updateRecordArrays() {
this._updatingRecordArraysLater = false;
- this.store.dataWasUpdated(this.modelClass, this);
+ this.store._dataWasUpdated(this);
}
}, {
key: "setId",
value: function setId(id) {
this.id = id;
@@ -3174,10 +2982,15 @@
}
return reference;
}
}, {
+ key: "modelClass",
+ get: function () {
+ return this._modelClass || (this._modelClass = this.store._modelFor(this.modelName));
+ }
+ }, {
key: "type",
get: function () {
return this.modelClass;
}
}, {
@@ -3301,13 +3114,14 @@
return this._data[key];
}
};
}
});
-define("ember-data/-private/system/model/model", ["exports", "ember", "ember-data/-private/debug", "ember-data/-private/system/promise-proxies", "ember-data/-private/system/model/errors", "ember-data/-private/system/debug/debug-info", "ember-data/-private/system/relationships/belongs-to", "ember-data/-private/system/relationships/has-many", "ember-data/-private/system/relationships/ext", "ember-data/-private/system/model/attr", "ember-data/-private/features", "ember-data/-private/system/model/states"], function (exports, _ember, _emberDataPrivateDebug, _emberDataPrivateSystemPromiseProxies, _emberDataPrivateSystemModelErrors, _emberDataPrivateSystemDebugDebugInfo, _emberDataPrivateSystemRelationshipsBelongsTo, _emberDataPrivateSystemRelationshipsHasMany, _emberDataPrivateSystemRelationshipsExt, _emberDataPrivateSystemModelAttr, _emberDataPrivateFeatures, _emberDataPrivateSystemModelStates) {
+define("ember-data/-private/system/model/model", ["exports", "ember", "ember-data/-private/debug", "ember-data/-private/system/promise-proxies", "ember-data/-private/system/model/errors", "ember-data/-private/features", "ember-data/-private/system/model/states", "ember-data/-private/system/empty-object", "ember-data/-private/system/relationships/ext"], function (exports, _ember, _emberDataPrivateDebug, _emberDataPrivateSystemPromiseProxies, _emberDataPrivateSystemModelErrors, _emberDataPrivateFeatures, _emberDataPrivateSystemModelStates, _emberDataPrivateSystemEmptyObject, _emberDataPrivateSystemRelationshipsExt) {
var get = _ember.default.get;
var computed = _ember.default.computed;
+ var Map = _ember.default.Map;
/**
@module ember-data
*/
@@ -3373,11 +3187,11 @@
record enters this state when its data is populated. Most of a
record's lifecycle is spent inside substates of the `loaded`
state.
Example
```javascript
- var record = store.createRecord('model');
+ let record = store.createRecord('model');
record.get('isLoaded'); // true
store.findRecord('model', 1).then(function(model) {
model.get('isLoaded'); // true
});
```
@@ -3391,11 +3205,11 @@
record has local changes that have not yet been saved by the
adapter. This includes records that have been created (but not yet
saved) or deleted.
Example
```javascript
- var record = store.createRecord('model');
+ let record = store.createRecord('model');
record.get('hasDirtyAttributes'); // true
store.findRecord('model', 1).then(function(model) {
model.get('hasDirtyAttributes'); // false
model.set('foo', 'some value');
model.get('hasDirtyAttributes'); // true
@@ -3414,13 +3228,13 @@
record enters the saving state when `save` is called, but the
adapter has not yet acknowledged that the changes have been
persisted to the backend.
Example
```javascript
- var record = store.createRecord('model');
+ let record = store.createRecord('model');
record.get('isSaving'); // false
- var promise = record.save();
+ let promise = record.save();
record.get('isSaving'); // true
promise.then(function() {
record.get('isSaving'); // false
});
```
@@ -3436,19 +3250,19 @@
was not yet persisted. When `isSaving` is true, the change is
in-flight. When both `hasDirtyAttributes` and `isSaving` are false, the
change has persisted.
Example
```javascript
- var record = store.createRecord('model');
+ let record = store.createRecord('model');
record.get('isDeleted'); // false
record.deleteRecord();
// Locally deleted
record.get('isDeleted'); // true
record.get('hasDirtyAttributes'); // true
record.get('isSaving'); // false
// Persisting the deletion
- var promise = record.save();
+ let promise = record.save();
record.get('isDeleted'); // true
record.get('isSaving'); // true
// Deletion Persisted
promise.then(function() {
record.get('isDeleted'); // true
@@ -3466,11 +3280,11 @@
record will be in the `new` state when it has been created on the
client and the adapter has not yet report that it was successfully
saved.
Example
```javascript
- var record = store.createRecord('model');
+ let record = store.createRecord('model');
record.get('isNew'); // true
record.save().then(function(model) {
model.get('isNew'); // false
});
```
@@ -3495,11 +3309,11 @@
- `created` The record has been created by the client and not yet saved to the adapter.
- `updated` The record has been updated by the client and not yet saved to the adapter.
- `deleted` The record has been deleted by the client and not yet saved to the adapter.
Example
```javascript
- var record = store.createRecord('model');
+ let record = store.createRecord('model');
record.get('dirtyType'); // 'created'
```
@property dirtyType
@type {String}
@readOnly
@@ -3523,11 +3337,11 @@
@readOnly
*/
isError: false,
/**
- If `true` the store is attempting to reload the record form the adapter.
+ If `true` the store is attempting to reload the record from the adapter.
Example
```javascript
record.get('isReloading'); // false
record.reload();
record.get('isReloading'); // true
@@ -3543,11 +3357,11 @@
managed by an external source. These are always coerced to be
strings before being used internally. Note when declaring the
attributes for a model it is an error to declare an id
attribute.
```javascript
- var record = store.createRecord('model');
+ let record = store.createRecord('model');
record.get('id'); // null
store.findRecord('model', 1).then(function(model) {
model.get('id'); // '1'
});
```
@@ -3730,11 +3544,11 @@
/**
Marks the record as deleted but does not save it. You must call
`save` afterwards if you want to persist it. You might use this
method if you want to allow the user to still `rollbackAttributes()`
- after a delete it was made.
+ after a delete was made.
Example
```app/routes/model/delete.js
import Ember from 'ember';
export default Ember.Route.extend({
actions: {
@@ -3762,20 +3576,20 @@
```app/routes/model/delete.js
import Ember from 'ember';
export default Ember.Route.extend({
actions: {
delete: function() {
- var controller = this.controller;
+ let controller = this.controller;
controller.get('model').destroyRecord().then(function() {
controller.transitionToRoute('model.index');
});
}
}
});
```
If you pass an object on the `adapterOptions` property of the options
- argument it will be passed to you adapter via the snapshot
+ argument it will be passed to your adapter via the snapshot
```js
record.destroyRecord({ adapterOptions: { subscribe: false } });
```
```app/adapters/post.js
import MyCustomAdapter from './custom-adapter';
@@ -3813,12 +3627,12 @@
@method _notifyProperties
@private
*/
_notifyProperties: function (keys) {
_ember.default.beginPropertyChanges();
- var key;
- for (var i = 0, length = keys.length; i < length; i++) {
+ var key = undefined;
+ for (var i = 0, _length = keys.length; i < _length; i++) {
key = keys[i];
this.notifyPropertyChange(key);
}
_ember.default.endPropertyChanges();
},
@@ -3838,11 +3652,11 @@
defaultValue: false
})
});
```
```javascript
- var mascot = store.createRecord('mascot');
+ let mascot = store.createRecord('mascot');
mascot.changedAttributes(); // {}
mascot.set('name', 'Tomster');
mascot.changedAttributes(); // { name: [undefined, 'Tomster'] }
mascot.set('isAdmin', true);
mascot.changedAttributes(); // { isAdmin: [undefined, true], name: [undefined, 'Tomster'] }
@@ -4017,34 +3831,37 @@
attr: function () {},
/**
Get the reference for the specified belongsTo relationship.
Example
- ```javascript
- // models/blog.js
+ ```app/models/blog.js
export default DS.Model.extend({
user: DS.belongsTo({ async: true })
});
- var blog = store.push({
- type: 'blog',
- id: 1,
- relationships: {
- user: {
- data: { type: 'user', id: 1 }
+ ```
+ ```javascript
+ let blog = store.push({
+ data: {
+ type: 'blog',
+ id: 1,
+ relationships: {
+ user: {
+ data: { type: 'user', id: 1 }
+ }
}
}
});
- var userRef = blog.belongsTo('user');
+ let userRef = blog.belongsTo('user');
// check if the user relationship is loaded
- var isLoaded = userRef.value() !== null;
+ let isLoaded = userRef.value() !== null;
// get the record of the reference (null if not yet available)
- var user = userRef.value();
+ let user = userRef.value();
// get the identifier of the reference
if (userRef.remoteType() === "id") {
- var id = userRef.id();
+ let id = userRef.id();
} else if (userRef.remoteType() === "link") {
- var link = userRef.link();
+ let link = userRef.link();
}
// load user (via store.findRecord or store.findBelongsTo)
userRef.load().then(...)
// or trigger a reload
userRef.reload().then(...)
@@ -4074,32 +3891,34 @@
```javascript
// models/blog.js
export default DS.Model.extend({
comments: DS.hasMany({ async: true })
});
- var blog = store.push({
- type: 'blog',
- id: 1,
- relationships: {
- comments: {
- data: [
- { type: 'comment', id: 1 },
- { type: 'comment', id: 2 }
- ]
+ let blog = store.push({
+ data: {
+ type: 'blog',
+ id: 1,
+ relationships: {
+ comments: {
+ data: [
+ { type: 'comment', id: 1 },
+ { type: 'comment', id: 2 }
+ ]
+ }
}
}
});
- var commentsRef = blog.hasMany('comments');
+ let commentsRef = blog.hasMany('comments');
// check if the comments are loaded already
- var isLoaded = commentsRef.value() !== null;
+ let isLoaded = commentsRef.value() !== null;
// get the records of the reference (null if not yet available)
- var comments = commentsRef.value();
+ let comments = commentsRef.value();
// get the identifier of the reference
if (commentsRef.remoteType() === "ids") {
- var ids = commentsRef.ids();
+ let ids = commentsRef.ids();
} else if (commentsRef.remoteType() === "link") {
- var link = commentsRef.link();
+ let link = commentsRef.link();
}
// load comments (via store.findMany or store.findHasMany)
commentsRef.load().then(...)
// or trigger a reload
commentsRef.reload().then(...)
@@ -4117,11 +3936,172 @@
return this._internalModel.referenceFor('hasMany', name);
},
setId: _ember.default.observer('id', function () {
this._internalModel.setId(this.get('id'));
- })
+ }),
+
+ /**
+ Provides info about the model for debugging purposes
+ by grouping the properties into more semantic groups.
+ Meant to be used by debugging tools such as the Chrome Ember Extension.
+ - Groups all attributes in "Attributes" group.
+ - Groups all belongsTo relationships in "Belongs To" group.
+ - Groups all hasMany relationships in "Has Many" group.
+ - Groups all flags in "Flags" group.
+ - Flags relationship CPs as expensive properties.
+ @method _debugInfo
+ @for DS.Model
+ @private
+ */
+ _debugInfo: function () {
+ var attributes = ['id'];
+ var relationships = {};
+ var expensiveProperties = [];
+
+ this.eachAttribute(function (name, meta) {
+ return attributes.push(name);
+ });
+
+ var groups = [{
+ name: 'Attributes',
+ properties: attributes,
+ expand: true
+ }];
+
+ this.eachRelationship(function (name, relationship) {
+ var properties = relationships[relationship.kind];
+
+ if (properties === undefined) {
+ properties = relationships[relationship.kind] = [];
+ groups.push({
+ name: relationship.name,
+ properties: properties,
+ expand: true
+ });
+ }
+ properties.push(name);
+ expensiveProperties.push(name);
+ });
+
+ groups.push({
+ name: 'Flags',
+ properties: ['isLoaded', 'hasDirtyAttributes', 'isSaving', 'isDeleted', 'isError', 'isNew', 'isValid']
+ });
+
+ return {
+ propertyInfo: {
+ // include all other mixins / properties (not just the grouped ones)
+ includeOtherProperties: true,
+ groups: groups,
+ // don't pre-calculate unless cached
+ expensiveProperties: expensiveProperties
+ }
+ };
+ },
+
+ notifyBelongsToChanged: function (key) {
+ this.notifyPropertyChange(key);
+ },
+
+ /**
+ This Ember.js hook allows an object to be notified when a property
+ is defined.
+ In this case, we use it to be notified when an Ember Data user defines a
+ belongs-to relationship. In that case, we need to set up observers for
+ each one, allowing us to track relationship changes and automatically
+ reflect changes in the inverse has-many array.
+ This hook passes the class being set up, as well as the key and value
+ being defined. So, for example, when the user does this:
+ ```javascript
+ DS.Model.extend({
+ parent: DS.belongsTo('user')
+ });
+ ```
+ This hook would be called with "parent" as the key and the computed
+ property returned by `DS.belongsTo` as the value.
+ @method didDefineProperty
+ @param {Object} proto
+ @param {String} key
+ @param {Ember.ComputedProperty} value
+ */
+ didDefineProperty: function (proto, key, value) {
+ // Check if the value being set is a computed property.
+ if (value instanceof _ember.default.ComputedProperty) {
+
+ // If it is, get the metadata for the relationship. This is
+ // populated by the `DS.belongsTo` helper when it is creating
+ // the computed property.
+ var meta = value.meta();
+
+ meta.parentType = proto.constructor;
+ }
+ },
+
+ /**
+ Given a callback, iterates over each of the relationships in the model,
+ invoking the callback with the name of each relationship and its relationship
+ descriptor.
+ The callback method you provide should have the following signature (all
+ parameters are optional):
+ ```javascript
+ function(name, descriptor);
+ ```
+ - `name` the name of the current property in the iteration
+ - `descriptor` the meta object that describes this relationship
+ The relationship descriptor argument is an object with the following properties.
+ - **key** <span class="type">String</span> the name of this relationship on the Model
+ - **kind** <span class="type">String</span> "hasMany" or "belongsTo"
+ - **options** <span class="type">Object</span> the original options hash passed when the relationship was declared
+ - **parentType** <span class="type">DS.Model</span> the type of the Model that owns this relationship
+ - **type** <span class="type">String</span> the type name of the related Model
+ Note that in addition to a callback, you can also pass an optional target
+ object that will be set as `this` on the context.
+ Example
+ ```app/serializers/application.js
+ import DS from 'ember-data';
+ export default DS.JSONSerializer.extend({
+ serialize: function(record, options) {
+ let json = {};
+ record.eachRelationship(function(name, descriptor) {
+ if (descriptor.kind === 'hasMany') {
+ let serializedHasManyName = name.toUpperCase() + '_IDS';
+ json[serializedHasManyName] = record.get(name).mapBy('id');
+ }
+ });
+ return json;
+ }
+ });
+ ```
+ @method eachRelationship
+ @param {Function} callback the callback to invoke
+ @param {any} binding the value to which the callback's `this` should be bound
+ */
+ eachRelationship: function (callback, binding) {
+ this.constructor.eachRelationship(callback, binding);
+ },
+
+ relationshipFor: function (name) {
+ return get(this.constructor, 'relationshipsByName').get(name);
+ },
+
+ inverseFor: function (key) {
+ return this.constructor.inverseFor(key, this.store);
+ },
+
+ notifyHasManyAdded: function (key) {
+ //We need to notifyPropertyChange in the adding case because we need to make sure
+ //we fetch the newly added record in case it is unloaded
+ //TODO(Igor): Consider whether we could do this only if the record state is unloaded
+
+ //Goes away once hasMany is double promisified
+ this.notifyPropertyChange(key);
+ },
+
+ eachAttribute: function (callback, binding) {
+ this.constructor.eachAttribute(callback, binding);
+ }
});
/**
@property data
@private
@@ -4132,11 +4112,19 @@
return this._internalModel._data;
}
});
Model.reopenClass({
- isModel: true,
+ /**
+ Alias DS.Model's `create` method to `_create`. This allows us to create DS.Model
+ instances from within the store, but if end users accidentally call `create()`
+ (instead of `createRecord()`), we can raise an error.
+ @method _create
+ @private
+ @static
+ */
+ _create: Model.create,
/**
Override the class' `create()` method to raise an error. This
prevents end users from inadvertently calling `create()` instead
of `createRecord()`. The store is still able to create instances
@@ -4144,10 +4132,14 @@
`DS.Model` use [store.createRecord](DS.Store.html#method_createRecord).
@method create
@private
@static
*/
+ create: function () {
+ throw new _ember.default.Error("You should not call `create` on a model. Instead, call `store.createRecord` with the attributes you would like to set.");
+ },
+
/**
Represents the model's class name as a string. This can be used to look up the model through
DS.Store's modelFor method.
`modelName` is generated for you by Ember Data. It will be a lowercased, dasherized string.
For example:
@@ -4156,22 +4148,583 @@
store.modelFor('blog-post').modelName; // 'blog-post'
```
The most common place you'll want to access `modelName` is in your serializer's `payloadKeyFromModelName` method. For example, to change payload
keys to underscore (instead of dasherized), you might use the following code:
```javascript
- export default var PostSerializer = DS.RESTSerializer.extend({
+ export default const PostSerializer = DS.RESTSerializer.extend({
payloadKeyFromModelName: function(modelName) {
return Ember.String.underscore(modelName);
}
});
```
@property modelName
@type String
@readonly
@static
*/
- modelName: null
+ modelName: null,
+
+ /*
+ These class methods below provide relationship
+ introspection abilities about relationships.
+ A note about the computed properties contained here:
+ **These properties are effectively sealed once called for the first time.**
+ To avoid repeatedly doing expensive iteration over a model's fields, these
+ values are computed once and then cached for the remainder of the runtime of
+ your application.
+ If your application needs to modify a class after its initial definition
+ (for example, using `reopen()` to add additional attributes), make sure you
+ do it before using your model with the store, which uses these properties
+ extensively.
+ */
+
+ /**
+ For a given relationship name, returns the model type of the relationship.
+ For example, if you define a model like this:
+ ```app/models/post.js
+ import DS from 'ember-data';
+ export default DS.Model.extend({
+ comments: DS.hasMany('comment')
+ });
+ ```
+ Calling `store.modelFor('post').typeForRelationship('comments', store)` will return `Comment`.
+ @method typeForRelationship
+ @static
+ @param {String} name the name of the relationship
+ @param {store} store an instance of DS.Store
+ @return {DS.Model} the type of the relationship, or undefined
+ */
+ typeForRelationship: function (name, store) {
+ var relationship = get(this, 'relationshipsByName').get(name);
+ return relationship && store.modelFor(relationship.type);
+ },
+
+ inverseMap: _ember.default.computed(function () {
+ return new _emberDataPrivateSystemEmptyObject.default();
+ }),
+
+ /**
+ Find the relationship which is the inverse of the one asked for.
+ For example, if you define models like this:
+ ```app/models/post.js
+ import DS from 'ember-data';
+ export default DS.Model.extend({
+ comments: DS.hasMany('message')
+ });
+ ```
+ ```app/models/message.js
+ import DS from 'ember-data';
+ export default DS.Model.extend({
+ owner: DS.belongsTo('post')
+ });
+ ```
+ store.modelFor('post').inverseFor('comments', store) -> { type: App.Message, name: 'owner', kind: 'belongsTo' }
+ store.modelFor('message').inverseFor('owner', store) -> { type: App.Post, name: 'comments', kind: 'hasMany' }
+ @method inverseFor
+ @static
+ @param {String} name the name of the relationship
+ @param {DS.Store} store
+ @return {Object} the inverse relationship, or null
+ */
+ inverseFor: function (name, store) {
+ var inverseMap = get(this, 'inverseMap');
+ if (inverseMap[name]) {
+ return inverseMap[name];
+ } else {
+ var inverse = this._findInverseFor(name, store);
+ inverseMap[name] = inverse;
+ return inverse;
+ }
+ },
+
+ //Calculate the inverse, ignoring the cache
+ _findInverseFor: function (name, store) {
+
+ var inverseType = this.typeForRelationship(name, store);
+ if (!inverseType) {
+ return null;
+ }
+
+ var propertyMeta = this.metaForProperty(name);
+ //If inverse is manually specified to be null, like `comments: DS.hasMany('message', { inverse: null })`
+ var options = propertyMeta.options;
+ if (options.inverse === null) {
+ return null;
+ }
+
+ var inverseName = undefined,
+ inverseKind = undefined,
+ inverse = undefined;
+
+ //If inverse is specified manually, return the inverse
+ if (options.inverse) {
+ inverseName = options.inverse;
+ inverse = _ember.default.get(inverseType, 'relationshipsByName').get(inverseName);
+
+ inverseKind = inverse.kind;
+ } else {
+ //No inverse was specified manually, we need to use a heuristic to guess one
+ if (propertyMeta.type === propertyMeta.parentType.modelName) {}
+
+ var possibleRelationships = findPossibleInverses(this, inverseType);
+
+ if (possibleRelationships.length === 0) {
+ return null;
+ }
+
+ var filteredRelationships = possibleRelationships.filter(function (possibleRelationship) {
+ var optionsForRelationship = inverseType.metaForProperty(possibleRelationship.name).options;
+ return name === optionsForRelationship.inverse;
+ });
+
+ if (filteredRelationships.length === 1) {
+ possibleRelationships = filteredRelationships;
+ }
+
+ inverseName = possibleRelationships[0].name;
+ inverseKind = possibleRelationships[0].kind;
+ }
+
+ function findPossibleInverses(type, inverseType, relationshipsSoFar) {
+ var possibleRelationships = relationshipsSoFar || [];
+
+ var relationshipMap = get(inverseType, 'relationships');
+ if (!relationshipMap) {
+ return possibleRelationships;
+ }
+
+ var relationships = relationshipMap.get(type.modelName);
+
+ relationships = relationships.filter(function (relationship) {
+ var optionsForRelationship = inverseType.metaForProperty(relationship.name).options;
+
+ if (!optionsForRelationship.inverse) {
+ return true;
+ }
+
+ return name === optionsForRelationship.inverse;
+ });
+
+ if (relationships) {
+ possibleRelationships.push.apply(possibleRelationships, relationships);
+ }
+
+ //Recurse to support polymorphism
+ if (type.superclass) {
+ findPossibleInverses(type.superclass, inverseType, possibleRelationships);
+ }
+
+ return possibleRelationships;
+ }
+
+ return {
+ type: inverseType,
+ name: inverseName,
+ kind: inverseKind
+ };
+ },
+
+ /**
+ The model's relationships as a map, keyed on the type of the
+ relationship. The value of each entry is an array containing a descriptor
+ for each relationship with that type, describing the name of the relationship
+ as well as the type.
+ For example, given the following model definition:
+ ```app/models/blog.js
+ import DS from 'ember-data';
+ export default DS.Model.extend({
+ users: DS.hasMany('user'),
+ owner: DS.belongsTo('user'),
+ posts: DS.hasMany('post')
+ });
+ ```
+ This computed property would return a map describing these
+ relationships, like this:
+ ```javascript
+ import Ember from 'ember';
+ import Blog from 'app/models/blog';
+ import User from 'app/models/user';
+ import Post from 'app/models/post';
+ let relationships = Ember.get(Blog, 'relationships');
+ relationships.get(User);
+ //=> [ { name: 'users', kind: 'hasMany' },
+ // { name: 'owner', kind: 'belongsTo' } ]
+ relationships.get(Post);
+ //=> [ { name: 'posts', kind: 'hasMany' } ]
+ ```
+ @property relationships
+ @static
+ @type Ember.Map
+ @readOnly
+ */
+
+ relationships: _emberDataPrivateSystemRelationshipsExt.relationshipsDescriptor,
+
+ /**
+ A hash containing lists of the model's relationships, grouped
+ by the relationship kind. For example, given a model with this
+ definition:
+ ```app/models/blog.js
+ import DS from 'ember-data';
+ export default DS.Model.extend({
+ users: DS.hasMany('user'),
+ owner: DS.belongsTo('user'),
+ posts: DS.hasMany('post')
+ });
+ ```
+ This property would contain the following:
+ ```javascript
+ import Ember from 'ember';
+ import Blog from 'app/models/blog';
+ let relationshipNames = Ember.get(Blog, 'relationshipNames');
+ relationshipNames.hasMany;
+ //=> ['users', 'posts']
+ relationshipNames.belongsTo;
+ //=> ['owner']
+ ```
+ @property relationshipNames
+ @static
+ @type Object
+ @readOnly
+ */
+ relationshipNames: _ember.default.computed(function () {
+ var names = {
+ hasMany: [],
+ belongsTo: []
+ };
+
+ this.eachComputedProperty(function (name, meta) {
+ if (meta.isRelationship) {
+ names[meta.kind].push(name);
+ }
+ });
+
+ return names;
+ }),
+
+ /**
+ An array of types directly related to a model. Each type will be
+ included once, regardless of the number of relationships it has with
+ the model.
+ For example, given a model with this definition:
+ ```app/models/blog.js
+ import DS from 'ember-data';
+ export default DS.Model.extend({
+ users: DS.hasMany('user'),
+ owner: DS.belongsTo('user'),
+ posts: DS.hasMany('post')
+ });
+ ```
+ This property would contain the following:
+ ```javascript
+ import Ember from 'ember';
+ import Blog from 'app/models/blog';
+ let relatedTypes = Ember.get(Blog, 'relatedTypes');
+ //=> [ User, Post ]
+ ```
+ @property relatedTypes
+ @static
+ @type Ember.Array
+ @readOnly
+ */
+ relatedTypes: _emberDataPrivateSystemRelationshipsExt.relatedTypesDescriptor,
+
+ /**
+ A map whose keys are the relationships of a model and whose values are
+ relationship descriptors.
+ For example, given a model with this
+ definition:
+ ```app/models/blog.js
+ import DS from 'ember-data';
+ export default DS.Model.extend({
+ users: DS.hasMany('user'),
+ owner: DS.belongsTo('user'),
+ posts: DS.hasMany('post')
+ });
+ ```
+ This property would contain the following:
+ ```javascript
+ import Ember from 'ember';
+ import Blog from 'app/models/blog';
+ let relationshipsByName = Ember.get(Blog, 'relationshipsByName');
+ relationshipsByName.get('users');
+ //=> { key: 'users', kind: 'hasMany', type: 'user', options: Object, isRelationship: true }
+ relationshipsByName.get('owner');
+ //=> { key: 'owner', kind: 'belongsTo', type: 'user', options: Object, isRelationship: true }
+ ```
+ @property relationshipsByName
+ @static
+ @type Ember.Map
+ @readOnly
+ */
+ relationshipsByName: _emberDataPrivateSystemRelationshipsExt.relationshipsByNameDescriptor,
+
+ /**
+ A map whose keys are the fields of the model and whose values are strings
+ describing the kind of the field. A model's fields are the union of all of its
+ attributes and relationships.
+ For example:
+ ```app/models/blog.js
+ import DS from 'ember-data';
+ export default DS.Model.extend({
+ users: DS.hasMany('user'),
+ owner: DS.belongsTo('user'),
+ posts: DS.hasMany('post'),
+ title: DS.attr('string')
+ });
+ ```
+ ```js
+ import Ember from 'ember';
+ import Blog from 'app/models/blog';
+ let fields = Ember.get(Blog, 'fields');
+ fields.forEach(function(kind, field) {
+ console.log(field, kind);
+ });
+ // prints:
+ // users, hasMany
+ // owner, belongsTo
+ // posts, hasMany
+ // title, attribute
+ ```
+ @property fields
+ @static
+ @type Ember.Map
+ @readOnly
+ */
+ fields: _ember.default.computed(function () {
+ var map = Map.create();
+
+ this.eachComputedProperty(function (name, meta) {
+ if (meta.isRelationship) {
+ map.set(name, meta.kind);
+ } else if (meta.isAttribute) {
+ map.set(name, 'attribute');
+ }
+ });
+
+ return map;
+ }).readOnly(),
+
+ /**
+ Given a callback, iterates over each of the relationships in the model,
+ invoking the callback with the name of each relationship and its relationship
+ descriptor.
+ @method eachRelationship
+ @static
+ @param {Function} callback the callback to invoke
+ @param {any} binding the value to which the callback's `this` should be bound
+ */
+ eachRelationship: function (callback, binding) {
+ get(this, 'relationshipsByName').forEach(function (relationship, name) {
+ callback.call(binding, name, relationship);
+ });
+ },
+
+ /**
+ Given a callback, iterates over each of the types related to a model,
+ invoking the callback with the related type's class. Each type will be
+ returned just once, regardless of how many different relationships it has
+ with a model.
+ @method eachRelatedType
+ @static
+ @param {Function} callback the callback to invoke
+ @param {any} binding the value to which the callback's `this` should be bound
+ */
+ eachRelatedType: function (callback, binding) {
+ var relationshipTypes = get(this, 'relatedTypes');
+
+ for (var i = 0; i < relationshipTypes.length; i++) {
+ var type = relationshipTypes[i];
+ callback.call(binding, type);
+ }
+ },
+
+ determineRelationshipType: function (knownSide, store) {
+ var knownKey = knownSide.key;
+ var knownKind = knownSide.kind;
+ var inverse = this.inverseFor(knownKey, store);
+ // let key;
+ var otherKind = undefined;
+
+ if (!inverse) {
+ return knownKind === 'belongsTo' ? 'oneToNone' : 'manyToNone';
+ }
+
+ // key = inverse.name;
+ otherKind = inverse.kind;
+
+ if (otherKind === 'belongsTo') {
+ return knownKind === 'belongsTo' ? 'oneToOne' : 'manyToOne';
+ } else {
+ return knownKind === 'belongsTo' ? 'oneToMany' : 'manyToMany';
+ }
+ },
+
+ /**
+ A map whose keys are the attributes of the model (properties
+ described by DS.attr) and whose values are the meta object for the
+ property.
+ Example
+ ```app/models/person.js
+ import DS from 'ember-data';
+ export default DS.Model.extend({
+ firstName: attr('string'),
+ lastName: attr('string'),
+ birthday: attr('date')
+ });
+ ```
+ ```javascript
+ import Ember from 'ember';
+ import Person from 'app/models/person';
+ let attributes = Ember.get(Person, 'attributes')
+ attributes.forEach(function(meta, name) {
+ console.log(name, meta);
+ });
+ // prints:
+ // firstName {type: "string", isAttribute: true, options: Object, parentType: function, name: "firstName"}
+ // lastName {type: "string", isAttribute: true, options: Object, parentType: function, name: "lastName"}
+ // birthday {type: "date", isAttribute: true, options: Object, parentType: function, name: "birthday"}
+ ```
+ @property attributes
+ @static
+ @type {Ember.Map}
+ @readOnly
+ */
+ attributes: _ember.default.computed(function () {
+ var map = Map.create();
+
+ this.eachComputedProperty(function (name, meta) {
+ if (meta.isAttribute) {
+
+ meta.name = name;
+ map.set(name, meta);
+ }
+ });
+
+ return map;
+ }).readOnly(),
+
+ /**
+ A map whose keys are the attributes of the model (properties
+ described by DS.attr) and whose values are type of transformation
+ applied to each attribute. This map does not include any
+ attributes that do not have an transformation type.
+ Example
+ ```app/models/person.js
+ import DS from 'ember-data';
+ export default DS.Model.extend({
+ firstName: attr(),
+ lastName: attr('string'),
+ birthday: attr('date')
+ });
+ ```
+ ```javascript
+ import Ember from 'ember';
+ import Person from 'app/models/person';
+ let transformedAttributes = Ember.get(Person, 'transformedAttributes')
+ transformedAttributes.forEach(function(field, type) {
+ console.log(field, type);
+ });
+ // prints:
+ // lastName string
+ // birthday date
+ ```
+ @property transformedAttributes
+ @static
+ @type {Ember.Map}
+ @readOnly
+ */
+ transformedAttributes: _ember.default.computed(function () {
+ var map = Map.create();
+
+ this.eachAttribute(function (key, meta) {
+ if (meta.type) {
+ map.set(key, meta.type);
+ }
+ });
+
+ return map;
+ }).readOnly(),
+
+ /**
+ Iterates through the attributes of the model, calling the passed function on each
+ attribute.
+ The callback method you provide should have the following signature (all
+ parameters are optional):
+ ```javascript
+ function(name, meta);
+ ```
+ - `name` the name of the current property in the iteration
+ - `meta` the meta object for the attribute property in the iteration
+ Note that in addition to a callback, you can also pass an optional target
+ object that will be set as `this` on the context.
+ Example
+ ```javascript
+ import DS from 'ember-data';
+ let Person = DS.Model.extend({
+ firstName: attr('string'),
+ lastName: attr('string'),
+ birthday: attr('date')
+ });
+ Person.eachAttribute(function(name, meta) {
+ console.log(name, meta);
+ });
+ // prints:
+ // firstName {type: "string", isAttribute: true, options: Object, parentType: function, name: "firstName"}
+ // lastName {type: "string", isAttribute: true, options: Object, parentType: function, name: "lastName"}
+ // birthday {type: "date", isAttribute: true, options: Object, parentType: function, name: "birthday"}
+ ```
+ @method eachAttribute
+ @param {Function} callback The callback to execute
+ @param {Object} [binding] the value to which the callback's `this` should be bound
+ @static
+ */
+ eachAttribute: function (callback, binding) {
+ get(this, 'attributes').forEach(function (meta, name) {
+ callback.call(binding, name, meta);
+ });
+ },
+
+ /**
+ Iterates through the transformedAttributes of the model, calling
+ the passed function on each attribute. Note the callback will not be
+ called for any attributes that do not have an transformation type.
+ The callback method you provide should have the following signature (all
+ parameters are optional):
+ ```javascript
+ function(name, type);
+ ```
+ - `name` the name of the current property in the iteration
+ - `type` a string containing the name of the type of transformed
+ applied to the attribute
+ Note that in addition to a callback, you can also pass an optional target
+ object that will be set as `this` on the context.
+ Example
+ ```javascript
+ import DS from 'ember-data';
+ let Person = DS.Model.extend({
+ firstName: attr(),
+ lastName: attr('string'),
+ birthday: attr('date')
+ });
+ Person.eachTransformedAttribute(function(name, type) {
+ console.log(name, type);
+ });
+ // prints:
+ // lastName string
+ // birthday date
+ ```
+ @method eachTransformedAttribute
+ @param {Function} callback The callback to execute
+ @param {Object} [binding] the value to which the callback's `this` should be bound
+ @static
+ */
+ eachTransformedAttribute: function (callback, binding) {
+ get(this, 'transformedAttributes').forEach(function (type, name) {
+ callback.call(binding, name, type);
+ });
+ }
});
// if `Ember.setOwner` is defined, accessing `this.container` is
// deprecated (but functional). In "standard" Ember usage, this
// deprecation is actually created via an `.extend` of the factory
@@ -4189,33 +4742,30 @@
}
if (false) {
Model.reopen({
/**
- Discards any unsaved changes to the given attribute.
+ Discards any unsaved changes to the given attribute. This feature is not enabled by default. You must enable `ds-rollback-attribute` and be running a canary build.
Example
```javascript
record.get('name'); // 'Untitled Document'
record.set('name', 'Doc 1');
record.get('name'); // 'Doc 1'
- record.resetAttribute('name');
+ record.rollbackAttribute('name');
record.get('name'); // 'Untitled Document'
```
- @method resetAttribute
+ @method rollbackAttribute
*/
- resetAttribute: function (attributeName) {
+ rollbackAttribute: function (attributeName) {
if (attributeName in this._internalModel._attributes) {
this.set(attributeName, this._internalModel.lastAcknowledgedValue(attributeName));
}
}
});
}
- Model.reopenClass(_emberDataPrivateSystemRelationshipsExt.RelationshipsClassMethodsMixin);
- Model.reopenClass(_emberDataPrivateSystemModelAttr.AttrClassMethodsMixin);
-
- exports.default = Model.extend(_emberDataPrivateSystemDebugDebugInfo.default, _emberDataPrivateSystemRelationshipsBelongsTo.BelongsToMixin, _emberDataPrivateSystemRelationshipsExt.DidDefinePropertyMixin, _emberDataPrivateSystemRelationshipsExt.RelationshipsInstanceMethodsMixin, _emberDataPrivateSystemRelationshipsHasMany.HasManyMixin, _emberDataPrivateSystemModelAttr.AttrInstanceMethodsMixin);
+ exports.default = Model;
});
define('ember-data/-private/system/model/states', ['exports', 'ember-data/-private/debug'], function (exports, _emberDataPrivateDebug) {
/*
This file encapsulates the various states that a record can transition
@@ -4474,11 +5024,11 @@
willCommit: function (internalModel) {
internalModel.transitionTo('inFlight');
},
reloadRecord: function (internalModel, resolve) {
- resolve(internalModel.store.reloadRecord(internalModel));
+ resolve(internalModel.store._reloadRecord(internalModel));
},
rolledBack: function (internalModel) {
internalModel.transitionTo('loaded.saved');
},
@@ -4775,11 +5325,11 @@
willCommit: function (internalModel) {
internalModel.transitionTo('updated.inFlight');
},
reloadRecord: function (internalModel, resolve) {
- resolve(internalModel.store.reloadRecord(internalModel));
+ resolve(internalModel.store._reloadRecord(internalModel));
},
deleteRecord: function (internalModel) {
internalModel.transitionTo('deleted.uncommitted');
},
@@ -5196,11 +5746,11 @@
return PromiseManyArray.create({
promise: Promise.resolve(promise, label)
});
}
});
-define("ember-data/-private/system/record-array-manager", ["exports", "ember", "ember-data/-private/system/record-arrays", "ember-data/-private/system/ordered-set"], function (exports, _ember, _emberDataPrivateSystemRecordArrays, _emberDataPrivateSystemOrderedSet) {
+define("ember-data/-private/system/record-array-manager", ["exports", "ember", "ember-data/-private/system/record-arrays", "ember-data/-private/system/ordered-set", "ember-data/-private/debug"], function (exports, _ember, _emberDataPrivateSystemRecordArrays, _emberDataPrivateSystemOrderedSet, _emberDataPrivateDebug) {
var get = _ember.default.get;
var MapWithDefault = _ember.default.MapWithDefault;
var emberRun = _ember.default.run;
/**
@@ -5218,12 +5768,12 @@
return [];
}
});
this.liveRecordArrays = MapWithDefault.create({
- defaultValue: function (modelClass) {
- return _this.createRecordArray(modelClass);
+ defaultValue: function (modelName) {
+ return _this.createRecordArray(modelName);
}
});
this.changedRecords = [];
this._adapterPopulatedRecordArrays = [];
@@ -5235,13 +5785,13 @@
}
emberRun.schedule('actions', this, this.updateRecordArrays);
},
- recordArraysForRecord: function (record) {
- record._recordArrays = record._recordArrays || _emberDataPrivateSystemOrderedSet.default.create();
- return record._recordArrays;
+ recordArraysForRecord: function (internalModel) {
+ internalModel._recordArrays = internalModel._recordArrays || _emberDataPrivateSystemOrderedSet.default.create();
+ return internalModel._recordArrays;
},
/**
This method is invoked whenever data is loaded into the store by the
adapter or updated by the adapter, or when a record has changed.
@@ -5262,64 +5812,64 @@
});
this.changedRecords.length = 0;
},
- _recordWasDeleted: function (record) {
- var recordArrays = record._recordArrays;
+ _recordWasDeleted: function (internalModel) {
+ var recordArrays = internalModel._recordArrays;
if (!recordArrays) {
return;
}
recordArrays.forEach(function (array) {
- return array._removeInternalModels([record]);
+ return array._removeInternalModels([internalModel]);
});
- record._recordArrays = null;
+ internalModel._recordArrays = null;
},
- _recordWasChanged: function (record) {
+ _recordWasChanged: function (internalModel) {
var _this3 = this;
- var typeClass = record.type;
- var recordArrays = this.filteredRecordArrays.get(typeClass);
+ var modelName = internalModel.modelName;
+ var recordArrays = this.filteredRecordArrays.get(modelName);
var filter = undefined;
recordArrays.forEach(function (array) {
filter = get(array, 'filterFunction');
- _this3.updateFilterRecordArray(array, filter, typeClass, record);
+ _this3.updateFilterRecordArray(array, filter, modelName, internalModel);
});
},
//Need to update live arrays on loading
- recordWasLoaded: function (record) {
+ recordWasLoaded: function (internalModel) {
var _this4 = this;
- var typeClass = record.type;
- var recordArrays = this.filteredRecordArrays.get(typeClass);
+ var modelName = internalModel.modelName;
+ var recordArrays = this.filteredRecordArrays.get(modelName);
var filter = undefined;
recordArrays.forEach(function (array) {
filter = get(array, 'filterFunction');
- _this4.updateFilterRecordArray(array, filter, typeClass, record);
+ _this4.updateFilterRecordArray(array, filter, modelName, internalModel);
});
- if (this.liveRecordArrays.has(typeClass)) {
- var liveRecordArray = this.liveRecordArrays.get(typeClass);
- this._addInternalModelToRecordArray(liveRecordArray, record);
+ if (this.liveRecordArrays.has(modelName)) {
+ var liveRecordArray = this.liveRecordArrays.get(modelName);
+ this._addInternalModelToRecordArray(liveRecordArray, internalModel);
}
},
/**
Update an individual filter.
@method updateFilterRecordArray
@param {DS.FilteredRecordArray} array
@param {Function} filter
- @param {DS.Model} modelClass
+ @param {String} modelName
@param {InternalModel} internalModel
*/
- updateFilterRecordArray: function (array, filter, modelClass, internalModel) {
+ updateFilterRecordArray: function (array, filter, modelName, internalModel) {
var shouldBeInArray = filter(internalModel.getRecord());
var recordArrays = this.recordArraysForRecord(internalModel);
if (shouldBeInArray) {
this._addInternalModelToRecordArray(array, internalModel);
} else {
@@ -5334,14 +5884,14 @@
array._pushInternalModels([internalModel]);
recordArrays.add(array);
}
},
- syncLiveRecordArray: function (array, modelClass) {
+ syncLiveRecordArray: function (array, modelName) {
var hasNoPotentialDeletions = this.changedRecords.length === 0;
- var typeMap = this.store.typeMapFor(modelClass);
- var hasNoInsertionsOrRemovals = typeMap.records.length === array.length;
+ var recordMap = this.store._recordMapFor(modelName);
+ var hasNoInsertionsOrRemovals = recordMap.length === array.length;
/*
Ideally the recordArrayManager has knowledge of the changes to be applied to
liveRecordArrays, and is capable of strategically flushing those changes and applying
small diffs if desired. However, until we've refactored recordArrayManager, this dirty
@@ -5349,16 +5899,16 @@
*/
if (hasNoPotentialDeletions && hasNoInsertionsOrRemovals) {
return;
}
- this.populateLiveRecordArray(array, modelClass);
+ this.populateLiveRecordArray(array, modelName);
},
- populateLiveRecordArray: function (array, modelClass) {
- var typeMap = this.store.typeMapFor(modelClass);
- var records = typeMap.records;
+ populateLiveRecordArray: function (array, modelName) {
+ var recordMap = this.store._recordMapFor(modelName);
+ var records = recordMap.records;
var record = undefined;
for (var i = 0; i < records.length; i++) {
record = records[i];
@@ -5373,87 +5923,88 @@
changed on a `DS.FilteredRecordArray`.
It essentially re-runs the filter from scratch. This same
method is invoked when the filter is created in th first place.
@method updateFilter
@param {Array} array
- @param {Class} modelClass
+ @param {String} modelName
@param {Function} filter
*/
- updateFilter: function (array, modelClass, filter) {
- var typeMap = this.store.typeMapFor(modelClass);
- var records = typeMap.records;
+ updateFilter: function (array, modelName, filter) {
+ var recordMap = this.store._recordMapFor(modelName);
+ var records = recordMap.records;
var record = undefined;
for (var i = 0; i < records.length; i++) {
record = records[i];
if (!record.isDeleted() && !record.isEmpty()) {
- this.updateFilterRecordArray(array, filter, modelClass, record);
+ this.updateFilterRecordArray(array, filter, modelName, record);
}
}
},
/**
- Get the `DS.RecordArray` for a type, which contains all loaded records of
- given type.
+ Get the `DS.RecordArray` for a modelName, which contains all loaded records of
+ given modelName.
@method liveRecordArrayFor
- @param {Class} typeClass
+ @param {String} modelName
@return {DS.RecordArray}
*/
- liveRecordArrayFor: function (typeClass) {
- return this.liveRecordArrays.get(typeClass);
+ liveRecordArrayFor: function (modelName) {
+ return this.liveRecordArrays.get(modelName);
},
/**
- Create a `DS.RecordArray` for a type.
+ Create a `DS.RecordArray` for a modelName.
@method createRecordArray
- @param {Class} modelClass
+ @param {String} modelName
@return {DS.RecordArray}
*/
- createRecordArray: function (modelClass) {
+ createRecordArray: function (modelName) {
return _emberDataPrivateSystemRecordArrays.RecordArray.create({
- type: modelClass,
+ modelName: modelName,
content: _ember.default.A(),
store: this.store,
isLoaded: true,
manager: this
});
},
/**
- Create a `DS.FilteredRecordArray` for a type and register it for updates.
+ Create a `DS.FilteredRecordArray` for a modelName and register it for updates.
@method createFilteredRecordArray
- @param {DS.Model} typeClass
+ @param {String} modelName
@param {Function} filter
@param {Object} query (optional
@return {DS.FilteredRecordArray}
*/
- createFilteredRecordArray: function (typeClass, filter, query) {
+ createFilteredRecordArray: function (modelName, filter, query) {
var array = _emberDataPrivateSystemRecordArrays.FilteredRecordArray.create({
query: query,
- type: typeClass,
+ modelName: modelName,
content: _ember.default.A(),
store: this.store,
manager: this,
filterFunction: filter
});
- this.registerFilteredRecordArray(array, typeClass, filter);
+ this.registerFilteredRecordArray(array, modelName, filter);
return array;
},
/**
- Create a `DS.AdapterPopulatedRecordArray` for a type with given query.
+ Create a `DS.AdapterPopulatedRecordArray` for a modelName with given query.
@method createAdapterPopulatedRecordArray
- @param {DS.Model} typeClass
+ @param {String} modelName
@param {Object} query
@return {DS.AdapterPopulatedRecordArray}
*/
- createAdapterPopulatedRecordArray: function (typeClass, query) {
+ createAdapterPopulatedRecordArray: function (modelName, query) {
+
var array = _emberDataPrivateSystemRecordArrays.AdapterPopulatedRecordArray.create({
- type: typeClass,
+ modelName: modelName,
query: query,
content: _ember.default.A(),
store: this.store,
manager: this
});
@@ -5462,50 +6013,51 @@
return array;
},
/**
- Register a RecordArray for a given type to be backed by
+ Register a RecordArray for a given modelName to be backed by
a filter function. This will cause the array to update
- automatically when records of that type change attribute
+ automatically when records of that modelName change attribute
values or states.
@method registerFilteredRecordArray
@param {DS.RecordArray} array
- @param {DS.Model} typeClass
+ @param {String} modelName
@param {Function} filter
*/
- registerFilteredRecordArray: function (array, typeClass, filter) {
- var recordArrays = this.filteredRecordArrays.get(typeClass);
+ registerFilteredRecordArray: function (array, modelName, filter) {
+
+ var recordArrays = this.filteredRecordArrays.get(modelName);
recordArrays.push(array);
- this.updateFilter(array, typeClass, filter);
+ this.updateFilter(array, modelName, filter);
},
/**
Unregister a RecordArray.
So manager will not update this array.
@method unregisterRecordArray
@param {DS.RecordArray} array
*/
unregisterRecordArray: function (array) {
- var typeClass = array.type;
+ var modelName = array.modelName;
// unregister filtered record array
- var recordArrays = this.filteredRecordArrays.get(typeClass);
+ var recordArrays = this.filteredRecordArrays.get(modelName);
var removedFromFiltered = remove(recordArrays, array);
// remove from adapter populated record array
var removedFromAdapterPopulated = remove(this._adapterPopulatedRecordArrays, array);
if (!removedFromFiltered && !removedFromAdapterPopulated) {
// unregister live record array
- if (this.liveRecordArrays.has(typeClass)) {
- var liveRecordArrayForType = this.liveRecordArrayFor(typeClass);
+ if (this.liveRecordArrays.has(modelName)) {
+ var liveRecordArrayForType = this.liveRecordArrayFor(modelName);
if (array === liveRecordArrayForType) {
- this.liveRecordArrays.delete(typeClass);
+ this.liveRecordArrays.delete(modelName);
}
}
}
},
@@ -5611,20 +6163,18 @@
this.query = this.query || null;
this.links = null;
},
replace: function () {
- var type = get(this, 'type').toString();
- throw new Error("The result of a server query (on " + type + ") is immutable.");
+ throw new Error("The result of a server query (on " + this.modelName + ") is immutable.");
},
_update: function () {
var store = get(this, 'store');
- var modelName = get(this, 'type.modelName');
var query = get(this, 'query');
- return store._query(modelName, query, this);
+ return store._query(this.modelName, query, this);
},
/**
@method _setInternalModels
@param {Array} internalModels
@@ -5644,12 +6194,12 @@
isUpdating: false,
meta: (0, _emberDataPrivateSystemCloneNull.default)(payload.meta),
links: (0, _emberDataPrivateSystemCloneNull.default)(payload.links)
});
- internalModels.forEach(function (record) {
- return _this.manager.recordArraysForRecord(record).add(_this);
+ internalModels.forEach(function (internalModel) {
+ return _this.manager.recordArraysForRecord(internalModel).add(_this);
});
// TODO: should triggering didLoad event be the last action of the runLoop?
_ember.default.run.once(this, 'trigger', 'didLoad');
}
@@ -5701,37 +6251,37 @@
@param {DS.Model} record
@return {Boolean} `true` if the record should be in the array
*/
replace: function () {
- var type = get(this, 'type').toString();
- throw new Error('The result of a client-side filter (on ' + type + ') is immutable.');
+ throw new Error('The result of a client-side filter (on ' + this.modelName + ') is immutable.');
},
/**
@method updateFilter
@private
*/
_updateFilter: function () {
if (get(this, 'isDestroying') || get(this, 'isDestroyed')) {
return;
}
- get(this, 'manager').updateFilter(this, get(this, 'type'), get(this, 'filterFunction'));
+ get(this, 'manager').updateFilter(this, this.modelName, get(this, 'filterFunction'));
},
updateFilter: _ember.default.observer('filterFunction', function () {
_ember.default.run.once(this, this._updateFilter);
})
});
});
define("ember-data/-private/system/record-arrays/record-array", ["exports", "ember", "ember-data/-private/system/promise-proxies", "ember-data/-private/system/snapshot-record-array"], function (exports, _ember, _emberDataPrivateSystemPromiseProxies, _emberDataPrivateSystemSnapshotRecordArray) {
+ var computed = _ember.default.computed;
var get = _ember.default.get;
var set = _ember.default.set;
var Promise = _ember.default.RSVP.Promise;
/**
- A record array is an array that contains records of a certain type. The record
+ A record array is an array that contains records of a certain modelName. The record
array materializes records as needed when they are retrieved for the first
time. You should not create record arrays yourself. Instead, an instance of
`DS.RecordArray` or its subclasses will be returned by your application's store
in response to queries.
@@ -5744,17 +6294,10 @@
exports.default = _ember.default.ArrayProxy.extend(_ember.default.Evented, {
init: function () {
this._super.apply(this, arguments);
/**
- The model type contained by this record array.
- @property type
- @type DS.Model
- */
- this.type = this.type || null;
-
- /**
The array of client ids backing the record array. When a
record is requested from the record array, the record
for the client id at the same index is materialized, if
necessary, by the store.
@property content
@@ -5797,15 +6340,26 @@
this.store = this.store || null;
this._updatingPromise = null;
},
replace: function () {
- var type = get(this, 'type').toString();
- throw new Error("The result of a server query (for all " + type + " types) is immutable. To modify contents, use toArray()");
+ throw new Error("The result of a server query (for all " + this.modelName + " types) is immutable. To modify contents, use toArray()");
},
/**
+ The modelClass represented by this record array.
+ @property type
+ @type DS.Model
+ */
+ type: computed('modelName', function () {
+ if (!this.modelName) {
+ return null;
+ }
+ return this.store._modelFor(this.modelName);
+ }).readOnly(),
+
+ /**
Retrieves an object from the content by index.
@method objectAtContent
@private
@param {Number} index
@return {DS.Model} record
@@ -5854,14 +6408,11 @@
/*
Update this RecordArray and return a promise which resolves once the update
is finished.
*/
_update: function () {
- var store = get(this, 'store');
- var modelName = get(this, 'type.modelName');
-
- return store.findAll(modelName, { reload: true });
+ return this.store.findAll(this.modelName, { reload: true });
},
/**
Adds an internal model to the `RecordArray` without duplicates
@method addInternalModel
@@ -5899,11 +6450,11 @@
@return {DS.PromiseArray} promise
*/
save: function () {
var _this2 = this;
- var promiseLabel = 'DS: RecordArray#save ' + get(this, 'type');
+ var promiseLabel = "DS: RecordArray#save " + this.modelName;
var promise = Promise.all(this.invoke('save'), promiseLabel).then(function () {
return _this2;
}, null, 'DS: RecordArray#save return RecordArray');
return _emberDataPrivateSystemPromiseProxies.PromiseArray.create({ promise: promise });
@@ -5965,10 +6516,162 @@
});
});
/**
@module ember-data
*/
+define('ember-data/-private/system/record-map', ['exports', 'ember-data/-private/debug', 'ember-data/-private/system/model/internal-model'], function (exports, _emberDataPrivateDebug, _emberDataPrivateSystemModelInternalModel) {
+ var _createClass = (function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ('value' in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })();
+
+ function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }
+
+ /**
+ `RecordMap` is a custom storage map for records of a given modelName
+ used by `IdentityMap`.
+
+ It was extracted from an implicit pojo based "record map" and preserves
+ that interface while we work towards a more official API.
+
+ @class RecordMap
+ @private
+ */
+
+ var RecordMap = (function () {
+ function RecordMap(modelName) {
+ this.modelName = modelName;
+ this._idToRecord = Object.create(null);
+ this._records = [];
+ this._metadata = null;
+ }
+
+ /**
+ A "map" of records based on their ID for this modelName
+ */
+
+ _createClass(RecordMap, [{
+ key: 'get',
+
+ /**
+ *
+ * @param id
+ * @returns {InternalModel}
+ */
+ value: function get(id) {
+ var r = this._idToRecord[id];
+ return r;
+ }
+ }, {
+ key: 'has',
+ value: function has(id) {
+ return !!this._idToRecord[id];
+ }
+ }, {
+ key: 'set',
+ value: function set(id, internalModel) {
+
+ this._idToRecord[id] = internalModel;
+ }
+ }, {
+ key: 'add',
+ value: function add(internalModel, id) {
+
+ if (id) {
+ this._idToRecord[id] = internalModel;
+ }
+
+ this._records.push(internalModel);
+ }
+ }, {
+ key: 'remove',
+ value: function remove(internalModel, id) {
+ if (id) {
+ delete this._idToRecord[id];
+ }
+
+ var loc = this._records.indexOf(internalModel);
+
+ if (loc !== -1) {
+ this._records.splice(loc, 1);
+ }
+ }
+ }, {
+ key: 'contains',
+ value: function contains(internalModel) {
+ return this._records.indexOf(internalModel) !== -1;
+ }
+
+ /**
+ An array of all records of this modelName
+ */
+ }, {
+ key: 'clear',
+
+ /**
+ Destroy all records in the recordMap and wipe metadata.
+ @method clear
+ */
+ value: function clear() {
+ if (this._records) {
+ var records = this._records;
+ this._records = [];
+ var record = undefined;
+
+ for (var i = 0; i < records.length; i++) {
+ record = records[i];
+ record.unloadRecord();
+ record.destroy(); // maybe within unloadRecord
+ }
+ }
+
+ this._metadata = null;
+ }
+ }, {
+ key: 'destroy',
+ value: function destroy() {
+ this._store = null;
+ this._modelClass = null;
+ }
+ }, {
+ key: 'idToRecord',
+ get: function () {
+ return this._idToRecord;
+ }
+ }, {
+ key: 'length',
+ get: function () {
+ return this._records.length;
+ }
+ }, {
+ key: 'records',
+ get: function () {
+ return this._records;
+ }
+
+ /**
+ * meta information about records
+ */
+ }, {
+ key: 'metadata',
+ get: function () {
+ return this._metadata || (this._metadata = Object.create(null));
+ }
+
+ /**
+ deprecated (and unsupported) way of accessing modelClass
+ @deprecated
+ */
+ }, {
+ key: 'type',
+ get: function () {
+ throw new Error('RecordMap.type is no longer available');
+ }
+ }]);
+
+ return RecordMap;
+ })();
+
+ exports.default = RecordMap;
+});
define('ember-data/-private/system/references', ['exports', 'ember-data/-private/system/references/record', 'ember-data/-private/system/references/belongs-to', 'ember-data/-private/system/references/has-many'], function (exports, _emberDataPrivateSystemReferencesRecord, _emberDataPrivateSystemReferencesBelongsTo, _emberDataPrivateSystemReferencesHasMany) {
exports.RecordReference = _emberDataPrivateSystemReferencesRecord.default;
exports.BelongsToReference = _emberDataPrivateSystemReferencesBelongsTo.default;
exports.HasManyReference = _emberDataPrivateSystemReferencesHasMany.default;
});
@@ -6379,10 +7082,17 @@
});
define('ember-data/-private/system/references/has-many', ['exports', 'ember', 'ember-data/-private/system/references/reference', 'ember-data/-private/debug', 'ember-data/-private/features'], function (exports, _ember, _emberDataPrivateSystemReferencesReference, _emberDataPrivateDebug, _emberDataPrivateFeatures) {
var resolve = _ember.default.RSVP.resolve;
var get = _ember.default.get;
+ /**
+ A HasManyReference is a low level API that allows users and addon
+ author to perform meta-operations on a has-many relationship.
+
+ @class HasManyReference
+ @namespace DS
+ */
var HasManyReference = function (store, parentInternalModel, hasManyRelationship) {
this._super$constructor(store, parentInternalModel);
this.hasManyRelationship = hasManyRelationship;
this.type = hasManyRelationship.relationshipMeta.type;
this.parent = parentInternalModel.recordReference;
@@ -6392,34 +7102,222 @@
HasManyReference.prototype = Object.create(_emberDataPrivateSystemReferencesReference.default.prototype);
HasManyReference.prototype.constructor = HasManyReference;
HasManyReference.prototype._super$constructor = _emberDataPrivateSystemReferencesReference.default;
+ /**
+ This returns a string that represents how the reference will be
+ looked up when it is loaded. If the relationship has a link it will
+ use the "link" otherwise it defaults to "id".
+
+ Example
+
+ ```app/models/post.js
+ export default DS.Model.extend({
+ comments: DS.hasMany({ async: true })
+ });
+ ```
+
+ ```javascript
+ var post = store.push({
+ data: {
+ type: 'post',
+ id: 1,
+ relationships: {
+ comments: {
+ data: [{ type: 'comment', id: 1 }]
+ }
+ }
+ }
+ });
+
+ var commentsRef = post.hasMany('comments');
+
+ // get the identifier of the reference
+ if (commentsRef.remoteType() === "ids") {
+ var ids = commentsRef.ids();
+ } else if (commentsRef.remoteType() === "link") {
+ var link = commentsRef.link();
+ }
+ ```
+
+ @method remoteType
+ @return {String} The name of the remote type. This should either be "link" or "ids"
+ */
HasManyReference.prototype.remoteType = function () {
if (this.hasManyRelationship.link) {
return "link";
}
return "ids";
};
+ /**
+ The link Ember Data will use to fetch or reload this has-many
+ relationship.
+
+ Example
+
+ ```app/models/post.js
+ export default DS.Model.extend({
+ comments: DS.hasMany({ async: true })
+ });
+ ```
+
+ ```javascript
+ var post = store.push({
+ data: {
+ type: 'post',
+ id: 1,
+ relationships: {
+ comments: {
+ links: {
+ related: '/posts/1/comments'
+ }
+ }
+ }
+ }
+ });
+
+ var commentsRef = post.hasMany('comments');
+
+ commentsRef.link(); // '/posts/1/comments'
+ ```
+
+ @method link
+ @return {String} The link Ember Data will use to fetch or reload this has-many relationship.
+ */
HasManyReference.prototype.link = function () {
return this.hasManyRelationship.link;
};
+ /**
+ `ids()` returns an array of the record ids in this relationship.
+
+ Example
+
+ ```app/models/post.js
+ export default DS.Model.extend({
+ comments: DS.hasMany({ async: true })
+ });
+ ```
+
+ ```javascript
+ var post = store.push({
+ data: {
+ type: 'post',
+ id: 1,
+ relationships: {
+ comments: {
+ data: [{ type: 'comment', id: 1 }]
+ }
+ }
+ }
+ });
+
+ var commentsRef = post.hasMany('comments');
+
+ commentsRef.ids(); // ['1']
+ ```
+
+ @method remoteType
+ @return {Array} The ids in this has-many relationship
+ */
HasManyReference.prototype.ids = function () {
var members = this.hasManyRelationship.members.toArray();
return members.map(function (internalModel) {
return internalModel.id;
});
};
+ /**
+ The link Ember Data will use to fetch or reload this has-many
+ relationship.
+
+ Example
+
+ ```app/models/post.js
+ export default DS.Model.extend({
+ comments: DS.hasMany({ async: true })
+ });
+ ```
+
+ ```javascript
+ var post = store.push({
+ data: {
+ type: 'post',
+ id: 1,
+ relationships: {
+ comments: {
+ links: {
+ related: {
+ href: '/posts/1/comments',
+ meta: {
+ count: 10
+ }
+ }
+ }
+ }
+ }
+ }
+ });
+
+ var commentsRef = post.hasMany('comments');
+
+ commentsRef.meta(); // { count: 10 }
+ ```
+
+ @method meta
+ @return {Object} The meta information for the has-many relationship.
+ */
HasManyReference.prototype.meta = function () {
return this.hasManyRelationship.meta;
};
+ /**
+ `push` can be used to update the data in the relationship and Ember
+ Data will treat the new data as the canonical value of this
+ relationship on the backend.
+
+ Example
+
+ ```app/models/post.js
+ export default DS.Model.extend({
+ comments: DS.hasMany({ async: true })
+ });
+ ```
+
+ ```
+ var post = store.push({
+ data: {
+ type: 'post',
+ id: 1,
+ relationships: {
+ comments: {
+ data: [{ type: 'comment', id: 1 }]
+ }
+ }
+ }
+ });
+
+ var commentsRef = post.hasMany('comments');
+
+ commentsRef.ids(); // ['1']
+
+ commentsRef.push([
+ [{ type: 'comment', id: 2 }],
+ [{ type: 'comment', id: 3 }],
+ ])
+
+ commentsRef.ids(); // ['2', '3']
+ ```
+
+ @method push
+ @param {Array|Promise} objectOrPromise a promise that resolves to a JSONAPI document object describing the new value of this relationship.
+ @return {DS.ManyArray}
+ */
HasManyReference.prototype.push = function (objectOrPromise) {
var _this = this;
return resolve(objectOrPromise).then(function (payload) {
var array = payload;
@@ -6467,26 +7365,135 @@
return members.every(function (internalModel) {
return internalModel.isLoaded() === true;
});
};
+ /**
+ `value()` sycronously returns the current value of the has-many
+ relationship. Unlike `record.get('relationshipName')`, calling
+ `value()` on a reference does not trigger a fetch if the async
+ relationship is not yet loaded. If the relationship is not loaded
+ it will always return `null`.
+
+ Example
+
+ ```app/models/post.js
+ export default DS.Model.extend({
+ comments: DS.hasMany({ async: true })
+ });
+ ```
+
+ ```javascript
+ var post = store.push({
+ data: {
+ type: 'post',
+ id: 1,
+ relationships: {
+ comments: {
+ data: [{ type: 'comment', id: 1 }]
+ }
+ }
+ }
+ });
+
+ var commentsRef = post.hasMany('comments');
+
+ post.get('comments').then(function(comments) {
+ commentsRef.value() === comments
+ })
+ ```
+
+ @method value
+ @return {DS.ManyArray}
+ */
HasManyReference.prototype.value = function () {
if (this._isLoaded()) {
return this.hasManyRelationship.getManyArray();
}
return null;
};
+ /**
+ Loads the relationship if it is not already loaded. If the
+ relationship is already loaded this method does not trigger a new
+ load.
+
+ Example
+
+ ```app/models/post.js
+ export default DS.Model.extend({
+ comments: DS.hasMany({ async: true })
+ });
+ ```
+
+ ```javascript
+ var post = store.push({
+ data: {
+ type: 'post',
+ id: 1,
+ relationships: {
+ comments: {
+ data: [{ type: 'comment', id: 1 }]
+ }
+ }
+ }
+ });
+
+ var commentsRef = post.hasMany('comments');
+
+ commentsRef.load().then(function(comments) {
+ //...
+ });
+ ```
+
+ @method load
+ @return {Promise} a promise that resolves with the ManyArray in
+ this has-many relationship.
+ */
HasManyReference.prototype.load = function () {
if (!this._isLoaded()) {
return this.hasManyRelationship.getRecords();
}
return resolve(this.hasManyRelationship.getManyArray());
};
+ /**
+ Reloads this has-many relationship.
+
+ Example
+
+ ```app/models/post.js
+ export default DS.Model.extend({
+ comments: DS.hasMany({ async: true })
+ });
+ ```
+
+ ```javascript
+ var post = store.push({
+ data: {
+ type: 'post',
+ id: 1,
+ relationships: {
+ comments: {
+ data: [{ type: 'comment', id: 1 }]
+ }
+ }
+ }
+ });
+
+ var commentsRef = post.hasMany('comments');
+
+ commentsRef.reload().then(function(comments) {
+ //...
+ });
+ ```
+
+ @method reload
+ @return {Promise} a promise that resolves with the ManyArray in this has-many relationship.
+ */
HasManyReference.prototype.reload = function () {
return this.hasManyRelationship.reload();
};
exports.default = HasManyReference;
@@ -6817,25 +7824,13 @@
return this._internalModel._relationships.get(key).getRecord();
}
}).meta(meta);
}
-
- /*
- These observers observe all `belongsTo` relationships on the record. See
- `relationships/ext` to see how these observers get their dependencies.
- */
- var BelongsToMixin = _ember.default.Mixin.create({
- notifyBelongsToChanged: function (key) {
- this.notifyPropertyChange(key);
- }
- });
- exports.BelongsToMixin = BelongsToMixin;
});
-define("ember-data/-private/system/relationships/ext", ["exports", "ember", "ember-data/-private/debug", "ember-data/-private/system/relationship-meta", "ember-data/-private/system/empty-object"], function (exports, _ember, _emberDataPrivateDebug, _emberDataPrivateSystemRelationshipMeta, _emberDataPrivateSystemEmptyObject) {
+define("ember-data/-private/system/relationships/ext", ["exports", "ember", "ember-data/-private/debug", "ember-data/-private/system/relationship-meta"], function (exports, _ember, _emberDataPrivateDebug, _emberDataPrivateSystemRelationshipMeta) {
- var get = _ember.default.get;
var Map = _ember.default.Map;
var MapWithDefault = _ember.default.MapWithDefault;
var relationshipsDescriptor = _ember.default.computed(function () {
if (_ember.default.testing === true && relationshipsDescriptor._cacheable === true) {
@@ -6864,10 +7859,11 @@
});
return map;
}).readOnly();
+ exports.relationshipsDescriptor = relationshipsDescriptor;
var relatedTypesDescriptor = _ember.default.computed(function () {
if (_ember.default.testing === true && relatedTypesDescriptor._cacheable === true) {
relatedTypesDescriptor._cacheable = false;
}
@@ -6889,10 +7885,11 @@
});
return types;
}).readOnly();
+ exports.relatedTypesDescriptor = relatedTypesDescriptor;
var relationshipsByNameDescriptor = _ember.default.computed(function () {
if (_ember.default.testing === true && relationshipsByNameDescriptor._cacheable === true) {
relationshipsByNameDescriptor._cacheable = false;
}
@@ -6907,518 +7904,11 @@
}
});
return map;
}).readOnly();
-
- /**
- @module ember-data
- */
-
- /*
- This file defines several extensions to the base `DS.Model` class that
- add support for one-to-many relationships.
- */
-
- /**
- @class Model
- @namespace DS
- */
- var DidDefinePropertyMixin = _ember.default.Mixin.create({
-
- /**
- This Ember.js hook allows an object to be notified when a property
- is defined.
- In this case, we use it to be notified when an Ember Data user defines a
- belongs-to relationship. In that case, we need to set up observers for
- each one, allowing us to track relationship changes and automatically
- reflect changes in the inverse has-many array.
- This hook passes the class being set up, as well as the key and value
- being defined. So, for example, when the user does this:
- ```javascript
- DS.Model.extend({
- parent: DS.belongsTo('user')
- });
- ```
- This hook would be called with "parent" as the key and the computed
- property returned by `DS.belongsTo` as the value.
- @method didDefineProperty
- @param {Object} proto
- @param {String} key
- @param {Ember.ComputedProperty} value
- */
- didDefineProperty: function (proto, key, value) {
- // Check if the value being set is a computed property.
- if (value instanceof _ember.default.ComputedProperty) {
-
- // If it is, get the metadata for the relationship. This is
- // populated by the `DS.belongsTo` helper when it is creating
- // the computed property.
- var meta = value.meta();
-
- meta.parentType = proto.constructor;
- }
- }
- });
-
- exports.DidDefinePropertyMixin = DidDefinePropertyMixin;
- /*
- These DS.Model extensions add class methods that provide relationship
- introspection abilities about relationships.
-
- A note about the computed properties contained here:
-
- **These properties are effectively sealed once called for the first time.**
- To avoid repeatedly doing expensive iteration over a model's fields, these
- values are computed once and then cached for the remainder of the runtime of
- your application.
-
- If your application needs to modify a class after its initial definition
- (for example, using `reopen()` to add additional attributes), make sure you
- do it before using your model with the store, which uses these properties
- extensively.
- */
-
- var RelationshipsClassMethodsMixin = _ember.default.Mixin.create({
-
- /**
- For a given relationship name, returns the model type of the relationship.
- For example, if you define a model like this:
- ```app/models/post.js
- import DS from 'ember-data';
- export default DS.Model.extend({
- comments: DS.hasMany('comment')
- });
- ```
- Calling `store.modelFor('post').typeForRelationship('comments', store)` will return `Comment`.
- @method typeForRelationship
- @static
- @param {String} name the name of the relationship
- @param {store} store an instance of DS.Store
- @return {DS.Model} the type of the relationship, or undefined
- */
- typeForRelationship: function (name, store) {
- var relationship = get(this, 'relationshipsByName').get(name);
- return relationship && store.modelFor(relationship.type);
- },
-
- inverseMap: _ember.default.computed(function () {
- return new _emberDataPrivateSystemEmptyObject.default();
- }),
-
- /**
- Find the relationship which is the inverse of the one asked for.
- For example, if you define models like this:
- ```app/models/post.js
- import DS from 'ember-data';
- export default DS.Model.extend({
- comments: DS.hasMany('message')
- });
- ```
- ```app/models/message.js
- import DS from 'ember-data';
- export default DS.Model.extend({
- owner: DS.belongsTo('post')
- });
- ```
- store.modelFor('post').inverseFor('comments', store) -> { type: App.Message, name: 'owner', kind: 'belongsTo' }
- store.modelFor('message').inverseFor('owner', store) -> { type: App.Post, name: 'comments', kind: 'hasMany' }
- @method inverseFor
- @static
- @param {String} name the name of the relationship
- @param {DS.Store} store
- @return {Object} the inverse relationship, or null
- */
- inverseFor: function (name, store) {
- var inverseMap = get(this, 'inverseMap');
- if (inverseMap[name]) {
- return inverseMap[name];
- } else {
- var inverse = this._findInverseFor(name, store);
- inverseMap[name] = inverse;
- return inverse;
- }
- },
-
- //Calculate the inverse, ignoring the cache
- _findInverseFor: function (name, store) {
-
- var inverseType = this.typeForRelationship(name, store);
- if (!inverseType) {
- return null;
- }
-
- var propertyMeta = this.metaForProperty(name);
- //If inverse is manually specified to be null, like `comments: DS.hasMany('message', { inverse: null })`
- var options = propertyMeta.options;
- if (options.inverse === null) {
- return null;
- }
-
- var inverseName, inverseKind, inverse;
-
- //If inverse is specified manually, return the inverse
- if (options.inverse) {
- inverseName = options.inverse;
- inverse = _ember.default.get(inverseType, 'relationshipsByName').get(inverseName);
-
- inverseKind = inverse.kind;
- } else {
- //No inverse was specified manually, we need to use a heuristic to guess one
- if (propertyMeta.type === propertyMeta.parentType.modelName) {}
-
- var possibleRelationships = findPossibleInverses(this, inverseType);
-
- if (possibleRelationships.length === 0) {
- return null;
- }
-
- var filteredRelationships = possibleRelationships.filter(function (possibleRelationship) {
- var optionsForRelationship = inverseType.metaForProperty(possibleRelationship.name).options;
- return name === optionsForRelationship.inverse;
- });
-
- if (filteredRelationships.length === 1) {
- possibleRelationships = filteredRelationships;
- }
-
- inverseName = possibleRelationships[0].name;
- inverseKind = possibleRelationships[0].kind;
- }
-
- function findPossibleInverses(type, inverseType, relationshipsSoFar) {
- var possibleRelationships = relationshipsSoFar || [];
-
- var relationshipMap = get(inverseType, 'relationships');
- if (!relationshipMap) {
- return possibleRelationships;
- }
-
- var relationships = relationshipMap.get(type.modelName);
-
- relationships = relationships.filter(function (relationship) {
- var optionsForRelationship = inverseType.metaForProperty(relationship.name).options;
-
- if (!optionsForRelationship.inverse) {
- return true;
- }
-
- return name === optionsForRelationship.inverse;
- });
-
- if (relationships) {
- possibleRelationships.push.apply(possibleRelationships, relationships);
- }
-
- //Recurse to support polymorphism
- if (type.superclass) {
- findPossibleInverses(type.superclass, inverseType, possibleRelationships);
- }
-
- return possibleRelationships;
- }
-
- return {
- type: inverseType,
- name: inverseName,
- kind: inverseKind
- };
- },
-
- /**
- The model's relationships as a map, keyed on the type of the
- relationship. The value of each entry is an array containing a descriptor
- for each relationship with that type, describing the name of the relationship
- as well as the type.
- For example, given the following model definition:
- ```app/models/blog.js
- import DS from 'ember-data';
- export default DS.Model.extend({
- users: DS.hasMany('user'),
- owner: DS.belongsTo('user'),
- posts: DS.hasMany('post')
- });
- ```
- This computed property would return a map describing these
- relationships, like this:
- ```javascript
- import Ember from 'ember';
- import Blog from 'app/models/blog';
- import User from 'app/models/user';
- import Post from 'app/models/post';
- var relationships = Ember.get(Blog, 'relationships');
- relationships.get(User);
- //=> [ { name: 'users', kind: 'hasMany' },
- // { name: 'owner', kind: 'belongsTo' } ]
- relationships.get(Post);
- //=> [ { name: 'posts', kind: 'hasMany' } ]
- ```
- @property relationships
- @static
- @type Ember.Map
- @readOnly
- */
-
- relationships: relationshipsDescriptor,
-
- /**
- A hash containing lists of the model's relationships, grouped
- by the relationship kind. For example, given a model with this
- definition:
- ```app/models/blog.js
- import DS from 'ember-data';
- export default DS.Model.extend({
- users: DS.hasMany('user'),
- owner: DS.belongsTo('user'),
- posts: DS.hasMany('post')
- });
- ```
- This property would contain the following:
- ```javascript
- import Ember from 'ember';
- import Blog from 'app/models/blog';
- var relationshipNames = Ember.get(Blog, 'relationshipNames');
- relationshipNames.hasMany;
- //=> ['users', 'posts']
- relationshipNames.belongsTo;
- //=> ['owner']
- ```
- @property relationshipNames
- @static
- @type Object
- @readOnly
- */
- relationshipNames: _ember.default.computed(function () {
- var names = {
- hasMany: [],
- belongsTo: []
- };
-
- this.eachComputedProperty(function (name, meta) {
- if (meta.isRelationship) {
- names[meta.kind].push(name);
- }
- });
-
- return names;
- }),
-
- /**
- An array of types directly related to a model. Each type will be
- included once, regardless of the number of relationships it has with
- the model.
- For example, given a model with this definition:
- ```app/models/blog.js
- import DS from 'ember-data';
- export default DS.Model.extend({
- users: DS.hasMany('user'),
- owner: DS.belongsTo('user'),
- posts: DS.hasMany('post')
- });
- ```
- This property would contain the following:
- ```javascript
- import Ember from 'ember';
- import Blog from 'app/models/blog';
- var relatedTypes = Ember.get(Blog, 'relatedTypes');
- //=> [ User, Post ]
- ```
- @property relatedTypes
- @static
- @type Ember.Array
- @readOnly
- */
- relatedTypes: relatedTypesDescriptor,
-
- /**
- A map whose keys are the relationships of a model and whose values are
- relationship descriptors.
- For example, given a model with this
- definition:
- ```app/models/blog.js
- import DS from 'ember-data';
- export default DS.Model.extend({
- users: DS.hasMany('user'),
- owner: DS.belongsTo('user'),
- posts: DS.hasMany('post')
- });
- ```
- This property would contain the following:
- ```javascript
- import Ember from 'ember';
- import Blog from 'app/models/blog';
- var relationshipsByName = Ember.get(Blog, 'relationshipsByName');
- relationshipsByName.get('users');
- //=> { key: 'users', kind: 'hasMany', type: 'user', options: Object, isRelationship: true }
- relationshipsByName.get('owner');
- //=> { key: 'owner', kind: 'belongsTo', type: 'user', options: Object, isRelationship: true }
- ```
- @property relationshipsByName
- @static
- @type Ember.Map
- @readOnly
- */
- relationshipsByName: relationshipsByNameDescriptor,
-
- /**
- A map whose keys are the fields of the model and whose values are strings
- describing the kind of the field. A model's fields are the union of all of its
- attributes and relationships.
- For example:
- ```app/models/blog.js
- import DS from 'ember-data';
- export default DS.Model.extend({
- users: DS.hasMany('user'),
- owner: DS.belongsTo('user'),
- posts: DS.hasMany('post'),
- title: DS.attr('string')
- });
- ```
- ```js
- import Ember from 'ember';
- import Blog from 'app/models/blog';
- var fields = Ember.get(Blog, 'fields');
- fields.forEach(function(kind, field) {
- console.log(field, kind);
- });
- // prints:
- // users, hasMany
- // owner, belongsTo
- // posts, hasMany
- // title, attribute
- ```
- @property fields
- @static
- @type Ember.Map
- @readOnly
- */
- fields: _ember.default.computed(function () {
- var map = Map.create();
-
- this.eachComputedProperty(function (name, meta) {
- if (meta.isRelationship) {
- map.set(name, meta.kind);
- } else if (meta.isAttribute) {
- map.set(name, 'attribute');
- }
- });
-
- return map;
- }).readOnly(),
-
- /**
- Given a callback, iterates over each of the relationships in the model,
- invoking the callback with the name of each relationship and its relationship
- descriptor.
- @method eachRelationship
- @static
- @param {Function} callback the callback to invoke
- @param {any} binding the value to which the callback's `this` should be bound
- */
- eachRelationship: function (callback, binding) {
- get(this, 'relationshipsByName').forEach(function (relationship, name) {
- callback.call(binding, name, relationship);
- });
- },
-
- /**
- Given a callback, iterates over each of the types related to a model,
- invoking the callback with the related type's class. Each type will be
- returned just once, regardless of how many different relationships it has
- with a model.
- @method eachRelatedType
- @static
- @param {Function} callback the callback to invoke
- @param {any} binding the value to which the callback's `this` should be bound
- */
- eachRelatedType: function (callback, binding) {
- var relationshipTypes = get(this, 'relatedTypes');
-
- for (var i = 0; i < relationshipTypes.length; i++) {
- var type = relationshipTypes[i];
- callback.call(binding, type);
- }
- },
-
- determineRelationshipType: function (knownSide, store) {
- var knownKey = knownSide.key;
- var knownKind = knownSide.kind;
- var inverse = this.inverseFor(knownKey, store);
- // let key;
- var otherKind = undefined;
-
- if (!inverse) {
- return knownKind === 'belongsTo' ? 'oneToNone' : 'manyToNone';
- }
-
- // key = inverse.name;
- otherKind = inverse.kind;
-
- if (otherKind === 'belongsTo') {
- return knownKind === 'belongsTo' ? 'oneToOne' : 'manyToOne';
- } else {
- return knownKind === 'belongsTo' ? 'oneToMany' : 'manyToMany';
- }
- }
-
- });
-
- exports.RelationshipsClassMethodsMixin = RelationshipsClassMethodsMixin;
- var RelationshipsInstanceMethodsMixin = _ember.default.Mixin.create({
- /**
- Given a callback, iterates over each of the relationships in the model,
- invoking the callback with the name of each relationship and its relationship
- descriptor.
- The callback method you provide should have the following signature (all
- parameters are optional):
- ```javascript
- function(name, descriptor);
- ```
- - `name` the name of the current property in the iteration
- - `descriptor` the meta object that describes this relationship
- The relationship descriptor argument is an object with the following properties.
- - **key** <span class="type">String</span> the name of this relationship on the Model
- - **kind** <span class="type">String</span> "hasMany" or "belongsTo"
- - **options** <span class="type">Object</span> the original options hash passed when the relationship was declared
- - **parentType** <span class="type">DS.Model</span> the type of the Model that owns this relationship
- - **type** <span class="type">String</span> the type name of the related Model
- Note that in addition to a callback, you can also pass an optional target
- object that will be set as `this` on the context.
- Example
- ```app/serializers/application.js
- import DS from 'ember-data';
- export default DS.JSONSerializer.extend({
- serialize: function(record, options) {
- var json = {};
- record.eachRelationship(function(name, descriptor) {
- if (descriptor.kind === 'hasMany') {
- var serializedHasManyName = name.toUpperCase() + '_IDS';
- json[serializedHasManyName] = record.get(name).mapBy('id');
- }
- });
- return json;
- }
- });
- ```
- @method eachRelationship
- @param {Function} callback the callback to invoke
- @param {any} binding the value to which the callback's `this` should be bound
- */
- eachRelationship: function (callback, binding) {
- this.constructor.eachRelationship(callback, binding);
- },
-
- relationshipFor: function (name) {
- return get(this.constructor, 'relationshipsByName').get(name);
- },
-
- inverseFor: function (key) {
- return this.constructor.inverseFor(key, this.store);
- }
-
- });
- exports.RelationshipsInstanceMethodsMixin = RelationshipsInstanceMethodsMixin;
+ exports.relationshipsByNameDescriptor = relationshipsByNameDescriptor;
});
define("ember-data/-private/system/relationships/has-many", ["exports", "ember", "ember-data/-private/debug", "ember-data/-private/system/normalize-model-name", "ember-data/-private/system/is-array-like"], function (exports, _ember, _emberDataPrivateDebug, _emberDataPrivateSystemNormalizeModelName, _emberDataPrivateSystemIsArrayLike) {
exports.default = hasMany;
/**
@@ -7565,485 +8055,541 @@
relationship.addRecords(_ember.default.A(records).mapBy('_internalModel'));
return relationship.getRecords();
}
}).meta(meta);
}
-
- var HasManyMixin = _ember.default.Mixin.create({
- notifyHasManyAdded: function (key) {
- //We need to notifyPropertyChange in the adding case because we need to make sure
- //we fetch the newly added record in case it is unloaded
- //TODO(Igor): Consider whether we could do this only if the record state is unloaded
-
- //Goes away once hasMany is double promisified
- this.notifyPropertyChange(key);
- }
- });
- exports.HasManyMixin = HasManyMixin;
});
/**
@module ember-data
*/
define("ember-data/-private/system/relationships/state/belongs-to", ["exports", "ember", "ember-data/-private/debug", "ember-data/-private/system/promise-proxies", "ember-data/-private/system/relationships/state/relationship"], function (exports, _ember, _emberDataPrivateDebug, _emberDataPrivateSystemPromiseProxies, _emberDataPrivateSystemRelationshipsStateRelationship) {
- exports.default = BelongsToRelationship;
+ var _createClass = (function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })();
- function BelongsToRelationship(store, record, inverseKey, relationshipMeta) {
- this._super$constructor(store, record, inverseKey, relationshipMeta);
- this.record = record;
- this.key = relationshipMeta.key;
- this.inverseRecord = null;
- this.canonicalState = null;
- }
+ var _get = function get(object, property, receiver) { if (object === null) object = Function.prototype; var desc = Object.getOwnPropertyDescriptor(object, property); if (desc === undefined) { var parent = Object.getPrototypeOf(object); if (parent === null) { return undefined; } else { return get(parent, property, receiver); } } else if ("value" in desc) { return desc.value; } else { var getter = desc.get; if (getter === undefined) { return undefined; } return getter.call(receiver); } };
- BelongsToRelationship.prototype = Object.create(_emberDataPrivateSystemRelationshipsStateRelationship.default.prototype);
- BelongsToRelationship.prototype.constructor = BelongsToRelationship;
- BelongsToRelationship.prototype._super$constructor = _emberDataPrivateSystemRelationshipsStateRelationship.default;
+ function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
- BelongsToRelationship.prototype.setRecord = function (newRecord) {
- if (newRecord) {
- this.addRecord(newRecord);
- } else if (this.inverseRecord) {
- this.removeRecord(this.inverseRecord);
- }
- this.setHasData(true);
- this.setHasLoaded(true);
- };
+ function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }
- BelongsToRelationship.prototype.setCanonicalRecord = function (newRecord) {
- if (newRecord) {
- this.addCanonicalRecord(newRecord);
- } else if (this.canonicalState) {
- this.removeCanonicalRecord(this.canonicalState);
- }
- this.flushCanonicalLater();
- };
+ var BelongsToRelationship = (function (_Relationship) {
+ _inherits(BelongsToRelationship, _Relationship);
- BelongsToRelationship.prototype._super$addCanonicalRecord = _emberDataPrivateSystemRelationshipsStateRelationship.default.prototype.addCanonicalRecord;
- BelongsToRelationship.prototype.addCanonicalRecord = function (newRecord) {
- if (this.canonicalMembers.has(newRecord)) {
- return;
+ function BelongsToRelationship(store, internalModel, inverseKey, relationshipMeta) {
+ _get(Object.getPrototypeOf(BelongsToRelationship.prototype), "constructor", this).call(this, store, internalModel, inverseKey, relationshipMeta);
+ this.internalModel = internalModel;
+ this.key = relationshipMeta.key;
+ this.inverseRecord = null;
+ this.canonicalState = null;
}
- if (this.canonicalState) {
- this.removeCanonicalRecord(this.canonicalState);
- }
+ _createClass(BelongsToRelationship, [{
+ key: "setRecord",
+ value: function setRecord(newRecord) {
+ if (newRecord) {
+ this.addRecord(newRecord);
+ } else if (this.inverseRecord) {
+ this.removeRecord(this.inverseRecord);
+ }
+ this.setHasData(true);
+ this.setHasLoaded(true);
+ }
+ }, {
+ key: "setCanonicalRecord",
+ value: function setCanonicalRecord(newRecord) {
+ if (newRecord) {
+ this.addCanonicalRecord(newRecord);
+ } else if (this.canonicalState) {
+ this.removeCanonicalRecord(this.canonicalState);
+ }
+ this.flushCanonicalLater();
+ }
+ }, {
+ key: "addCanonicalRecord",
+ value: function addCanonicalRecord(newRecord) {
+ if (this.canonicalMembers.has(newRecord)) {
+ return;
+ }
- this.canonicalState = newRecord;
- this._super$addCanonicalRecord(newRecord);
- };
+ if (this.canonicalState) {
+ this.removeCanonicalRecord(this.canonicalState);
+ }
- BelongsToRelationship.prototype._super$flushCanonical = _emberDataPrivateSystemRelationshipsStateRelationship.default.prototype.flushCanonical;
- BelongsToRelationship.prototype.flushCanonical = function () {
- //temporary fix to not remove newly created records if server returned null.
- //TODO remove once we have proper diffing
- if (this.inverseRecord && this.inverseRecord.isNew() && !this.canonicalState) {
- return;
- }
- if (this.inverseRecord !== this.canonicalState) {
- this.inverseRecord = this.canonicalState;
- this.record.notifyBelongsToChanged(this.key);
- }
- this._super$flushCanonical();
- };
+ this.canonicalState = newRecord;
+ _get(Object.getPrototypeOf(BelongsToRelationship.prototype), "addCanonicalRecord", this).call(this, newRecord);
+ }
+ }, {
+ key: "flushCanonical",
+ value: function flushCanonical() {
+ //temporary fix to not remove newly created records if server returned null.
+ //TODO remove once we have proper diffing
+ if (this.inverseRecord && this.inverseRecord.isNew() && !this.canonicalState) {
+ return;
+ }
+ if (this.inverseRecord !== this.canonicalState) {
+ this.inverseRecord = this.canonicalState;
+ this.internalModel.notifyBelongsToChanged(this.key);
+ }
- BelongsToRelationship.prototype._super$addRecord = _emberDataPrivateSystemRelationshipsStateRelationship.default.prototype.addRecord;
- BelongsToRelationship.prototype.addRecord = function (newRecord) {
- if (this.members.has(newRecord)) {
- return;
- }
+ _get(Object.getPrototypeOf(BelongsToRelationship.prototype), "flushCanonical", this).call(this);
+ }
+ }, {
+ key: "addRecord",
+ value: function addRecord(newRecord) {
+ if (this.members.has(newRecord)) {
+ return;
+ }
- if (this.inverseRecord) {
- this.removeRecord(this.inverseRecord);
- }
+ if (this.inverseRecord) {
+ this.removeRecord(this.inverseRecord);
+ }
- this.inverseRecord = newRecord;
- this._super$addRecord(newRecord);
- this.record.notifyBelongsToChanged(this.key);
- };
-
- BelongsToRelationship.prototype.setRecordPromise = function (newPromise) {
- var content = newPromise.get && newPromise.get('content');
-
- this.setRecord(content ? content._internalModel : content);
- };
-
- BelongsToRelationship.prototype._super$removeRecordFromOwn = _emberDataPrivateSystemRelationshipsStateRelationship.default.prototype.removeRecordFromOwn;
- BelongsToRelationship.prototype.removeRecordFromOwn = function (record) {
- if (!this.members.has(record)) {
- return;
- }
- this.inverseRecord = null;
- this._super$removeRecordFromOwn(record);
- this.record.notifyBelongsToChanged(this.key);
- };
-
- BelongsToRelationship.prototype._super$removeCanonicalRecordFromOwn = _emberDataPrivateSystemRelationshipsStateRelationship.default.prototype.removeCanonicalRecordFromOwn;
- BelongsToRelationship.prototype.removeCanonicalRecordFromOwn = function (record) {
- if (!this.canonicalMembers.has(record)) {
- return;
- }
- this.canonicalState = null;
- this._super$removeCanonicalRecordFromOwn(record);
- };
-
- BelongsToRelationship.prototype.findRecord = function () {
- if (this.inverseRecord) {
- return this.store._findByInternalModel(this.inverseRecord);
- } else {
- return _ember.default.RSVP.Promise.resolve(null);
- }
- };
-
- BelongsToRelationship.prototype.fetchLink = function () {
- var _this = this;
-
- return this.store.findBelongsTo(this.record, this.link, this.relationshipMeta).then(function (record) {
- if (record) {
- _this.addRecord(record);
+ this.inverseRecord = newRecord;
+ _get(Object.getPrototypeOf(BelongsToRelationship.prototype), "addRecord", this).call(this, newRecord);
+ this.internalModel.notifyBelongsToChanged(this.key);
}
- return record;
- });
- };
+ }, {
+ key: "setRecordPromise",
+ value: function setRecordPromise(newPromise) {
+ var content = newPromise.get && newPromise.get('content');
- BelongsToRelationship.prototype.getRecord = function () {
- var _this2 = this;
-
- //TODO(Igor) flushCanonical here once our syncing is not stupid
- if (this.isAsync) {
- var promise;
- if (this.link) {
- if (this.hasLoaded) {
- promise = this.findRecord();
+ this.setRecord(content ? content._internalModel : content);
+ }
+ }, {
+ key: "removeRecordFromOwn",
+ value: function removeRecordFromOwn(record) {
+ if (!this.members.has(record)) {
+ return;
+ }
+ this.inverseRecord = null;
+ _get(Object.getPrototypeOf(BelongsToRelationship.prototype), "removeRecordFromOwn", this).call(this, record);
+ this.internalModel.notifyBelongsToChanged(this.key);
+ }
+ }, {
+ key: "removeCanonicalRecordFromOwn",
+ value: function removeCanonicalRecordFromOwn(record) {
+ if (!this.canonicalMembers.has(record)) {
+ return;
+ }
+ this.canonicalState = null;
+ _get(Object.getPrototypeOf(BelongsToRelationship.prototype), "removeCanonicalRecordFromOwn", this).call(this, record);
+ }
+ }, {
+ key: "findRecord",
+ value: function findRecord() {
+ if (this.inverseRecord) {
+ return this.store._findByInternalModel(this.inverseRecord);
} else {
- promise = this.findLink().then(function () {
- return _this2.findRecord();
- });
+ return _ember.default.RSVP.Promise.resolve(null);
}
- } else {
- promise = this.findRecord();
}
+ }, {
+ key: "fetchLink",
+ value: function fetchLink() {
+ var _this = this;
- return _emberDataPrivateSystemPromiseProxies.PromiseObject.create({
- promise: promise,
- content: this.inverseRecord ? this.inverseRecord.getRecord() : null
- });
- } else {
- if (this.inverseRecord === null) {
- return null;
+ return this.store.findBelongsTo(this.internalModel, this.link, this.relationshipMeta).then(function (record) {
+ if (record) {
+ _this.addRecord(record);
+ }
+ return record;
+ });
}
- var toReturn = this.inverseRecord.getRecord();
+ }, {
+ key: "getRecord",
+ value: function getRecord() {
+ var _this2 = this;
- return toReturn;
- }
- };
+ //TODO(Igor) flushCanonical here once our syncing is not stupid
+ if (this.isAsync) {
+ var promise;
+ if (this.link) {
+ if (this.hasLoaded) {
+ promise = this.findRecord();
+ } else {
+ promise = this.findLink().then(function () {
+ return _this2.findRecord();
+ });
+ }
+ } else {
+ promise = this.findRecord();
+ }
- BelongsToRelationship.prototype.reload = function () {
- // TODO handle case when reload() is triggered multiple times
+ return _emberDataPrivateSystemPromiseProxies.PromiseObject.create({
+ promise: promise,
+ content: this.inverseRecord ? this.inverseRecord.getRecord() : null
+ });
+ } else {
+ if (this.inverseRecord === null) {
+ return null;
+ }
+ var toReturn = this.inverseRecord.getRecord();
- if (this.link) {
- return this.fetchLink();
- }
+ return toReturn;
+ }
+ }
+ }, {
+ key: "reload",
+ value: function reload() {
+ // TODO handle case when reload() is triggered multiple times
- // reload record, if it is already loaded
- if (this.inverseRecord && this.inverseRecord.hasRecord) {
- return this.inverseRecord.record.reload();
- }
+ if (this.link) {
+ return this.fetchLink();
+ }
- return this.findRecord();
- };
+ // reload record, if it is already loaded
+ if (this.inverseRecord && this.inverseRecord.hasRecord) {
+ return this.inverseRecord.record.reload();
+ }
- BelongsToRelationship.prototype.updateData = function (data) {
- var internalModel = this.store._pushResourceIdentifier(this, data);
- this.setCanonicalRecord(internalModel);
- };
+ return this.findRecord();
+ }
+ }, {
+ key: "updateData",
+ value: function updateData(data) {
+ var internalModel = this.store._pushResourceIdentifier(this, data);
+ this.setCanonicalRecord(internalModel);
+ }
+ }]);
+
+ return BelongsToRelationship;
+ })(_emberDataPrivateSystemRelationshipsStateRelationship.default);
+
+ exports.default = BelongsToRelationship;
});
-define("ember-data/-private/system/relationships/state/create", ["exports", "ember", "ember-data/-private/system/relationships/state/has-many", "ember-data/-private/system/relationships/state/belongs-to", "ember-data/-private/system/empty-object"], function (exports, _ember, _emberDataPrivateSystemRelationshipsStateHasMany, _emberDataPrivateSystemRelationshipsStateBelongsTo, _emberDataPrivateSystemEmptyObject) {
- exports.default = Relationships;
+define("ember-data/-private/system/relationships/state/create", ["exports", "ember", "ember-data/-private/system/relationships/state/has-many", "ember-data/-private/system/relationships/state/belongs-to", "ember-data/-private/system/empty-object", "ember-data/-private/debug"], function (exports, _ember, _emberDataPrivateSystemRelationshipsStateHasMany, _emberDataPrivateSystemRelationshipsStateBelongsTo, _emberDataPrivateSystemEmptyObject, _emberDataPrivateDebug) {
+ var _createClass = (function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })();
- var get = _ember.default.get;
+ function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
+ var _get = _ember.default.get;
+
function shouldFindInverse(relationshipMeta) {
var options = relationshipMeta.options;
return !(options && options.inverse === null);
}
- function createRelationshipFor(record, relationshipMeta, store) {
+ function createRelationshipFor(internalModel, relationshipMeta, store) {
var inverseKey = undefined;
var inverse = null;
+
if (shouldFindInverse(relationshipMeta)) {
- inverse = record.type.inverseFor(relationshipMeta.key, store);
- }
+ inverse = internalModel.type.inverseFor(relationshipMeta.key, store);
+ } else {}
if (inverse) {
inverseKey = inverse.name;
}
if (relationshipMeta.kind === 'hasMany') {
- return new _emberDataPrivateSystemRelationshipsStateHasMany.default(store, record, inverseKey, relationshipMeta);
+ return new _emberDataPrivateSystemRelationshipsStateHasMany.default(store, internalModel, inverseKey, relationshipMeta);
} else {
- return new _emberDataPrivateSystemRelationshipsStateBelongsTo.default(store, record, inverseKey, relationshipMeta);
+ return new _emberDataPrivateSystemRelationshipsStateBelongsTo.default(store, internalModel, inverseKey, relationshipMeta);
}
}
- function Relationships(record) {
- this.record = record;
- this.initializedRelationships = new _emberDataPrivateSystemEmptyObject.default();
- }
+ var Relationships = (function () {
+ function Relationships(internalModel) {
+ this.internalModel = internalModel;
+ this.initializedRelationships = new _emberDataPrivateSystemEmptyObject.default();
+ }
- Relationships.prototype.has = function (key) {
- return !!this.initializedRelationships[key];
- };
+ // TODO @runspired deprecate this as it was never truly a record instance
- Relationships.prototype.get = function (key) {
- var relationships = this.initializedRelationships;
- var relationshipsByName = get(this.record.type, 'relationshipsByName');
- if (!relationships[key] && relationshipsByName.get(key)) {
- relationships[key] = createRelationshipFor(this.record, relationshipsByName.get(key), this.record.store);
- }
- return relationships[key];
- };
-});
-define("ember-data/-private/system/relationships/state/has-many", ["exports", "ember-data/-private/debug", "ember-data/-private/system/promise-proxies", "ember-data/-private/system/relationships/state/relationship", "ember-data/-private/system/ordered-set", "ember-data/-private/system/many-array"], function (exports, _emberDataPrivateDebug, _emberDataPrivateSystemPromiseProxies, _emberDataPrivateSystemRelationshipsStateRelationship, _emberDataPrivateSystemOrderedSet, _emberDataPrivateSystemManyArray) {
- exports.default = ManyRelationship;
+ _createClass(Relationships, [{
+ key: "has",
+ value: function has(key) {
+ return !!this.initializedRelationships[key];
+ }
+ }, {
+ key: "get",
+ value: function get(key) {
+ var relationships = this.initializedRelationships;
+ var internalModel = this.internalModel;
+ var relationshipsByName = _get(internalModel.type, 'relationshipsByName');
- function ManyRelationship(store, record, inverseKey, relationshipMeta) {
- this._super$constructor(store, record, inverseKey, relationshipMeta);
- this.belongsToType = relationshipMeta.type;
- this.canonicalState = [];
- this.isPolymorphic = relationshipMeta.options.polymorphic;
- }
+ if (!relationships[key] && relationshipsByName.get(key)) {
+ relationships[key] = createRelationshipFor(internalModel, relationshipsByName.get(key), internalModel.store);
+ }
- ManyRelationship.prototype = Object.create(_emberDataPrivateSystemRelationshipsStateRelationship.default.prototype);
- ManyRelationship.prototype.getManyArray = function () {
- if (!this._manyArray) {
- this._manyArray = _emberDataPrivateSystemManyArray.default.create({
- canonicalState: this.canonicalState,
- store: this.store,
- relationship: this,
- type: this.store.modelFor(this.belongsToType),
- record: this.record,
- meta: this.meta,
- isPolymorphic: this.isPolymorphic
- });
- }
- return this._manyArray;
- };
+ return relationships[key];
+ }
+ }, {
+ key: "record",
+ get: function () {
+ return this.internalModel;
+ }
+ }]);
- ManyRelationship.prototype.constructor = ManyRelationship;
- ManyRelationship.prototype._super$constructor = _emberDataPrivateSystemRelationshipsStateRelationship.default;
+ return Relationships;
+ })();
- ManyRelationship.prototype.destroy = function () {
- if (this._manyArray) {
- this._manyArray.destroy();
- }
- };
+ exports.default = Relationships;
+});
+define("ember-data/-private/system/relationships/state/has-many", ["exports", "ember-data/-private/debug", "ember-data/-private/system/promise-proxies", "ember-data/-private/system/relationships/state/relationship", "ember-data/-private/system/ordered-set", "ember-data/-private/system/many-array"], function (exports, _emberDataPrivateDebug, _emberDataPrivateSystemPromiseProxies, _emberDataPrivateSystemRelationshipsStateRelationship, _emberDataPrivateSystemOrderedSet, _emberDataPrivateSystemManyArray) {
+ var _createClass = (function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })();
- ManyRelationship.prototype._super$updateMeta = _emberDataPrivateSystemRelationshipsStateRelationship.default.prototype.updateMeta;
- ManyRelationship.prototype.updateMeta = function (meta) {
- this._super$updateMeta(meta);
- if (this._manyArray) {
- this._manyArray.set('meta', meta);
- }
- };
+ var _get = function get(object, property, receiver) { if (object === null) object = Function.prototype; var desc = Object.getOwnPropertyDescriptor(object, property); if (desc === undefined) { var parent = Object.getPrototypeOf(object); if (parent === null) { return undefined; } else { return get(parent, property, receiver); } } else if ("value" in desc) { return desc.value; } else { var getter = desc.get; if (getter === undefined) { return undefined; } return getter.call(receiver); } };
- ManyRelationship.prototype._super$addCanonicalRecord = _emberDataPrivateSystemRelationshipsStateRelationship.default.prototype.addCanonicalRecord;
- ManyRelationship.prototype.addCanonicalRecord = function (record, idx) {
- if (this.canonicalMembers.has(record)) {
- return;
- }
- if (idx !== undefined) {
- this.canonicalState.splice(idx, 0, record);
- } else {
- this.canonicalState.push(record);
- }
- this._super$addCanonicalRecord(record, idx);
- };
+ function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
- ManyRelationship.prototype._super$addRecord = _emberDataPrivateSystemRelationshipsStateRelationship.default.prototype.addRecord;
- ManyRelationship.prototype.addRecord = function (record, idx) {
- if (this.members.has(record)) {
- return;
- }
- this._super$addRecord(record, idx);
- // make lazy later
- this.getManyArray().internalAddRecords([record], idx);
- };
+ function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }
- ManyRelationship.prototype._super$removeCanonicalRecordFromOwn = _emberDataPrivateSystemRelationshipsStateRelationship.default.prototype.removeCanonicalRecordFromOwn;
- ManyRelationship.prototype.removeCanonicalRecordFromOwn = function (record, idx) {
- var i = idx;
- if (!this.canonicalMembers.has(record)) {
- return;
- }
- if (i === undefined) {
- i = this.canonicalState.indexOf(record);
- }
- if (i > -1) {
- this.canonicalState.splice(i, 1);
- }
- this._super$removeCanonicalRecordFromOwn(record, idx);
- };
+ var ManyRelationship = (function (_Relationship) {
+ _inherits(ManyRelationship, _Relationship);
- ManyRelationship.prototype._super$flushCanonical = _emberDataPrivateSystemRelationshipsStateRelationship.default.prototype.flushCanonical;
- ManyRelationship.prototype.flushCanonical = function () {
- if (this._manyArray) {
- this._manyArray.flushCanonical();
+ function ManyRelationship(store, record, inverseKey, relationshipMeta) {
+ _get(Object.getPrototypeOf(ManyRelationship.prototype), "constructor", this).call(this, store, record, inverseKey, relationshipMeta);
+ this.belongsToType = relationshipMeta.type;
+ this.canonicalState = [];
+ this.isPolymorphic = relationshipMeta.options.polymorphic;
}
- this._super$flushCanonical();
- };
- ManyRelationship.prototype._super$removeRecordFromOwn = _emberDataPrivateSystemRelationshipsStateRelationship.default.prototype.removeRecordFromOwn;
- ManyRelationship.prototype.removeRecordFromOwn = function (record, idx) {
- if (!this.members.has(record)) {
- return;
- }
- this._super$removeRecordFromOwn(record, idx);
- var manyArray = this.getManyArray();
- if (idx !== undefined) {
- //TODO(Igor) not used currently, fix
- manyArray.currentState.removeAt(idx);
- } else {
- manyArray.internalRemoveRecords([record]);
- }
- };
-
- ManyRelationship.prototype.notifyRecordRelationshipAdded = function (record, idx) {
-
- this.record.notifyHasManyAdded(this.key, record, idx);
- };
-
- ManyRelationship.prototype.reload = function () {
- var manyArray = this.getManyArray();
- var manyArrayLoadedState = manyArray.get('isLoaded');
-
- if (this._loadingPromise) {
- if (this._loadingPromise.get('isPending')) {
- return this._loadingPromise;
+ _createClass(ManyRelationship, [{
+ key: "getManyArray",
+ value: function getManyArray() {
+ if (!this._manyArray) {
+ this._manyArray = _emberDataPrivateSystemManyArray.default.create({
+ canonicalState: this.canonicalState,
+ store: this.store,
+ relationship: this,
+ type: this.store.modelFor(this.belongsToType),
+ record: this.record,
+ meta: this.meta,
+ isPolymorphic: this.isPolymorphic
+ });
+ }
+ return this._manyArray;
}
- if (this._loadingPromise.get('isRejected')) {
- manyArray.set('isLoaded', manyArrayLoadedState);
+ }, {
+ key: "destroy",
+ value: function destroy() {
+ if (this._manyArray) {
+ this._manyArray.destroy();
+ }
}
- }
+ }, {
+ key: "updateMeta",
+ value: function updateMeta(meta) {
+ _get(Object.getPrototypeOf(ManyRelationship.prototype), "updateMeta", this).call(this, meta);
+ if (this._manyArray) {
+ this._manyArray.set('meta', meta);
+ }
+ }
+ }, {
+ key: "addCanonicalRecord",
+ value: function addCanonicalRecord(record, idx) {
+ if (this.canonicalMembers.has(record)) {
+ return;
+ }
+ if (idx !== undefined) {
+ this.canonicalState.splice(idx, 0, record);
+ } else {
+ this.canonicalState.push(record);
+ }
+ _get(Object.getPrototypeOf(ManyRelationship.prototype), "addCanonicalRecord", this).call(this, record, idx);
+ }
+ }, {
+ key: "addRecord",
+ value: function addRecord(record, idx) {
+ if (this.members.has(record)) {
+ return;
+ }
+ _get(Object.getPrototypeOf(ManyRelationship.prototype), "addRecord", this).call(this, record, idx);
+ // make lazy later
+ this.getManyArray().internalAddRecords([record], idx);
+ }
+ }, {
+ key: "removeCanonicalRecordFromOwn",
+ value: function removeCanonicalRecordFromOwn(record, idx) {
+ var i = idx;
+ if (!this.canonicalMembers.has(record)) {
+ return;
+ }
+ if (i === undefined) {
+ i = this.canonicalState.indexOf(record);
+ }
+ if (i > -1) {
+ this.canonicalState.splice(i, 1);
+ }
+ _get(Object.getPrototypeOf(ManyRelationship.prototype), "removeCanonicalRecordFromOwn", this).call(this, record, idx);
+ }
+ }, {
+ key: "flushCanonical",
+ value: function flushCanonical() {
+ if (this._manyArray) {
+ this._manyArray.flushCanonical();
+ }
+ _get(Object.getPrototypeOf(ManyRelationship.prototype), "flushCanonical", this).call(this);
+ }
+ }, {
+ key: "removeRecordFromOwn",
+ value: function removeRecordFromOwn(record, idx) {
+ if (!this.members.has(record)) {
+ return;
+ }
+ _get(Object.getPrototypeOf(ManyRelationship.prototype), "removeRecordFromOwn", this).call(this, record, idx);
+ var manyArray = this.getManyArray();
+ if (idx !== undefined) {
+ //TODO(Igor) not used currently, fix
+ manyArray.currentState.removeAt(idx);
+ } else {
+ manyArray.internalRemoveRecords([record]);
+ }
+ }
+ }, {
+ key: "notifyRecordRelationshipAdded",
+ value: function notifyRecordRelationshipAdded(record, idx) {
- if (this.link) {
- this._loadingPromise = (0, _emberDataPrivateSystemPromiseProxies.promiseManyArray)(this.fetchLink(), 'Reload with link');
- return this._loadingPromise;
- } else {
- this._loadingPromise = (0, _emberDataPrivateSystemPromiseProxies.promiseManyArray)(this.store._scheduleFetchMany(manyArray.currentState).then(function () {
- return manyArray;
- }), 'Reload with ids');
- return this._loadingPromise;
- }
- };
+ this.record.notifyHasManyAdded(this.key, record, idx);
+ }
+ }, {
+ key: "reload",
+ value: function reload() {
+ var manyArray = this.getManyArray();
+ var manyArrayLoadedState = manyArray.get('isLoaded');
- ManyRelationship.prototype.computeChanges = function (records) {
- var members = this.canonicalMembers;
- var recordsToRemove = [];
- var length;
- var record;
- var i;
+ if (this._loadingPromise) {
+ if (this._loadingPromise.get('isPending')) {
+ return this._loadingPromise;
+ }
+ if (this._loadingPromise.get('isRejected')) {
+ manyArray.set('isLoaded', manyArrayLoadedState);
+ }
+ }
- records = setForArray(records);
-
- members.forEach(function (member) {
- if (records.has(member)) {
- return;
+ if (this.link) {
+ this._loadingPromise = (0, _emberDataPrivateSystemPromiseProxies.promiseManyArray)(this.fetchLink(), 'Reload with link');
+ return this._loadingPromise;
+ } else {
+ this._loadingPromise = (0, _emberDataPrivateSystemPromiseProxies.promiseManyArray)(this.store._scheduleFetchMany(manyArray.currentState).then(function () {
+ return manyArray;
+ }), 'Reload with ids');
+ return this._loadingPromise;
+ }
}
+ }, {
+ key: "computeChanges",
+ value: function computeChanges(records) {
+ var members = this.canonicalMembers;
+ var recordsToRemove = [];
+ var length;
+ var record;
+ var i;
- recordsToRemove.push(member);
- });
+ records = setForArray(records);
- this.removeCanonicalRecords(recordsToRemove);
+ members.forEach(function (member) {
+ if (records.has(member)) {
+ return;
+ }
- // Using records.toArray() since currently using
- // removeRecord can modify length, messing stuff up
- // forEach since it directly looks at "length" each
- // iteration
- records = records.toArray();
- length = records.length;
- for (i = 0; i < length; i++) {
- record = records[i];
- this.removeCanonicalRecord(record);
- this.addCanonicalRecord(record, i);
- }
- };
+ recordsToRemove.push(member);
+ });
- ManyRelationship.prototype.fetchLink = function () {
- var _this = this;
+ this.removeCanonicalRecords(recordsToRemove);
- return this.store.findHasMany(this.record, this.link, this.relationshipMeta).then(function (records) {
- if (records.hasOwnProperty('meta')) {
- _this.updateMeta(records.meta);
+ // Using records.toArray() since currently using
+ // removeRecord can modify length, messing stuff up
+ // forEach since it directly looks at "length" each
+ // iteration
+ records = records.toArray();
+ length = records.length;
+ for (i = 0; i < length; i++) {
+ record = records[i];
+ this.removeCanonicalRecord(record);
+ this.addCanonicalRecord(record, i);
+ }
}
- _this.store._backburner.join(function () {
- _this.updateRecordsFromAdapter(records);
- _this.getManyArray().set('isLoaded', true);
- });
- return _this.getManyArray();
- });
- };
+ }, {
+ key: "fetchLink",
+ value: function fetchLink() {
+ var _this = this;
- ManyRelationship.prototype.findRecords = function () {
- var manyArray = this.getManyArray();
- var array = manyArray.toArray();
- var internalModels = new Array(array.length);
+ return this.store.findHasMany(this.record, this.link, this.relationshipMeta).then(function (records) {
+ if (records.hasOwnProperty('meta')) {
+ _this.updateMeta(records.meta);
+ }
+ _this.store._backburner.join(function () {
+ _this.updateRecordsFromAdapter(records);
+ _this.getManyArray().set('isLoaded', true);
+ });
+ return _this.getManyArray();
+ });
+ }
+ }, {
+ key: "findRecords",
+ value: function findRecords() {
+ var manyArray = this.getManyArray();
+ var array = manyArray.toArray();
+ var internalModels = new Array(array.length);
- for (var i = 0; i < array.length; i++) {
- internalModels[i] = array[i]._internalModel;
- }
+ for (var i = 0; i < array.length; i++) {
+ internalModels[i] = array[i]._internalModel;
+ }
- //TODO CLEANUP
- return this.store.findMany(internalModels).then(function () {
- if (!manyArray.get('isDestroyed')) {
- //Goes away after the manyArray refactor
- manyArray.set('isLoaded', true);
+ //TODO CLEANUP
+ return this.store.findMany(internalModels).then(function () {
+ if (!manyArray.get('isDestroyed')) {
+ //Goes away after the manyArray refactor
+ manyArray.set('isLoaded', true);
+ }
+ return manyArray;
+ });
}
- return manyArray;
- });
- };
- ManyRelationship.prototype.notifyHasManyChanged = function () {
- this.record.notifyHasManyAdded(this.key);
- };
+ }, {
+ key: "notifyHasManyChanged",
+ value: function notifyHasManyChanged() {
+ this.record.notifyHasManyAdded(this.key);
+ }
+ }, {
+ key: "getRecords",
+ value: function getRecords() {
+ var _this2 = this;
- ManyRelationship.prototype.getRecords = function () {
- var _this2 = this;
-
- //TODO(Igor) sync server here, once our syncing is not stupid
- var manyArray = this.getManyArray();
- if (this.isAsync) {
- var promise;
- if (this.link) {
- if (this.hasLoaded) {
- promise = this.findRecords();
- } else {
- promise = this.findLink().then(function () {
- return _this2.findRecords();
+ //TODO(Igor) sync server here, once our syncing is not stupid
+ var manyArray = this.getManyArray();
+ if (this.isAsync) {
+ var promise;
+ if (this.link) {
+ if (this.hasLoaded) {
+ promise = this.findRecords();
+ } else {
+ promise = this.findLink().then(function () {
+ return _this2.findRecords();
+ });
+ }
+ } else {
+ promise = this.findRecords();
+ }
+ this._loadingPromise = _emberDataPrivateSystemPromiseProxies.PromiseManyArray.create({
+ content: manyArray,
+ promise: promise
});
+ return this._loadingPromise;
+ } else {
+
+ //TODO(Igor) WTF DO I DO HERE?
+ // TODO @runspired equal WTFs to Igor
+ if (!manyArray.get('isDestroyed')) {
+ manyArray.set('isLoaded', true);
+ }
+ return manyArray;
}
- } else {
- promise = this.findRecords();
}
- this._loadingPromise = _emberDataPrivateSystemPromiseProxies.PromiseManyArray.create({
- content: manyArray,
- promise: promise
- });
- return this._loadingPromise;
- } else {
-
- //TODO(Igor) WTF DO I DO HERE?
- if (!manyArray.get('isDestroyed')) {
- manyArray.set('isLoaded', true);
+ }, {
+ key: "updateData",
+ value: function updateData(data) {
+ var internalModels = this.store._pushResourceIdentifiers(this, data);
+ this.updateRecordsFromAdapter(internalModels);
}
- return manyArray;
- }
- };
+ }]);
- ManyRelationship.prototype.updateData = function (data) {
- var internalModels = this.store._pushResourceIdentifiers(this, data);
- this.updateRecordsFromAdapter(internalModels);
- };
+ return ManyRelationship;
+ })(_emberDataPrivateSystemRelationshipsStateRelationship.default);
+ exports.default = ManyRelationship;
+
function setForArray(array) {
var set = new _emberDataPrivateSystemOrderedSet.default();
if (array) {
for (var i = 0, l = array.length; i < l; i++) {
@@ -8053,307 +8599,355 @@
return set;
}
});
define("ember-data/-private/system/relationships/state/relationship", ["exports", "ember-data/-private/debug", "ember-data/-private/system/ordered-set", "ember-data/-private/system/normalize-link"], function (exports, _emberDataPrivateDebug, _emberDataPrivateSystemOrderedSet, _emberDataPrivateSystemNormalizeLink) {
- exports.default = Relationship;
+ var _createClass = (function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })();
- function Relationship(store, record, inverseKey, relationshipMeta) {
- var async = relationshipMeta.options.async;
- this.members = new _emberDataPrivateSystemOrderedSet.default();
- this.canonicalMembers = new _emberDataPrivateSystemOrderedSet.default();
- this.store = store;
- this.key = relationshipMeta.key;
- this.inverseKey = inverseKey;
- this.record = record;
- this.isAsync = typeof async === 'undefined' ? true : async;
- this.relationshipMeta = relationshipMeta;
- //This probably breaks for polymorphic relationship in complex scenarios, due to
- //multiple possible modelNames
- this.inverseKeyForImplicit = this.record.constructor.modelName + this.key;
- this.linkPromise = null;
- this.meta = null;
- this.hasData = false;
- this.hasLoaded = false;
- }
+ function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
- Relationship.prototype = {
- constructor: Relationship,
+ var Relationship = (function () {
+ function Relationship(store, internalModel, inverseKey, relationshipMeta) {
+ var async = relationshipMeta.options.async;
+ this.members = new _emberDataPrivateSystemOrderedSet.default();
+ this.canonicalMembers = new _emberDataPrivateSystemOrderedSet.default();
+ this.store = store;
+ this.key = relationshipMeta.key;
+ this.inverseKey = inverseKey;
+ this.internalModel = internalModel;
+ this.isAsync = typeof async === 'undefined' ? true : async;
+ this.relationshipMeta = relationshipMeta;
+ //This probably breaks for polymorphic relationship in complex scenarios, due to
+ //multiple possible modelNames
+ this.inverseKeyForImplicit = this.internalModel.modelName + this.key;
+ this.linkPromise = null;
+ this.meta = null;
+ this.hasData = false;
+ this.hasLoaded = false;
+ }
- destroy: function () {},
+ // TODO @runspired deprecate this as it was never truly a record instance
- updateMeta: function (meta) {
- this.meta = meta;
- },
+ _createClass(Relationship, [{
+ key: "destroy",
+ value: function destroy() {}
+ }, {
+ key: "updateMeta",
+ value: function updateMeta(meta) {
+ this.meta = meta;
+ }
+ }, {
+ key: "clear",
+ value: function clear() {
+ var members = this.members.list;
+ var member;
- clear: function () {
- var members = this.members.list;
- var member;
+ while (members.length > 0) {
+ member = members[0];
+ this.removeRecord(member);
+ }
+ }
+ }, {
+ key: "removeRecords",
+ value: function removeRecords(records) {
+ var _this = this;
- while (members.length > 0) {
- member = members[0];
- this.removeRecord(member);
+ records.forEach(function (record) {
+ return _this.removeRecord(record);
+ });
}
- },
+ }, {
+ key: "addRecords",
+ value: function addRecords(records, idx) {
+ var _this2 = this;
- removeRecords: function (records) {
- var _this = this;
-
- records.forEach(function (record) {
- return _this.removeRecord(record);
- });
- },
-
- addRecords: function (records, idx) {
- var _this2 = this;
-
- records.forEach(function (record) {
- _this2.addRecord(record, idx);
- if (idx !== undefined) {
- idx++;
+ records.forEach(function (record) {
+ _this2.addRecord(record, idx);
+ if (idx !== undefined) {
+ idx++;
+ }
+ });
+ }
+ }, {
+ key: "addCanonicalRecords",
+ value: function addCanonicalRecords(records, idx) {
+ for (var i = 0; i < records.length; i++) {
+ if (idx !== undefined) {
+ this.addCanonicalRecord(records[i], i + idx);
+ } else {
+ this.addCanonicalRecord(records[i]);
+ }
}
- });
- },
-
- addCanonicalRecords: function (records, idx) {
- for (var i = 0; i < records.length; i++) {
- if (idx !== undefined) {
- this.addCanonicalRecord(records[i], i + idx);
- } else {
- this.addCanonicalRecord(records[i]);
+ }
+ }, {
+ key: "addCanonicalRecord",
+ value: function addCanonicalRecord(record, idx) {
+ if (!this.canonicalMembers.has(record)) {
+ this.canonicalMembers.add(record);
+ if (this.inverseKey) {
+ record._relationships.get(this.inverseKey).addCanonicalRecord(this.record);
+ } else {
+ if (!record._implicitRelationships[this.inverseKeyForImplicit]) {
+ record._implicitRelationships[this.inverseKeyForImplicit] = new Relationship(this.store, record, this.key, { options: {} });
+ }
+ record._implicitRelationships[this.inverseKeyForImplicit].addCanonicalRecord(this.record);
+ }
}
+ this.flushCanonicalLater();
+ this.setHasData(true);
}
- },
-
- addCanonicalRecord: function (record, idx) {
- if (!this.canonicalMembers.has(record)) {
- this.canonicalMembers.add(record);
- if (this.inverseKey) {
- record._relationships.get(this.inverseKey).addCanonicalRecord(this.record);
- } else {
- if (!record._implicitRelationships[this.inverseKeyForImplicit]) {
- record._implicitRelationships[this.inverseKeyForImplicit] = new Relationship(this.store, record, this.key, { options: {} });
+ }, {
+ key: "removeCanonicalRecords",
+ value: function removeCanonicalRecords(records, idx) {
+ for (var i = 0; i < records.length; i++) {
+ if (idx !== undefined) {
+ this.removeCanonicalRecord(records[i], i + idx);
+ } else {
+ this.removeCanonicalRecord(records[i]);
}
- record._implicitRelationships[this.inverseKeyForImplicit].addCanonicalRecord(this.record);
}
}
- this.flushCanonicalLater();
- this.setHasData(true);
- },
-
- removeCanonicalRecords: function (records, idx) {
- for (var i = 0; i < records.length; i++) {
- if (idx !== undefined) {
- this.removeCanonicalRecord(records[i], i + idx);
- } else {
- this.removeCanonicalRecord(records[i]);
+ }, {
+ key: "removeCanonicalRecord",
+ value: function removeCanonicalRecord(record, idx) {
+ if (this.canonicalMembers.has(record)) {
+ this.removeCanonicalRecordFromOwn(record);
+ if (this.inverseKey) {
+ this.removeCanonicalRecordFromInverse(record);
+ } else {
+ if (record._implicitRelationships[this.inverseKeyForImplicit]) {
+ record._implicitRelationships[this.inverseKeyForImplicit].removeCanonicalRecord(this.record);
+ }
+ }
}
+ this.flushCanonicalLater();
}
- },
-
- removeCanonicalRecord: function (record, idx) {
- if (this.canonicalMembers.has(record)) {
- this.removeCanonicalRecordFromOwn(record);
- if (this.inverseKey) {
- this.removeCanonicalRecordFromInverse(record);
- } else {
- if (record._implicitRelationships[this.inverseKeyForImplicit]) {
- record._implicitRelationships[this.inverseKeyForImplicit].removeCanonicalRecord(this.record);
+ }, {
+ key: "addRecord",
+ value: function addRecord(record, idx) {
+ if (!this.members.has(record)) {
+ this.members.addWithIndex(record, idx);
+ this.notifyRecordRelationshipAdded(record, idx);
+ if (this.inverseKey) {
+ record._relationships.get(this.inverseKey).addRecord(this.record);
+ } else {
+ if (!record._implicitRelationships[this.inverseKeyForImplicit]) {
+ record._implicitRelationships[this.inverseKeyForImplicit] = new Relationship(this.store, record, this.key, { options: {} });
+ }
+ record._implicitRelationships[this.inverseKeyForImplicit].addRecord(this.record);
}
+ this.record.updateRecordArraysLater();
}
+ this.setHasData(true);
}
- this.flushCanonicalLater();
- },
-
- addRecord: function (record, idx) {
- if (!this.members.has(record)) {
- this.members.addWithIndex(record, idx);
- this.notifyRecordRelationshipAdded(record, idx);
- if (this.inverseKey) {
- record._relationships.get(this.inverseKey).addRecord(this.record);
- } else {
- if (!record._implicitRelationships[this.inverseKeyForImplicit]) {
- record._implicitRelationships[this.inverseKeyForImplicit] = new Relationship(this.store, record, this.key, { options: {} });
+ }, {
+ key: "removeRecord",
+ value: function removeRecord(record) {
+ if (this.members.has(record)) {
+ this.removeRecordFromOwn(record);
+ if (this.inverseKey) {
+ this.removeRecordFromInverse(record);
+ } else {
+ if (record._implicitRelationships[this.inverseKeyForImplicit]) {
+ record._implicitRelationships[this.inverseKeyForImplicit].removeRecord(this.record);
+ }
}
- record._implicitRelationships[this.inverseKeyForImplicit].addRecord(this.record);
}
- this.record.updateRecordArraysLater();
}
- this.setHasData(true);
- },
-
- removeRecord: function (record) {
- if (this.members.has(record)) {
- this.removeRecordFromOwn(record);
- if (this.inverseKey) {
- this.removeRecordFromInverse(record);
- } else {
- if (record._implicitRelationships[this.inverseKeyForImplicit]) {
- record._implicitRelationships[this.inverseKeyForImplicit].removeRecord(this.record);
+ }, {
+ key: "removeRecordFromInverse",
+ value: function removeRecordFromInverse(record) {
+ var inverseRelationship = record._relationships.get(this.inverseKey);
+ //Need to check for existence, as the record might unloading at the moment
+ if (inverseRelationship) {
+ inverseRelationship.removeRecordFromOwn(this.record);
+ }
+ }
+ }, {
+ key: "removeRecordFromOwn",
+ value: function removeRecordFromOwn(record) {
+ this.members.delete(record);
+ this.notifyRecordRelationshipRemoved(record);
+ this.record.updateRecordArrays();
+ }
+ }, {
+ key: "removeCanonicalRecordFromInverse",
+ value: function removeCanonicalRecordFromInverse(record) {
+ var inverseRelationship = record._relationships.get(this.inverseKey);
+ //Need to check for existence, as the record might unloading at the moment
+ if (inverseRelationship) {
+ inverseRelationship.removeCanonicalRecordFromOwn(this.record);
+ }
+ }
+ }, {
+ key: "removeCanonicalRecordFromOwn",
+ value: function removeCanonicalRecordFromOwn(record) {
+ this.canonicalMembers.delete(record);
+ this.flushCanonicalLater();
+ }
+ }, {
+ key: "flushCanonical",
+ value: function flushCanonical() {
+ this.willSync = false;
+ //a hack for not removing new records
+ //TODO remove once we have proper diffing
+ var newRecords = [];
+ for (var i = 0; i < this.members.list.length; i++) {
+ if (this.members.list[i].isNew()) {
+ newRecords.push(this.members.list[i]);
}
}
+ //TODO(Igor) make this less abysmally slow
+ this.members = this.canonicalMembers.copy();
+ for (i = 0; i < newRecords.length; i++) {
+ this.members.add(newRecords[i]);
+ }
}
- },
+ }, {
+ key: "flushCanonicalLater",
+ value: function flushCanonicalLater() {
+ var _this3 = this;
- removeRecordFromInverse: function (record) {
- var inverseRelationship = record._relationships.get(this.inverseKey);
- //Need to check for existence, as the record might unloading at the moment
- if (inverseRelationship) {
- inverseRelationship.removeRecordFromOwn(this.record);
+ if (this.willSync) {
+ return;
+ }
+ this.willSync = true;
+ this.store._backburner.join(function () {
+ return _this3.store._backburner.schedule('syncRelationships', _this3, _this3.flushCanonical);
+ });
}
- },
+ }, {
+ key: "updateLink",
+ value: function updateLink(link) {
- removeRecordFromOwn: function (record) {
- this.members.delete(record);
- this.notifyRecordRelationshipRemoved(record);
- this.record.updateRecordArrays();
- },
-
- removeCanonicalRecordFromInverse: function (record) {
- var inverseRelationship = record._relationships.get(this.inverseKey);
- //Need to check for existence, as the record might unloading at the moment
- if (inverseRelationship) {
- inverseRelationship.removeCanonicalRecordFromOwn(this.record);
+ this.link = link;
+ this.linkPromise = null;
+ this.record.notifyPropertyChange(this.key);
}
- },
-
- removeCanonicalRecordFromOwn: function (record) {
- this.canonicalMembers.delete(record);
- this.flushCanonicalLater();
- },
-
- flushCanonical: function () {
- this.willSync = false;
- //a hack for not removing new records
- //TODO remove once we have proper diffing
- var newRecords = [];
- for (var i = 0; i < this.members.list.length; i++) {
- if (this.members.list[i].isNew()) {
- newRecords.push(this.members.list[i]);
+ }, {
+ key: "findLink",
+ value: function findLink() {
+ if (this.linkPromise) {
+ return this.linkPromise;
+ } else {
+ var promise = this.fetchLink();
+ this.linkPromise = promise;
+ return promise.then(function (result) {
+ return result;
+ });
}
}
- //TODO(Igor) make this less abysmally slow
- this.members = this.canonicalMembers.copy();
- for (i = 0; i < newRecords.length; i++) {
- this.members.add(newRecords[i]);
+ }, {
+ key: "updateRecordsFromAdapter",
+ value: function updateRecordsFromAdapter(records) {
+ //TODO(Igor) move this to a proper place
+ //TODO Once we have adapter support, we need to handle updated and canonical changes
+ this.computeChanges(records);
}
- },
+ }, {
+ key: "notifyRecordRelationshipAdded",
+ value: function notifyRecordRelationshipAdded() {}
+ }, {
+ key: "notifyRecordRelationshipRemoved",
+ value: function notifyRecordRelationshipRemoved() {}
- flushCanonicalLater: function () {
- var _this3 = this;
-
- if (this.willSync) {
- return;
+ /*
+ `hasData` for a relationship is a flag to indicate if we consider the
+ content of this relationship "known". Snapshots uses this to tell the
+ difference between unknown (`undefined`) or empty (`null`). The reason for
+ this is that we wouldn't want to serialize unknown relationships as `null`
+ as that might overwrite remote state.
+ All relationships for a newly created (`store.createRecord()`) are
+ considered known (`hasData === true`).
+ */
+ }, {
+ key: "setHasData",
+ value: function setHasData(value) {
+ this.hasData = value;
}
- this.willSync = true;
- this.store._backburner.join(function () {
- return _this3.store._backburner.schedule('syncRelationships', _this3, _this3.flushCanonical);
- });
- },
- updateLink: function (link) {
-
- this.link = link;
- this.linkPromise = null;
- this.record.notifyPropertyChange(this.key);
- },
-
- findLink: function () {
- if (this.linkPromise) {
- return this.linkPromise;
- } else {
- var promise = this.fetchLink();
- this.linkPromise = promise;
- return promise.then(function (result) {
- return result;
- });
+ /*
+ `hasLoaded` is a flag to indicate if we have gotten data from the adapter or
+ not when the relationship has a link.
+ This is used to be able to tell when to fetch the link and when to return
+ the local data in scenarios where the local state is considered known
+ (`hasData === true`).
+ Updating the link will automatically set `hasLoaded` to `false`.
+ */
+ }, {
+ key: "setHasLoaded",
+ value: function setHasLoaded(value) {
+ this.hasLoaded = value;
}
- },
- updateRecordsFromAdapter: function (records) {
- //TODO(Igor) move this to a proper place
- //TODO Once we have adapter support, we need to handle updated and canonical changes
- this.computeChanges(records);
- },
+ /*
+ `push` for a relationship allows the store to push a JSON API Relationship
+ Object onto the relationship. The relationship will then extract and set the
+ meta, data and links of that relationship.
+ `push` use `updateMeta`, `updateData` and `updateLink` to update the state
+ of the relationship.
+ */
+ }, {
+ key: "push",
+ value: function push(payload) {
- notifyRecordRelationshipAdded: function () {},
- notifyRecordRelationshipRemoved: function () {},
+ var hasData = false;
+ var hasLink = false;
- /*
- `hasData` for a relationship is a flag to indicate if we consider the
- content of this relationship "known". Snapshots uses this to tell the
- difference between unknown (`undefined`) or empty (`null`). The reason for
- this is that we wouldn't want to serialize unknown relationships as `null`
- as that might overwrite remote state.
- All relationships for a newly created (`store.createRecord()`) are
- considered known (`hasData === true`).
- */
- setHasData: function (value) {
- this.hasData = value;
- },
+ if (payload.meta) {
+ this.updateMeta(payload.meta);
+ }
- /*
- `hasLoaded` is a flag to indicate if we have gotten data from the adapter or
- not when the relationship has a link.
- This is used to be able to tell when to fetch the link and when to return
- the local data in scenarios where the local state is considered known
- (`hasData === true`).
- Updating the link will automatically set `hasLoaded` to `false`.
- */
- setHasLoaded: function (value) {
- this.hasLoaded = value;
- },
+ if (payload.data !== undefined) {
+ hasData = true;
+ this.updateData(payload.data);
+ }
- /*
- `push` for a relationship allows the store to push a JSON API Relationship
- Object onto the relationship. The relationship will then extract and set the
- meta, data and links of that relationship.
- `push` use `updateMeta`, `updateData` and `updateLink` to update the state
- of the relationship.
- */
- push: function (payload) {
+ if (payload.links && payload.links.related) {
+ var relatedLink = (0, _emberDataPrivateSystemNormalizeLink.default)(payload.links.related);
+ if (relatedLink && relatedLink.href && relatedLink.href !== this.link) {
+ hasLink = true;
+ this.updateLink(relatedLink.href);
+ }
+ }
- var hasData = false;
- var hasLink = false;
-
- if (payload.meta) {
- this.updateMeta(payload.meta);
+ /*
+ Data being pushed into the relationship might contain only data or links,
+ or a combination of both.
+ If we got data we want to set both hasData and hasLoaded to true since
+ this would indicate that we should prefer the local state instead of
+ trying to fetch the link or call findRecord().
+ If we have no data but a link is present we want to set hasLoaded to false
+ without modifying the hasData flag. This will ensure we fetch the updated
+ link next time the relationship is accessed.
+ */
+ if (hasData) {
+ this.setHasData(true);
+ this.setHasLoaded(true);
+ } else if (hasLink) {
+ this.setHasLoaded(false);
+ }
}
-
- if (payload.data !== undefined) {
- hasData = true;
- this.updateData(payload.data);
+ }, {
+ key: "updateData",
+ value: function updateData() {}
+ }, {
+ key: "record",
+ get: function () {
+ return this.internalModel;
}
-
- if (payload.links && payload.links.related) {
- var relatedLink = (0, _emberDataPrivateSystemNormalizeLink.default)(payload.links.related);
- if (relatedLink && relatedLink.href && relatedLink.href !== this.link) {
- hasLink = true;
- this.updateLink(relatedLink.href);
- }
+ }, {
+ key: "parentType",
+ get: function () {
+ return this.internalModel.modelName;
}
+ }]);
- /*
- Data being pushed into the relationship might contain only data or links,
- or a combination of both.
- If we got data we want to set both hasData and hasLoaded to true since
- this would indicate that we should prefer the local state instead of
- trying to fetch the link or call findRecord().
- If we have no data but a link is present we want to set hasLoaded to false
- without modifying the hasData flag. This will ensure we fetch the updated
- link next time the relationship is accessed.
- */
- if (hasData) {
- this.setHasData(true);
- this.setHasLoaded(true);
- } else if (hasLink) {
- this.setHasLoaded(false);
- }
- },
+ return Relationship;
+ })();
- updateData: function () {}
- };
+ exports.default = Relationship;
});
/* global heimdall */
define('ember-data/-private/system/snapshot-record-array', ['exports'], function (exports) {
exports.default = SnapshotRecordArray;
/**
@@ -8384,40 +8978,112 @@
@private
@property _recordArray
@type {Array}
*/
this._recordArray = recordArray;
+
/**
Number of records in the array
- @property length
+ Example
+ ```app/adapters/post.js
+ import DS from 'ember-data'
+ export default DS.JSONAPIAdapter.extend({
+ shouldReloadAll(store, snapshotRecordArray) {
+ return !snapshotRecordArray.length;
+ },
+ });
+ ```
+ @property length
@type {Number}
*/
this.length = recordArray.get('length');
+
/**
The type of the underlying records for the snapshots in the array, as a DS.Model
@property type
@type {DS.Model}
*/
this.type = recordArray.get('type');
+
/**
- Meta object
- @property meta
+ Meta objects for the record array.
+ Example
+ ```app/adapters/post.js
+ import DS from 'ember-data'
+ export default DS.JSONAPIAdapter.extend({
+ shouldReloadAll(store, snapshotRecordArray) {
+ var lastRequestTime = snapshotRecordArray.meta.lastRequestTime;
+ var twentyMinutes = 20 * 60 * 1000;
+ return Date.now() > lastRequestTime + twentyMinutes;
+ },
+ });
+ ```
+ @property meta
@type {Object}
*/
this.meta = meta;
+
/**
- A hash of adapter options
- @property adapterOptions
+ A hash of adapter options passed into the store method for this request.
+ Example
+ ```app/adapters/post.js
+ import MyCustomAdapter from './custom-adapter';
+ export default MyCustomAdapter.extend({
+ findAll(store, type, sinceToken, snapshotRecordArray) {
+ if (snapshotRecordArray.adapterOptions.subscribe) {
+ // ...
+ }
+ // ...
+ }
+ });
+ ```
+ @property adapterOptions
@type {Object}
*/
this.adapterOptions = options.adapterOptions;
+ /**
+ The relationships to include for this request.
+ Example
+ ```app/adapters/application.js
+ import DS from 'ember-data';
+ export default DS.Adapter.extend({
+ findAll(store, type, snapshotRecordArray) {
+ var url = `/${type.modelName}?include=${encodeURIComponent(snapshotRecordArray.include)}`;
+ return fetch(url).then((response) => response.json())
+ }
+ });
+ @property include
+ @type {String|Array}
+ */
this.include = options.include;
}
/**
Get snapshots of the underlying record array
+
+ Example
+
+ ```app/adapters/post.js
+ import DS from 'ember-data'
+
+ export default DS.JSONAPIAdapter.extend({
+ shouldReloadAll(store, snapshotArray) {
+ var snapshots = snapshotArray.snapshots();
+
+ return snapshots.any(function(ticketSnapshot) {
+ var timeDiff = moment().diff(ticketSnapshot.attr('lastAccessedAt'), 'minutes');
+ if (timeDiff > 20) {
+ return true;
+ } else {
+ return false;
+ }
+ });
+ }
+ });
+ ```
+
@method snapshots
@return {Array} Array of snapshots
*/
SnapshotRecordArray.prototype.snapshots = function () {
if (this._snapshots !== null) {
@@ -8740,11 +9406,26 @@
eachRelationship: function (callback, binding) {
this.record.eachRelationship(callback, binding);
},
/**
- @method serialize
+ Serializes the snapshot using the serializer for the model.
+ Example
+ ```app/adapters/application.js
+ import DS from 'ember-data';
+ export default DS.Adapter.extend({
+ createRecord(store, type, snapshot) {
+ var data = snapshot.serialize({ includeId: true });
+ var url = `/${type.modelName}`;
+ return fetch(url, {
+ method: 'POST',
+ body: data,
+ }).then((response) => response.json())
+ }
+ });
+ ```
+ @method serialize
@param {Object} options
@return {Object} an object whose values are primitive JSON values only
*/
serialize: function (options) {
return this.record.store.serializerFor(this.modelName).serialize(this, options);
@@ -8752,22 +9433,21 @@
};
});
/**
@module ember-data
*/
-define('ember-data/-private/system/store', ['exports', 'ember', 'ember-data/model', 'ember-data/-private/debug', 'ember-data/-private/system/normalize-model-name', 'ember-data/adapters/errors', 'ember-data/-private/system/promise-proxies', 'ember-data/-private/system/store/common', 'ember-data/-private/system/store/serializer-response', 'ember-data/-private/system/store/serializers', 'ember-data/-private/system/store/finders', 'ember-data/-private/utils', 'ember-data/-private/system/coerce-id', 'ember-data/-private/system/record-array-manager', 'ember-data/-private/system/store/container-instance-cache', 'ember-data/-private/system/model/internal-model', 'ember-data/-private/system/empty-object', 'ember-data/-private/features'], function (exports, _ember, _emberDataModel, _emberDataPrivateDebug, _emberDataPrivateSystemNormalizeModelName, _emberDataAdaptersErrors, _emberDataPrivateSystemPromiseProxies, _emberDataPrivateSystemStoreCommon, _emberDataPrivateSystemStoreSerializerResponse, _emberDataPrivateSystemStoreSerializers, _emberDataPrivateSystemStoreFinders, _emberDataPrivateUtils, _emberDataPrivateSystemCoerceId, _emberDataPrivateSystemRecordArrayManager, _emberDataPrivateSystemStoreContainerInstanceCache, _emberDataPrivateSystemModelInternalModel, _emberDataPrivateSystemEmptyObject, _emberDataPrivateFeatures) {
+define('ember-data/-private/system/store', ['exports', 'ember', 'ember-data/model', 'ember-data/-private/debug', 'ember-data/-private/system/normalize-model-name', 'ember-data/adapters/errors', 'ember-data/-private/system/identity-map', 'ember-data/-private/system/promise-proxies', 'ember-data/-private/system/store/common', 'ember-data/-private/system/store/serializer-response', 'ember-data/-private/system/store/serializers', 'ember-data/-private/system/store/finders', 'ember-data/-private/utils', 'ember-data/-private/system/coerce-id', 'ember-data/-private/system/record-array-manager', 'ember-data/-private/system/store/container-instance-cache', 'ember-data/-private/system/model/internal-model', 'ember-data/-private/system/empty-object', 'ember-data/-private/features'], function (exports, _ember, _emberDataModel, _emberDataPrivateDebug, _emberDataPrivateSystemNormalizeModelName, _emberDataAdaptersErrors, _emberDataPrivateSystemIdentityMap, _emberDataPrivateSystemPromiseProxies, _emberDataPrivateSystemStoreCommon, _emberDataPrivateSystemStoreSerializerResponse, _emberDataPrivateSystemStoreSerializers, _emberDataPrivateSystemStoreFinders, _emberDataPrivateUtils, _emberDataPrivateSystemCoerceId, _emberDataPrivateSystemRecordArrayManager, _emberDataPrivateSystemStoreContainerInstanceCache, _emberDataPrivateSystemModelInternalModel, _emberDataPrivateSystemEmptyObject, _emberDataPrivateFeatures) {
var badIdFormatAssertion = '`id` passed to `findRecord()` has to be non-empty string or number';
exports.badIdFormatAssertion = badIdFormatAssertion;
var A = _ember.default.A;
var Backburner = _ember.default._Backburner;
var computed = _ember.default.computed;
var copy = _ember.default.copy;
var ENV = _ember.default.ENV;
var EmberError = _ember.default.Error;
var get = _ember.default.get;
- var guidFor = _ember.default.guidFor;
var inspect = _ember.default.inspect;
var isNone = _ember.default.isNone;
var isPresent = _ember.default.isPresent;
var MapWithDefault = _ember.default.MapWithDefault;
var emberRun = _ember.default.run;
@@ -8886,22 +9566,36 @@
*/
init: function () {
this._super.apply(this, arguments);
this._backburner = new Backburner(['normalizeRelationships', 'syncRelationships', 'finished']);
// internal bookkeeping; not observable
- this.typeMaps = {};
this.recordArrayManager = _emberDataPrivateSystemRecordArrayManager.default.create({
store: this
});
+ this._identityMap = new _emberDataPrivateSystemIdentityMap.default();
this._pendingSave = [];
- this._modelClassCache = new _emberDataPrivateSystemEmptyObject.default();
this._instanceCache = new _emberDataPrivateSystemStoreContainerInstanceCache.default((0, _emberDataPrivateUtils.getOwner)(this), this);
+ this._modelClassCache = new _emberDataPrivateSystemEmptyObject.default();
- //Used to keep track of all the find requests that need to be coalesced
+ /*
+ Ember Data uses several specialized micro-queues for organizing
+ and coalescing similar async work.
+ These queues are currently controlled by a flush scheduled into
+ ember-data's custom backburner instance.
+ */
+ // used for coalescing record save requests
+ this._pendingSave = [];
+ // used for coalescing relationship setup needs
+ this._pushedInternalModels = [];
+ // stores a reference to the flush for relationship setup
+ this._relationshipFlush = null;
+ // used to keep track of all the find requests that need to be coalesced
this._pendingFetch = MapWithDefault.create({ defaultValue: function () {
return [];
} });
+
+ this._instanceCache = new _emberDataPrivateSystemStoreContainerInstanceCache.default((0, _emberDataPrivateUtils.getOwner)(this), this);
},
/**
The default adapter to use to communicate to a backend server or
other persistence layer. This will be overridden by an application
@@ -8981,26 +9675,26 @@
@param {Object} inputProperties a hash of properties to set on the
newly created record.
@return {DS.Model} record
*/
createRecord: function (modelName, inputProperties) {
- var modelClass = this.modelFor(modelName);
+ var trueModelName = this._classKeyFor(modelName);
var properties = copy(inputProperties) || new _emberDataPrivateSystemEmptyObject.default();
// If the passed properties do not include a primary key,
// give the adapter an opportunity to generate one. Typically,
// client-side ID generators will use something like uuid.js
// to avoid conflicts.
if (isNone(properties.id)) {
- properties.id = this._generateId(modelName, properties);
+ properties.id = this._generateId(trueModelName, properties);
}
// Coerce ID to a string
properties.id = (0, _emberDataPrivateSystemCoerceId.default)(properties.id);
- var internalModel = this.buildInternalModel(modelClass, properties.id);
+ var internalModel = this.buildInternalModel(trueModelName, properties.id);
var record = internalModel.getRecord();
// Move the record out of its initial `empty` state into
// the `loaded` state.
// TODO @runspired this seems really bad, store should not be changing the state
@@ -9088,17 +9782,13 @@
find: function (modelName, id, options) {
// The default `model` hook in Ember.Route calls `find(modelName, id)`,
// that's why we have to keep this method around even though `findRecord` is
// the public way to get a record by modelName and id.
- if (arguments.length === 1) {}
+ var trueModelName = this._classKeyFor(modelName);
- if (typeOf(id) === 'object') {}
-
- if (options) {}
-
- return this.findRecord(modelName, id);
+ return this.findRecord(trueModelName, id);
},
/**
This method returns a record for a given type and id combination.
The `findRecord` method will always resolve its promise with the same
@@ -9257,20 +9947,22 @@
@param {Object} options
@return {Promise} promise
*/
findRecord: function (modelName, id, options) {
- var internalModel = this._internalModelForId(modelName, id);
+ var trueModelName = this._classKeyFor(modelName);
+
+ var internalModel = this._internalModelForId(trueModelName, id);
options = options || {};
- if (!this.hasRecordForId(modelName, id)) {
+ if (!this.hasRecordForId(trueModelName, id)) {
return this._findByInternalModel(internalModel, options);
}
var fetchedInternalModel = this._findRecord(internalModel, options);
- return promiseRecord(fetchedInternalModel, "DS: Store#findRecord " + internalModel.typeKey + " with id: " + get(internalModel, 'id'));
+ return promiseRecord(fetchedInternalModel, 'DS: Store#findRecord ' + trueModelName + ' with id: ' + id);
},
_findRecord: function (internalModel, options) {
// Refetch if the reload option is passed
if (options.reload) {
@@ -9334,15 +10026,17 @@
@return {Promise} promise
*/
findByIds: function (modelName, ids) {
var promises = new Array(ids.length);
+ var trueModelName = this._classKeyFor(modelName);
+
for (var i = 0; i < ids.length; i++) {
- promises[i] = this.findRecord(modelName, ids[i]);
+ promises[i] = this.findRecord(trueModelName, ids[i]);
}
- return (0, _emberDataPrivateSystemPromiseProxies.promiseArray)(RSVP.all(promises).then(A, null, "DS: Store#findByIds of " + modelName + " complete"));
+ return (0, _emberDataPrivateSystemPromiseProxies.promiseArray)(RSVP.all(promises).then(A, null, 'DS: Store#findByIds of ' + trueModelName + ' complete'));
},
/**
This method is called by `findRecord` if it discovers that a particular
type/id pair hasn't been loaded yet to kick off a request to the
@@ -9536,17 +10230,19 @@
userRef.push({ id: 1, username: "@user" }).then(function(user) {
userRef.value() === user;
});
```
@method getReference
- @param {String} type
+ @param {String} modelName
@param {String|Integer} id
@since 2.5.0
@return {RecordReference}
*/
- getReference: function (type, id) {
- return this._internalModelForId(type, id).recordReference;
+ getReference: function (modelName, id) {
+ var trueModelName = this._classKeyFor(modelName);
+
+ return this._internalModelForId(trueModelName, id).recordReference;
},
/**
Get a record by a given type and ID without triggering a fetch.
This method will synchronously return the record if it is available in the store,
@@ -9562,12 +10258,14 @@
@param {String} modelName
@param {String|Integer} id
@return {DS.Model|null} record
*/
peekRecord: function (modelName, id) {
- if (this.hasRecordForId(modelName, id)) {
- return this._internalModelForId(modelName, id).getRecord();
+ var trueModelName = this._classKeyFor(modelName);
+
+ if (this.hasRecordForId(trueModelName, id)) {
+ return this._internalModelForId(trueModelName, id).getRecord();
} else {
return null;
}
},
@@ -9579,12 +10277,11 @@
@method reloadRecord
@private
@param {DS.Model} internalModel
@return {Promise} promise
*/
- // TODO @runspired this should be underscored
- reloadRecord: function (internalModel) {
+ _reloadRecord: function (internalModel) {
var modelName = internalModel.type.modelName;
var adapter = this.adapterFor(modelName);
var id = internalModel.id;
return this._scheduleFetch(internalModel);
@@ -9605,14 +10302,14 @@
@param {String} modelName
@param {(String|Integer)} id
@return {Boolean}
*/
hasRecordForId: function (modelName, id) {
+ var trueModelName = this._classKeyFor(modelName);
var trueId = (0, _emberDataPrivateSystemCoerceId.default)(id);
- var modelClass = this.modelFor(modelName);
- var internalModel = this.typeMapFor(modelClass).idToRecord[trueId];
+ var internalModel = this._recordMapFor(trueModelName).get(trueId);
return !!internalModel && internalModel.isLoaded();
},
/**
@@ -9626,18 +10323,16 @@
*/
recordForId: function (modelName, id) {
return this._internalModelForId(modelName, id).getRecord();
},
- _internalModelForId: function (modelName, inputId) {
- var modelClass = this.modelFor(modelName);
- var id = (0, _emberDataPrivateSystemCoerceId.default)(inputId);
- var idToRecord = this.typeMapFor(modelClass).idToRecord;
- var internalModel = idToRecord[id];
+ _internalModelForId: function (modelName, id) {
+ var trueId = (0, _emberDataPrivateSystemCoerceId.default)(id);
+ var internalModel = this._recordMapFor(modelName).get(trueId);
- if (!internalModel || !idToRecord[id]) {
- internalModel = this.buildInternalModel(modelClass, id);
+ if (!internalModel) {
+ internalModel = this.buildInternalModel(modelName, trueId);
}
return internalModel;
},
@@ -9728,17 +10423,19 @@
@param {String} modelName
@param {any} query an opaque query to be used by the adapter
@return {Promise} promise
*/
query: function (modelName, query) {
- return this._query(modelName, query);
+
+ var trueModelName = this._classKeyFor(modelName);
+ return this._query(trueModelName, query);
},
_query: function (modelName, query, array) {
- var modelClass = this.modelFor(modelName);
+ var modelClass = this._modelFor(modelName);
- array = array || this.recordArrayManager.createAdapterPopulatedRecordArray(modelClass, query);
+ array = array || this.recordArrayManager.createAdapterPopulatedRecordArray(modelName, query);
var adapter = this.adapterFor(modelName);
var pA = (0, _emberDataPrivateSystemPromiseProxies.promiseArray)((0, _emberDataPrivateSystemStoreFinders._query)(adapter, this, modelClass, query, array));
@@ -9821,13 +10518,14 @@
@param {String} modelName
@param {any} query an opaque query to be used by the adapter
@return {Promise} promise which resolves with the found record or `null`
*/
queryRecord: function (modelName, query) {
+ var trueModelName = this._classKeyFor(modelName);
- var modelClass = this.modelFor(modelName);
- var adapter = this.adapterFor(modelName);
+ var modelClass = this._modelFor(trueModelName);
+ var adapter = this.adapterFor(trueModelName);
return (0, _emberDataPrivateSystemPromiseProxies.promiseObject)((0, _emberDataPrivateSystemStoreFinders._queryRecord)(adapter, this, modelClass, query).then(function (internalModel) {
// the promise returned by store.queryRecord is expected to resolve with
// an instance of DS.Model
if (internalModel) {
@@ -9946,11 +10644,11 @@
}
// ...
}
});
```
- See [peekAll](#method_peekAll) to get an array of current records in the
+ See [peekAll](#method_peekAll) to get an array of current records in the
store, without waiting until a reload is finished.
### Retrieving Related Model Records
If you use an adapter such as Ember's default
[`JSONAPIAdapter`](http://emberjs.com/api/data/classes/DS.JSONAPIAdapter.html)
that supports the [JSON API specification](http://jsonapi.org/) and if your server
@@ -9987,14 +10685,14 @@
@param {String} modelName
@param {Object} options
@return {Promise} promise
*/
findAll: function (modelName, options) {
- var modelClass = this.modelFor(modelName);
+ var trueModelName = this._classKeyFor(modelName);
+ var modelClass = this._modelFor(trueModelName);
+ var fetch = this._fetchAll(modelClass, this.peekAll(trueModelName), options);
- var fetch = this._fetchAll(modelClass, this.peekAll(modelName), options);
-
return fetch;
},
/**
@method _fetchAll
@@ -10004,12 +10702,13 @@
@return {Promise} promise
*/
_fetchAll: function (modelClass, array, options) {
options = options || {};
- var adapter = this.adapterFor(modelClass.modelName);
- var sinceToken = this.typeMapFor(modelClass).metadata.since;
+ var modelName = modelClass.modelName;
+ var adapter = this.adapterFor(modelName);
+ var sinceToken = this._recordMapFor(modelName).metadata.since;
if (options.reload) {
set(array, 'isUpdating', true);
return (0, _emberDataPrivateSystemPromiseProxies.promiseArray)((0, _emberDataPrivateSystemStoreFinders._findAll)(adapter, this, modelClass, sinceToken, options));
}
@@ -10033,15 +10732,15 @@
return (0, _emberDataPrivateSystemPromiseProxies.promiseArray)(Promise.resolve(array));
},
/**
@method didUpdateAll
- @param {DS.Model} modelClass
+ @param {String} modelName
@private
*/
- didUpdateAll: function (modelClass) {
- var liveRecordArray = this.recordArrayManager.liveRecordArrayFor(modelClass);
+ didUpdateAll: function (modelName) {
+ var liveRecordArray = this.recordArrayManager.liveRecordArrayFor(modelName);
set(liveRecordArray, 'isUpdating', false);
},
/**
@@ -10062,14 +10761,14 @@
@method peekAll
@param {String} modelName
@return {DS.RecordArray}
*/
peekAll: function (modelName) {
- var modelClass = this.modelFor(modelName);
- var liveRecordArray = this.recordArrayManager.liveRecordArrayFor(modelClass);
+ var trueModelName = this._classKeyFor(modelName);
+ var liveRecordArray = this.recordArrayManager.liveRecordArrayFor(trueModelName);
- this.recordArrayManager.syncLiveRecordArray(liveRecordArray, modelClass);
+ this.recordArrayManager.syncLiveRecordArray(liveRecordArray, trueModelName);
return liveRecordArray;
},
/**
@@ -10084,32 +10783,14 @@
@param {String} modelName
*/
unloadAll: function (modelName) {
if (arguments.length === 0) {
- var typeMaps = this.typeMaps;
- var keys = Object.keys(typeMaps);
- var types = new Array(keys.length);
-
- for (var i = 0; i < keys.length; i++) {
- types[i] = typeMaps[keys[i]]['type'].modelName;
- }
-
- types.forEach(this.unloadAll, this);
+ this._identityMap.clear();
} else {
- var modelClass = this.modelFor(modelName);
- var typeMap = this.typeMapFor(modelClass);
- var records = typeMap.records.slice();
- var record = undefined;
-
- for (var i = 0; i < records.length; i++) {
- record = records[i];
- record.unloadRecord();
- record.destroy(); // maybe within unloadRecord
- }
-
- typeMap.metadata = new _emberDataPrivateSystemEmptyObject.default();
+ var trueModelName = this._classKeyFor(modelName);
+ this._recordMapFor(trueModelName).clear();
}
},
/**
Takes a type and filter function, and returns a live RecordArray that
@@ -10162,30 +10843,30 @@
var promise = undefined;
var length = arguments.length;
var array = undefined;
var hasQuery = length === 3;
+ var trueModelName = this._classKeyFor(modelName);
+
// allow an optional server query
if (hasQuery) {
- promise = this.query(modelName, query);
+ promise = this.query(trueModelName, query);
} else if (arguments.length === 2) {
filter = query;
}
- modelName = this.modelFor(modelName);
-
if (hasQuery) {
- array = this.recordArrayManager.createFilteredRecordArray(modelName, filter, query);
+ array = this.recordArrayManager.createFilteredRecordArray(trueModelName, filter, query);
} else {
- array = this.recordArrayManager.createFilteredRecordArray(modelName, filter);
+ array = this.recordArrayManager.createFilteredRecordArray(trueModelName, filter);
}
promise = promise || Promise.resolve(array);
return (0, _emberDataPrivateSystemPromiseProxies.promiseArray)(promise.then(function () {
return array;
- }, null, 'DS: Store#filter of ' + modelName));
+ }, null, 'DS: Store#filter of ' + trueModelName));
},
/**
This method has been deprecated and is an alias for store.hasRecordForId, which should
be used instead.
@@ -10206,16 +10887,15 @@
/**
If the adapter updates attributes the record will notify
the store to update its membership in any filters.
To avoid thrashing, this method is invoked only once per
run loop per record.
- @method dataWasUpdated
+ @method _dataWasUpdated
@private
- @param {Class} type
@param {InternalModel} internalModel
*/
- dataWasUpdated: function (type, internalModel) {
+ _dataWasUpdated: function (internalModel) {
this.recordArrayManager.recordDidChange(internalModel);
},
// ..............
// . PERSISTING .
@@ -10247,34 +10927,33 @@
flushes any records passed into `scheduleSave`
@method flushPendingSave
@private
*/
flushPendingSave: function () {
- var _this = this;
-
var pending = this._pendingSave.slice();
this._pendingSave = [];
- pending.forEach(function (pendingItem) {
+ for (var i = 0, j = pending.length; i < j; i++) {
+ var pendingItem = pending[i];
var snapshot = pendingItem.snapshot;
var resolver = pendingItem.resolver;
- var record = snapshot._internalModel;
- var adapter = _this.adapterFor(record.modelClass.modelName);
+ var internalModel = snapshot._internalModel;
+ var adapter = this.adapterFor(internalModel.modelClass.modelName);
var operation = undefined;
- if (get(record, 'currentState.stateName') === 'root.deleted.saved') {
+ if (get(internalModel, 'currentState.stateName') === 'root.deleted.saved') {
return resolver.resolve();
- } else if (record.isNew()) {
+ } else if (internalModel.isNew()) {
operation = 'createRecord';
- } else if (record.isDeleted()) {
+ } else if (internalModel.isDeleted()) {
operation = 'deleteRecord';
} else {
operation = 'updateRecord';
}
- resolver.resolve(_commit(adapter, _this, operation, snapshot));
- });
+ resolver.resolve(_commit(adapter, this, operation, snapshot));
+ }
},
/**
This method is called once the promise returned by an
adapter's `createRecord`, `updateRecord` or `deleteRecord`
@@ -10291,12 +10970,12 @@
if (dataArg) {
data = dataArg.data;
}
if (data) {
// normalize relationship IDs into records
- this._backburner.schedule('normalizeRelationships', this, this._setupRelationships, internalModel, data);
this.updateId(internalModel, data);
+ this._setupRelationshipsForModel(internalModel, data);
} else {}
//We first make sure the primary data has been updated
//TODO try to move notification to the user to the end of the runloop
internalModel.adapterDidCommit(data);
@@ -10349,57 +11028,52 @@
// however, this is more than likely a developer error.
if (oldId !== null && id === null) {
return;
}
- this.typeMapFor(internalModel.type).idToRecord[id] = internalModel;
+ this._recordMapFor(internalModel.modelName).set(id, internalModel);
internalModel.setId(id);
},
/**
- Returns a map of IDs to client IDs for a given type.
- @method typeMapFor
+ Returns the normalized (dasherized) modelName. This method should be used whenever
+ receiving a modelName in a public method.
+ @method _classKeyFor
+ @param {String} modelName
+ @returns {String}
+ @private
+ */
+ _classKeyFor: function (modelName) {
+ return (0, _emberDataPrivateSystemNormalizeModelName.default)(modelName);
+ },
+
+ /**
+ Returns a map of IDs to client IDs for a given modelName.
+ @method _recordMapFor
@private
- @param {DS.Model} modelClass
- @return {Object} typeMap
+ @param {String} modelName
+ @return {Object} recordMap
*/
- typeMapFor: function (modelClass) {
- var typeMaps = get(this, 'typeMaps');
- var guid = guidFor(modelClass);
- var typeMap = typeMaps[guid];
-
- if (typeMap) {
- return typeMap;
- }
-
- typeMap = {
- idToRecord: new _emberDataPrivateSystemEmptyObject.default(),
- records: [],
- metadata: new _emberDataPrivateSystemEmptyObject.default(),
- type: modelClass
- };
-
- typeMaps[guid] = typeMap;
-
- return typeMap;
+ _recordMapFor: function (modelName) {
+ return this._identityMap.retrieve(modelName);
},
// ................
// . LOADING DATA .
// ................
/**
This internal method is used by `push`.
@method _load
@private
- @param {(String|DS.Model)} type
@param {Object} data
*/
_load: function (data) {
var internalModel = this._internalModelForId(data.type, data.id);
+ // TODO @runspired move this out of here
internalModel.setupData(data);
this.recordArrayManager.recordDidChange(internalModel);
return internalModel;
@@ -10417,39 +11091,31 @@
```
we want to look up a Commentable class which has all the necessary
relationship metadata. Thus, we look up the mixin and create a mock
DS.Model, so we can access the relationship CPs of the mixin (`comments`)
in this case
+ @private
*/
-
_modelForMixin: function (modelName) {
var normalizedModelName = (0, _emberDataPrivateSystemNormalizeModelName.default)(modelName);
// container.registry = 2.1
// container._registry = 1.11 - 2.0
// container = < 1.11
var owner = (0, _emberDataPrivateUtils.getOwner)(this);
- var mixin = undefined;
- if (owner.factoryFor) {
- var MaybeMixin = owner.factoryFor('mixin:' + normalizedModelName);
- mixin = MaybeMixin && MaybeMixin.class;
- } else {
- mixin = owner._lookupFactory('mixin:' + normalizedModelName);
- }
-
+ var mixin = owner._lookupFactory('mixin:' + normalizedModelName);
if (mixin) {
- var ModelForMixin = _emberDataModel.default.extend(mixin);
- ModelForMixin.reopenClass({
- __isMixin: true,
- __mixin: mixin
- });
-
//Cache the class as a model
- owner.register('model:' + normalizedModelName, ModelForMixin);
+ owner.register('model:' + normalizedModelName, _emberDataModel.default.extend(mixin));
}
+ var factory = this.modelFactoryFor(normalizedModelName);
+ if (factory) {
+ factory.__isMixin = true;
+ factory.__mixin = mixin;
+ }
- return this.modelFactoryFor(normalizedModelName);
+ return factory;
},
/**
Returns the model class for the particular `modelName`.
The class of a model might be useful if you want to get a list of all the
@@ -10460,33 +11126,19 @@
@param {String} modelName
@return {DS.Model}
*/
modelFor: function (modelName) {
- var normalizedModelName = (0, _emberDataPrivateSystemNormalizeModelName.default)(modelName);
- var factory = this.modelFactoryFor(normalizedModelName);
- if (!factory) {
- //Support looking up mixins as base types for polymorphic relationships
- factory = this._modelForMixin(normalizedModelName);
- }
- if (!factory) {
- throw new EmberError("No model was found for '" + normalizedModelName + "'");
- }
+ var trueModelName = this._classKeyFor(modelName);
- return this._modelFor(normalizedModelName);
+ return this._modelFor(trueModelName);
},
/*
@private
*/
_modelFor: function (modelName) {
- var maybeFactory = this._modelFactoryFor(modelName);
- // for factorFor factory/class split
- return maybeFactory.class ? maybeFactory.class : maybeFactory;
- },
-
- _modelFactoryFor: function (modelName) {
var factory = this._modelClassCache[modelName];
if (!factory) {
factory = this.modelFactoryFor(modelName);
@@ -10496,31 +11148,26 @@
}
if (!factory) {
throw new EmberError('No model was found for \'' + modelName + '\'');
}
- // interopt with the future
- var klass = (0, _emberDataPrivateUtils.getOwner)(this).factoryFor ? factory.class : factory;
+ factory.modelName = factory.modelName || modelName;
- // TODO: deprecate this
- klass.modelName = klass.modelName || modelName;
-
this._modelClassCache[modelName] = factory;
}
return factory;
},
+ /*
+ @private
+ */
modelFactoryFor: function (modelName) {
- var trueModelName = (0, _emberDataPrivateSystemNormalizeModelName.default)(modelName);
+ var trueModelName = this._classKeyFor(modelName);
var owner = (0, _emberDataPrivateUtils.getOwner)(this);
- if (owner.factoryFor) {
- return owner.factoryFor('model:' + trueModelName);
- } else {
- return owner._lookupFactory('model:' + trueModelName);
- }
+ return owner._lookupFactory('model:' + trueModelName);
},
/**
Push some data for a given type into the store.
This method expects normalized [JSON API](http://jsonapi.org/) document. This means you have to follow [JSON API specification](http://jsonapi.org/format/) with few minor adjustments:
@@ -10669,79 +11316,88 @@
return record;
},
/*
- Push some data into the store, without creating materialized records.
+ Push some data in the form of a json-api document into the store,
+ without creating materialized records.
@method _push
@private
- @param {Object} data
+ @param {Object} jsonApiDoc
@return {DS.InternalModel|Array<DS.InternalModel>} pushed InternalModel(s)
*/
- _push: function (data) {
- var included = data.included;
- var i = undefined,
- length = undefined;
+ _push: function (jsonApiDoc) {
+ var _this = this;
- if (included) {
- for (i = 0, length = included.length; i < length; i++) {
- this._pushInternalModel(included[i]);
+ var internalModelOrModels = this._backburner.join(function () {
+ var included = jsonApiDoc.included;
+ var i = undefined,
+ length = undefined;
+
+ if (included) {
+ for (i = 0, length = included.length; i < length; i++) {
+ _this._pushInternalModel(included[i]);
+ }
}
- }
- if (Array.isArray(data.data)) {
- length = data.data.length;
- var internalModels = new Array(length);
+ if (Array.isArray(jsonApiDoc.data)) {
+ length = jsonApiDoc.data.length;
+ var internalModels = new Array(length);
- for (i = 0; i < length; i++) {
- internalModels[i] = this._pushInternalModel(data.data[i]);
+ for (i = 0; i < length; i++) {
+ internalModels[i] = _this._pushInternalModel(jsonApiDoc.data[i]);
+ }
+ return internalModels;
}
- return internalModels;
- }
+ if (jsonApiDoc.data === null) {
+ return null;
+ }
- if (data.data === null) {
- return null;
- }
+ return _this._pushInternalModel(jsonApiDoc.data);
+ });
- var internalModel = this._pushInternalModel(data.data);
-
- return internalModel;
+ return internalModelOrModels;
},
_hasModelFor: function (modelName) {
- var owner = (0, _emberDataPrivateUtils.getOwner)(this);
-
- if (owner.factoryFor) {
- return !!owner.factoryFor('model:' + modelName);
- } else {
- return !!owner._lookupFactory('model:' + modelName);
- }
+ return !!(0, _emberDataPrivateUtils.getOwner)(this)._lookupFactory('model:' + modelName);
},
_pushInternalModel: function (data) {
- var _this2 = this;
-
var modelName = data.type;
// Actually load the record into the store.
var internalModel = this._load(data);
- this._backburner.join(function () {
- _this2._backburner.schedule('normalizeRelationships', _this2, _this2._setupRelationships, internalModel, data);
- });
+ this._setupRelationshipsForModel(internalModel, data);
return internalModel;
},
- _setupRelationships: function (record, data) {
- // This will convert relationships specified as IDs into DS.Model instances
- // (possibly unloaded) and also create the data structures used to track
- // relationships.
- setupRelationships(this, record, data);
+ _setupRelationshipsForModel: function (internalModel, data) {
+ this._pushedInternalModels.push(internalModel, data);
+ if (this._relationshipFlush === null) {
+ this._relationshipFlush = this._backburner.schedule('normalizeRelationships', this, this._setupRelationships);
+ }
},
+ _setupRelationships: function () {
+ var pushed = this._pushedInternalModels;
+ this._pushedInternalModels = [];
+ this._relationshipFlush = null;
+
+ for (var i = 0, l = pushed.length; i < l; i += 2) {
+ // This will convert relationships specified as IDs into DS.Model instances
+ // (possibly unloaded) and also create the data structures used to track
+ // relationships.
+ var internalModel = pushed[i];
+ var data = pushed[i + 1];
+ setupRelationships(this, internalModel, data);
+ }
+ },
+
/**
Push some raw data into the store.
This method can be used both to push in brand new
records, as well as to update existing records. You
can push in more than one type of object at once.
@@ -10781,30 +11437,25 @@
@method pushPayload
@param {String} modelName Optionally, a model type used to determine which serializer will be used
@param {Object} inputPayload
*/
pushPayload: function (modelName, inputPayload) {
- var _this3 = this;
-
var serializer = undefined;
var payload = undefined;
if (!inputPayload) {
payload = modelName;
serializer = defaultSerializer(this);
} else {
payload = inputPayload;
- serializer = this.serializerFor(modelName);
+ var trueModelName = this._classKeyFor(modelName);
+ serializer = this.serializerFor(trueModelName);
}
if (false) {
- return this._adapterRun(function () {
- return serializer.pushPayload(_this3, payload);
- });
+ return serializer.pushPayload(this, payload);
} else {
- this._adapterRun(function () {
- return serializer.pushPayload(_this3, payload);
- });
+ serializer.pushPayload(this, payload);
}
},
/**
`normalize` converts a json payload into the normalized form that
@@ -10821,41 +11472,36 @@
@param {String} modelName The name of the model type for this payload
@param {Object} payload
@return {Object} The normalized payload
*/
normalize: function (modelName, payload) {
- var serializer = this.serializerFor(modelName);
- var model = this.modelFor(modelName);
+ var trueModelName = this._classKeyFor(modelName);
+ var serializer = this.serializerFor(trueModelName);
+ var model = this._modelFor(trueModelName);
return serializer.normalize(model, payload);
},
/**
Build a brand new record for a given type, ID, and
initial data.
@method buildRecord
@private
- @param {DS.Model} modelClass
+ @param {String} modelName
@param {String} id
@param {Object} data
@return {InternalModel} internal model
*/
- buildInternalModel: function (modelClass, id, data) {
- var typeMap = this.typeMapFor(modelClass);
- var idToRecord = typeMap.idToRecord;
+ buildInternalModel: function (modelName, id, data) {
+ var recordMap = this._recordMapFor(modelName);
+
// lookupFactory should really return an object that creates
// instances with the injections applied
- var internalModel = new _emberDataPrivateSystemModelInternalModel.default(modelClass, id, this, data);
+ var internalModel = new _emberDataPrivateSystemModelInternalModel.default(modelName, id, this, data);
- // if we're creating an item, this process will be done
- // later, once the object has been persisted.
- if (id) {
- idToRecord[id] = internalModel;
- }
+ recordMap.add(internalModel, id);
- typeMap.records.push(internalModel);
-
return internalModel;
},
//Called by the state machine to notify the store that the record is ready to be interacted with
recordWasLoaded: function (record) {
@@ -10872,22 +11518,16 @@
@method _dematerializeRecord
@private
@param {InternalModel} internalModel
*/
_dematerializeRecord: function (internalModel) {
- var modelClass = internalModel.type;
- var typeMap = this.typeMapFor(modelClass);
+ var recordMap = this._recordMapFor(internalModel.modelName);
var id = internalModel.id;
internalModel.updateRecordArrays();
- if (id) {
- delete typeMap.idToRecord[id];
- }
-
- var loc = typeMap.records.indexOf(internalModel);
- typeMap.records.splice(loc, 1);
+ recordMap.remove(internalModel, id);
},
// ......................
// . PER-TYPE ADAPTERS
// ......................
@@ -10905,20 +11545,15 @@
@public
@param {String} modelName
@return DS.Adapter
*/
adapterFor: function (modelName) {
+ var trueModelName = this._classKeyFor(modelName);
- var normalizedModelName = (0, _emberDataPrivateSystemNormalizeModelName.default)(modelName);
-
- return this._instanceCache.get('adapter', normalizedModelName);
+ return this._instanceCache.get('adapter', trueModelName);
},
- _adapterRun: function (fn) {
- return this._backburner.run(fn);
- },
-
// ..............................
// . RECORD CHANGE NOTIFICATION .
// ..............................
/**
@@ -10937,14 +11572,13 @@
@public
@param {String} modelName the record to serialize
@return {DS.Serializer}
*/
serializerFor: function (modelName) {
+ var trueModelName = this._classKeyFor(modelName);
- var normalizedModelName = (0, _emberDataPrivateSystemNormalizeModelName.default)(modelName);
-
- return this._instanceCache.get('serializer', normalizedModelName);
+ return this._instanceCache.get('serializer', trueModelName);
},
lookupAdapter: function (name) {
return this.adapterFor(name);
},
@@ -10953,10 +11587,13 @@
return this.serializerFor(name);
},
willDestroy: function () {
this._super.apply(this, arguments);
+ this._pushedInternalModels = null;
+ this._backburner.cancel(this._relationshipFlush);
+ this._relationshipFlush = null;
this.recordArrayManager.destroy();
this._instanceCache.destroy();
this.unloadAll();
},
@@ -10990,28 +11627,36 @@
}
function _commit(adapter, store, operation, snapshot) {
var internalModel = snapshot._internalModel;
var modelName = snapshot.modelName;
- var modelClass = store.modelFor(modelName);
+ var modelClass = store._modelFor(modelName);
var promise = adapter[operation](store, modelClass, snapshot);
var serializer = (0, _emberDataPrivateSystemStoreSerializers.serializerForAdapter)(store, adapter, modelName);
var label = 'DS: Extract and notify about ' + operation + ' completion of ' + internalModel;
promise = Promise.resolve(promise, label);
promise = (0, _emberDataPrivateSystemStoreCommon._guard)(promise, (0, _emberDataPrivateSystemStoreCommon._bind)(_emberDataPrivateSystemStoreCommon._objectIsAlive, store));
promise = (0, _emberDataPrivateSystemStoreCommon._guard)(promise, (0, _emberDataPrivateSystemStoreCommon._bind)(_emberDataPrivateSystemStoreCommon._objectIsAlive, internalModel));
return promise.then(function (adapterPayload) {
- store._adapterRun(function () {
+ /*
+ Note to future spelunkers hoping to optimize.
+ We rely on this `run` to create a run loop if needed
+ that `store._push` and `store.didSaveRecord` will both share.
+ We use `join` because it is often the case that we
+ have an outer run loop available still from the first
+ call to `store._push`;
+ */
+ store._backburner.join(function () {
var payload = undefined,
data = undefined;
if (adapterPayload) {
payload = (0, _emberDataPrivateSystemStoreSerializerResponse.normalizeResponseHelper)(serializer, store, modelClass, adapterPayload, snapshot.id, operation);
if (payload.included) {
- store.push({ data: payload.included });
+ store._push({ data: null, included: payload.included });
}
data = payload.data;
}
store.didSaveRecord(internalModel, { data: data });
});
@@ -11028,21 +11673,21 @@
throw error;
}, label);
}
- function setupRelationships(store, record, data) {
+ function setupRelationships(store, internalModel, data) {
if (!data.relationships) {
return;
}
- record.type.eachRelationship(function (key, descriptor) {
+ internalModel.type.eachRelationship(function (key, descriptor) {
if (!data.relationships[key]) {
return;
}
- var relationship = record._relationships.get(key);
+ var relationship = internalModel._relationships.get(key);
relationship.push(data.relationships[key]);
});
}
exports.Store = Store;
@@ -11060,15 +11705,16 @@
// Check unknown relationships
define('ember-data/-private/system/store/common', ['exports', 'ember'], function (exports, _ember) {
exports._bind = _bind;
exports._guard = _guard;
exports._objectIsAlive = _objectIsAlive;
-
var get = _ember.default.get;
function _bind(fn) {
- var args = Array.prototype.slice.call(arguments, 1);
+ for (var _len = arguments.length, args = Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) {
+ args[_key - 1] = arguments[_key];
+ }
return function () {
return fn.apply(undefined, args);
};
}
@@ -11233,173 +11879,151 @@
} else {
return Object.keys(adapterPayload || {}).length;
}
}
- function _find(adapter, store, typeClass, id, internalModel, options) {
+ function _find(adapter, store, modelClass, id, internalModel, options) {
var snapshot = internalModel.createSnapshot(options);
- var promise = adapter.findRecord(store, typeClass, id, snapshot);
+ var promise = adapter.findRecord(store, modelClass, id, snapshot);
var serializer = (0, _emberDataPrivateSystemStoreSerializers.serializerForAdapter)(store, adapter, internalModel.type.modelName);
- var label = "DS: Handle Adapter#findRecord of " + typeClass + " with id: " + id;
+ var label = "DS: Handle Adapter#findRecord of " + modelClass + " with id: " + id;
promise = Promise.resolve(promise, label);
promise = (0, _emberDataPrivateSystemStoreCommon._guard)(promise, (0, _emberDataPrivateSystemStoreCommon._bind)(_emberDataPrivateSystemStoreCommon._objectIsAlive, store));
return promise.then(function (adapterPayload) {
- return store._adapterRun(function () {
- var payload = (0, _emberDataPrivateSystemStoreSerializerResponse.normalizeResponseHelper)(serializer, store, typeClass, adapterPayload, id, 'findRecord');
+ var payload = (0, _emberDataPrivateSystemStoreSerializerResponse.normalizeResponseHelper)(serializer, store, modelClass, adapterPayload, id, 'findRecord');
- var internalModel = store._push(payload);
- return internalModel;
- });
+ return store._push(payload);
}, function (error) {
internalModel.notFound();
if (internalModel.isEmpty()) {
internalModel.unloadRecord();
}
throw error;
- }, "DS: Extract payload of '" + typeClass + "'");
+ }, "DS: Extract payload of '" + modelClass + "'");
}
- function _findMany(adapter, store, typeClass, ids, internalModels) {
+ function _findMany(adapter, store, modelClass, ids, internalModels) {
var snapshots = _ember.default.A(internalModels).invoke('createSnapshot');
- var promise = adapter.findMany(store, typeClass, ids, snapshots);
- var serializer = (0, _emberDataPrivateSystemStoreSerializers.serializerForAdapter)(store, adapter, typeClass.modelName);
- var label = "DS: Handle Adapter#findMany of " + typeClass;
+ var promise = adapter.findMany(store, modelClass, ids, snapshots);
+ var serializer = (0, _emberDataPrivateSystemStoreSerializers.serializerForAdapter)(store, adapter, modelClass.modelName);
+ var label = "DS: Handle Adapter#findMany of " + modelClass;
if (promise === undefined) {
throw new Error('adapter.findMany returned undefined, this was very likely a mistake');
}
promise = Promise.resolve(promise, label);
promise = (0, _emberDataPrivateSystemStoreCommon._guard)(promise, (0, _emberDataPrivateSystemStoreCommon._bind)(_emberDataPrivateSystemStoreCommon._objectIsAlive, store));
return promise.then(function (adapterPayload) {
- return store._adapterRun(function () {
- var payload = (0, _emberDataPrivateSystemStoreSerializerResponse.normalizeResponseHelper)(serializer, store, typeClass, adapterPayload, null, 'findMany');
- var internalModels = store._push(payload);
- return internalModels;
- });
- }, null, "DS: Extract payload of " + typeClass);
+ var payload = (0, _emberDataPrivateSystemStoreSerializerResponse.normalizeResponseHelper)(serializer, store, modelClass, adapterPayload, null, 'findMany');
+ return store._push(payload);
+ }, null, "DS: Extract payload of " + modelClass);
}
function _findHasMany(adapter, store, internalModel, link, relationship) {
var snapshot = internalModel.createSnapshot();
- var typeClass = store.modelFor(relationship.type);
+ var modelClass = store.modelFor(relationship.type);
var promise = adapter.findHasMany(store, snapshot, link, relationship);
var serializer = (0, _emberDataPrivateSystemStoreSerializers.serializerForAdapter)(store, adapter, relationship.type);
var label = "DS: Handle Adapter#findHasMany of " + internalModel + " : " + relationship.type;
promise = Promise.resolve(promise, label);
promise = (0, _emberDataPrivateSystemStoreCommon._guard)(promise, (0, _emberDataPrivateSystemStoreCommon._bind)(_emberDataPrivateSystemStoreCommon._objectIsAlive, store));
promise = (0, _emberDataPrivateSystemStoreCommon._guard)(promise, (0, _emberDataPrivateSystemStoreCommon._bind)(_emberDataPrivateSystemStoreCommon._objectIsAlive, internalModel));
return promise.then(function (adapterPayload) {
- return store._adapterRun(function () {
- var payload = (0, _emberDataPrivateSystemStoreSerializerResponse.normalizeResponseHelper)(serializer, store, typeClass, adapterPayload, null, 'findHasMany');
- //TODO Use a non record creating push
- var records = store.push(payload);
- var recordArray = records.map(function (record) {
- return record._internalModel;
- });
- recordArray.meta = payload.meta;
- return recordArray;
- });
+ var payload = (0, _emberDataPrivateSystemStoreSerializerResponse.normalizeResponseHelper)(serializer, store, modelClass, adapterPayload, null, 'findHasMany');
+ var internalModelArray = store._push(payload);
+
+ internalModelArray.meta = payload.meta;
+ return internalModelArray;
}, null, "DS: Extract payload of " + internalModel + " : hasMany " + relationship.type);
}
function _findBelongsTo(adapter, store, internalModel, link, relationship) {
var snapshot = internalModel.createSnapshot();
- var typeClass = store.modelFor(relationship.type);
+ var modelClass = store.modelFor(relationship.type);
var promise = adapter.findBelongsTo(store, snapshot, link, relationship);
var serializer = (0, _emberDataPrivateSystemStoreSerializers.serializerForAdapter)(store, adapter, relationship.type);
var label = "DS: Handle Adapter#findBelongsTo of " + internalModel + " : " + relationship.type;
promise = Promise.resolve(promise, label);
promise = (0, _emberDataPrivateSystemStoreCommon._guard)(promise, (0, _emberDataPrivateSystemStoreCommon._bind)(_emberDataPrivateSystemStoreCommon._objectIsAlive, store));
promise = (0, _emberDataPrivateSystemStoreCommon._guard)(promise, (0, _emberDataPrivateSystemStoreCommon._bind)(_emberDataPrivateSystemStoreCommon._objectIsAlive, internalModel));
return promise.then(function (adapterPayload) {
- return store._adapterRun(function () {
- var payload = (0, _emberDataPrivateSystemStoreSerializerResponse.normalizeResponseHelper)(serializer, store, typeClass, adapterPayload, null, 'findBelongsTo');
+ var payload = (0, _emberDataPrivateSystemStoreSerializerResponse.normalizeResponseHelper)(serializer, store, modelClass, adapterPayload, null, 'findBelongsTo');
- if (!payload.data) {
- return null;
- }
+ if (!payload.data) {
+ return null;
+ }
- var internalModel = store._push(payload);
- return internalModel;
- });
+ return store._push(payload);
}, null, "DS: Extract payload of " + internalModel + " : " + relationship.type);
}
- function _findAll(adapter, store, typeClass, sinceToken, options) {
- var modelName = typeClass.modelName;
+ function _findAll(adapter, store, modelClass, sinceToken, options) {
+ var modelName = modelClass.modelName;
var recordArray = store.peekAll(modelName);
var snapshotArray = recordArray._createSnapshot(options);
- var promise = adapter.findAll(store, typeClass, sinceToken, snapshotArray);
+ var promise = adapter.findAll(store, modelClass, sinceToken, snapshotArray);
var serializer = (0, _emberDataPrivateSystemStoreSerializers.serializerForAdapter)(store, adapter, modelName);
- var label = "DS: Handle Adapter#findAll of " + typeClass;
+ var label = "DS: Handle Adapter#findAll of " + modelClass;
promise = Promise.resolve(promise, label);
promise = (0, _emberDataPrivateSystemStoreCommon._guard)(promise, (0, _emberDataPrivateSystemStoreCommon._bind)(_emberDataPrivateSystemStoreCommon._objectIsAlive, store));
return promise.then(function (adapterPayload) {
- store._adapterRun(function () {
- var payload = (0, _emberDataPrivateSystemStoreSerializerResponse.normalizeResponseHelper)(serializer, store, typeClass, adapterPayload, null, 'findAll');
- store._push(payload);
- });
+ var payload = (0, _emberDataPrivateSystemStoreSerializerResponse.normalizeResponseHelper)(serializer, store, modelClass, adapterPayload, null, 'findAll');
- store.didUpdateAll(typeClass);
+ store._push(payload);
+ store.didUpdateAll(modelName);
+
return store.peekAll(modelName);
- }, null, "DS: Extract payload of findAll " + typeClass);
+ }, null, "DS: Extract payload of findAll " + modelClass);
}
- function _query(adapter, store, typeClass, query, recordArray) {
- var modelName = typeClass.modelName;
- var promise = adapter.query(store, typeClass, query, recordArray);
+ function _query(adapter, store, modelClass, query, recordArray) {
+ var modelName = modelClass.modelName;
+ var promise = adapter.query(store, modelClass, query, recordArray);
var serializer = (0, _emberDataPrivateSystemStoreSerializers.serializerForAdapter)(store, adapter, modelName);
- var label = 'DS: Handle Adapter#query of ' + typeClass;
+ var label = 'DS: Handle Adapter#query of ' + modelClass;
+
promise = Promise.resolve(promise, label);
promise = (0, _emberDataPrivateSystemStoreCommon._guard)(promise, (0, _emberDataPrivateSystemStoreCommon._bind)(_emberDataPrivateSystemStoreCommon._objectIsAlive, store));
return promise.then(function (adapterPayload) {
- var internalModels = undefined,
- payload = undefined;
- store._adapterRun(function () {
- payload = (0, _emberDataPrivateSystemStoreSerializerResponse.normalizeResponseHelper)(serializer, store, typeClass, adapterPayload, null, 'query');
- internalModels = store._push(payload);
- });
+ var payload = (0, _emberDataPrivateSystemStoreSerializerResponse.normalizeResponseHelper)(serializer, store, modelClass, adapterPayload, null, 'query');
+ var internalModels = store._push(payload);
+
recordArray._setInternalModels(internalModels, payload);
return recordArray;
- }, null, 'DS: Extract payload of query ' + typeClass);
+ }, null, 'DS: Extract payload of query ' + modelName);
}
- function _queryRecord(adapter, store, typeClass, query) {
- var modelName = typeClass.modelName;
- var promise = adapter.queryRecord(store, typeClass, query);
+ function _queryRecord(adapter, store, modelClass, query) {
+ var modelName = modelClass.modelName;
+ var promise = adapter.queryRecord(store, modelClass, query);
var serializer = (0, _emberDataPrivateSystemStoreSerializers.serializerForAdapter)(store, adapter, modelName);
- var label = "DS: Handle Adapter#queryRecord of " + typeClass;
+ var label = "DS: Handle Adapter#queryRecord of " + modelName;
promise = Promise.resolve(promise, label);
promise = (0, _emberDataPrivateSystemStoreCommon._guard)(promise, (0, _emberDataPrivateSystemStoreCommon._bind)(_emberDataPrivateSystemStoreCommon._objectIsAlive, store));
return promise.then(function (adapterPayload) {
- var internalModel;
- store._adapterRun(function () {
- var payload = (0, _emberDataPrivateSystemStoreSerializerResponse.normalizeResponseHelper)(serializer, store, typeClass, adapterPayload, null, 'queryRecord');
+ var payload = (0, _emberDataPrivateSystemStoreSerializerResponse.normalizeResponseHelper)(serializer, store, modelClass, adapterPayload, null, 'queryRecord');
- internalModel = store._push(payload);
- });
-
- return internalModel;
- }, null, "DS: Extract payload of queryRecord " + typeClass);
+ return store._push(payload);
+ }, null, "DS: Extract payload of queryRecord " + modelName);
}
});
define('ember-data/-private/system/store/serializer-response', ['exports', 'ember', 'ember-data/-private/debug'], function (exports, _ember, _emberDataPrivateDebug) {
exports.validateDocumentStructure = validateDocumentStructure;
exports.normalizeResponseHelper = normalizeResponseHelper;
@@ -11733,17 +12357,19 @@
/*
ember-container-inject-owner is a new feature in Ember 2.3 that finally provides a public
API for looking items up. This function serves as a super simple polyfill to avoid
triggering deprecations.
- */
+ */
function getOwner(context) {
var owner;
if (_ember.default.getOwner) {
owner = _ember.default.getOwner(context);
- } else if (context.container) {
+ }
+
+ if (!owner && context.container) {
owner = context.container;
}
if (owner && owner.lookupFactory && !owner._lookupFactory) {
// `owner` is a container, we are just making this work
@@ -14072,11 +14698,11 @@
return status >= 200 && status < 300 || status === 304;
},
/**
Default `handleResponse` implementation uses this hook to decide if the
- response is a an invalid error.
+ response is an invalid error.
@since 1.13.0
@method isInvalid
@param {Number} status
@param {Object} headers
@param {Object} payload
@@ -15875,11 +16501,11 @@
if (!this.store._hasModelFor(modelName)) {
return null;
}
- var modelClass = this.store.modelFor(modelName);
+ var modelClass = this.store._modelFor(modelName);
var serializer = this.store.serializerFor(modelName);
var _serializer$normalize = serializer.normalize(modelClass, resourceHash);
var data = _serializer$normalize.data;
@@ -16185,11 +16811,11 @@
},
serializeHasMany: function (snapshot, json, relationship) {
var key = relationship.key;
var shouldSerializeHasMany = '_shouldSerializeHasMany';
- if (false) {
+ if (true) {
shouldSerializeHasMany = 'shouldSerializeHasMany';
}
if (this[shouldSerializeHasMany](snapshot, key, relationship)) {
var hasMany = snapshot.hasMany(key);
@@ -17281,11 +17907,11 @@
var _this5 = this;
var json = {};
if (options && options.includeId) {
- if (false) {
+ if (true) {
this.serializeId(snapshot, json, get(this, 'primaryKey'));
} else {
var id = snapshot.id;
if (id) {
json[get(this, 'primaryKey')] = id;
@@ -17447,11 +18073,11 @@
@param {Object} relationship
*/
serializeHasMany: function (snapshot, json, relationship) {
var key = relationship.key;
var shouldSerializeHasMany = '_shouldSerializeHasMany';
- if (false) {
+ if (true) {
shouldSerializeHasMany = 'shouldSerializeHasMany';
}
if (this[shouldSerializeHasMany](snapshot, key, relationship)) {
var hasMany = snapshot.hasMany(key, { ids: true });
@@ -17719,11 +18345,11 @@
}
});
}
- if (false) {
+ if (true) {
JSONSerializer.reopen({
/**
serializeId can be used to customize how id is serialized
@@ -17909,11 +18535,11 @@
var documentHash = {
data: [],
included: []
};
- var modelClass = store.modelFor(modelName);
+ var modelClass = store._modelFor(modelName);
var serializer = store.serializerFor(modelName);
_ember.default.makeArray(arrayHash).forEach(function (hash) {
var _normalizePolymorphicRecord = _this._normalizePolymorphicRecord(store, hash, prop, modelClass, serializer);
@@ -18728,10 +19354,10 @@
*/
deserialize: null
});
});
define("ember-data/version", ["exports"], function (exports) {
- exports.default = "2.11.3";
+ exports.default = "2.12.0-beta.1";
});
define("ember-inflector", ["exports", "ember", "ember-inflector/lib/system", "ember-inflector/lib/ext/string"], function (exports, _ember, _emberInflectorLibSystem, _emberInflectorLibExtString) {
_emberInflectorLibSystem.Inflector.defaultRules = _emberInflectorLibSystem.defaultRules;
_ember.default.Inflector = _emberInflectorLibSystem.Inflector;