dist/globals/ember-data.prod.js in ember-data-source-2.18.0 vs dist/globals/ember-data.prod.js in ember-data-source-2.18.1
- old
+ new
@@ -4,11 +4,11 @@
/*!
* @overview Ember Data
* @copyright Copyright 2011-2017 Tilde Inc. and contributors.
* Portions Copyright 2011 LivingSocial Inc.
* @license Licensed under MIT license (see license.js)
- * @version 2.18.0
+ * @version 2.18.1
*/
var loader, define, requireModule, require, requirejs;
(function (global) {
@@ -2687,16 +2687,28 @@
}
}
return true;
}
+ // Handle dematerialization for relationship `rel`. In all cases, notify the
+ // relatinoship of the dematerialization: this is done so the relationship can
+ // notify its inverse which needs to update state
+ //
+ // If the inverse is sync, unloading this record is treated as a client-side
+ // delete, so we remove the inverse records from this relationship to
+ // disconnect the graph. Because it's not async, we don't need to keep around
+ // the internalModel as an id-wrapper for references and because the graph is
+ // disconnected we can actually destroy the internalModel when checking for
+ // orphaned models.
function destroyRelationship(rel) {
- if (rel._inverseIsAsync()) {
- rel.removeInternalModelFromInverse(rel.inverseInternalModel);
- rel.removeInverseRelationships();
- } else {
- rel.removeCompletelyFromInverse();
+ rel.internalModelDidDematerialize();
+
+ if (rel._inverseIsSync()) {
+ // disconnect the graph so that the sync inverse relationship does not
+ // prevent us from cleaning up during `_cleanupOrphanedInternalModels`
+ rel.removeAllInternalModelsFromOwn();
+ rel.removeAllCanonicalInternalModelsFromOwn();
}
}
// this (and all heimdall instrumentation) will be stripped by a babel transform
// https://github.com/heimdalljs/babel5-plugin-strip-heimdall
@@ -2909,10 +2921,11 @@
});
};
InternalModel.prototype._directlyRelatedInternalModels = function _directlyRelatedInternalModels() {
var array = [];
+
this._relationships.forEach(function (name, rel) {
array = array.concat(rel.members.list, rel.canonicalMembers.list);
});
return array;
};
@@ -3306,14 +3319,11 @@
var implicitRelationships = this._implicitRelationships;
this.__implicitRelationships = null;
Object.keys(implicitRelationships).forEach(function (key) {
var rel = implicitRelationships[key];
-
destroyRelationship(rel);
-
- rel.destroy();
});
};
InternalModel.prototype.preloadData = function preloadData(preload) {
var _this = this;
@@ -8542,10 +8552,11 @@
this.canonicalState = internalModel;
_Relationship.prototype.addCanonicalInternalModel.call(this, internalModel);
};
BelongsToRelationship.prototype.inverseDidDematerialize = function inverseDidDematerialize() {
+ _Relationship.prototype.inverseDidDematerialize.call(this, this.inverseInternalModel);
this.notifyBelongsToChanged();
};
BelongsToRelationship.prototype.removeCompletelyFromOwn = function removeCompletelyFromOwn(internalModel) {
_Relationship.prototype.removeCompletelyFromOwn.call(this, internalModel);
@@ -8558,10 +8569,16 @@
this.inverseInternalModel = null;
this.notifyBelongsToChanged();
}
};
+ BelongsToRelationship.prototype.removeCompletelyFromInverse = function removeCompletelyFromInverse() {
+ _Relationship.prototype.removeCompletelyFromInverse.call(this);
+
+ this.inverseInternalModel = null;
+ };
+
BelongsToRelationship.prototype.flushCanonical = function flushCanonical() {
//temporary fix to not remove newly created records if server returned null.
//TODO remove once we have proper diffing
if (this.inverseInternalModel && this.inverseInternalModel.isNew() && !this.canonicalState) {
return;
@@ -8602,10 +8619,16 @@
this.inverseInternalModel = null;
_Relationship.prototype.removeInternalModelFromOwn.call(this, internalModel);
this.notifyBelongsToChanged();
};
+ BelongsToRelationship.prototype.removeAllInternalModelsFromOwn = function removeAllInternalModelsFromOwn() {
+ _Relationship.prototype.removeAllInternalModelsFromOwn.call(this);
+ this.inverseInternalModel = null;
+ this.notifyBelongsToChanged();
+ };
+
BelongsToRelationship.prototype.notifyBelongsToChanged = function notifyBelongsToChanged() {
this.internalModel.notifyBelongsToChanged(this.key);
};
BelongsToRelationship.prototype.removeCanonicalInternalModelFromOwn = function removeCanonicalInternalModelFromOwn(internalModel) {
@@ -8614,10 +8637,15 @@
}
this.canonicalState = null;
_Relationship.prototype.removeCanonicalInternalModelFromOwn.call(this, internalModel);
};
+ BelongsToRelationship.prototype.removeAllCanonicalInternalModelsFromOwn = function removeAllCanonicalInternalModelsFromOwn() {
+ _Relationship.prototype.removeAllCanonicalInternalModelsFromOwn.call(this);
+ this.canonicalState = null;
+ };
+
BelongsToRelationship.prototype.findRecord = function findRecord() {
if (this.inverseInternalModel) {
return this.store._findByInternalModel(this.inverseInternalModel);
} else {
return EmberPromise.resolve(null);
@@ -8874,11 +8902,16 @@
var _this = _possibleConstructorReturn(this, _Relationship.call(this, store, internalModel, inverseKey, relationshipMeta));
_this.belongsToType = relationshipMeta.type;
_this.canonicalState = [];
_this.isPolymorphic = relationshipMeta.options.polymorphic;
+ // The ManyArray for this relationship
_this._manyArray = null;
+ // The previous ManyArray for this relationship. It will be destroyed when
+ // we create a new many array, but in the interim it will be updated if
+ // inverse internal models are unloaded.
+ _this._retainedManyArray = null;
_this.__loadingPromise = null;
return _this;
}
ManyRelationship.prototype._updateLoadingPromise = function _updateLoadingPromise(promise, content) {
@@ -8926,14 +8959,18 @@
this.canonicalState.push(internalModel);
}
_Relationship.prototype.addCanonicalInternalModel.call(this, internalModel, idx);
};
- ManyRelationship.prototype.inverseDidDematerialize = function inverseDidDematerialize() {
- if (this._manyArray) {
- this._manyArray.destroy();
- this._manyArray = null;
+ ManyRelationship.prototype.inverseDidDematerialize = function inverseDidDematerialize(inverseInternalModel) {
+ _Relationship.prototype.inverseDidDematerialize.call(this, inverseInternalModel);
+ if (this.isAsync) {
+ if (this._manyArray) {
+ this._retainedManyArray = this._manyArray;
+ this._manyArray = null;
+ }
+ this._removeInternalModelFromManyArray(this._retainedManyArray, inverseInternalModel);
}
this.notifyHasManyChanged();
};
ManyRelationship.prototype.addInternalModel = function addInternalModel(internalModel, idx) {
@@ -8958,10 +8995,16 @@
this.canonicalState.splice(i, 1);
}
_Relationship.prototype.removeCanonicalInternalModelFromOwn.call(this, internalModel, idx);
};
+ ManyRelationship.prototype.removeAllCanonicalInternalModelsFromOwn = function removeAllCanonicalInternalModelsFromOwn() {
+ _Relationship.prototype.removeAllCanonicalInternalModelsFromOwn.call(this);
+ this.canonicalMembers.clear();
+ this.canonicalState.splice(0, this.canonicalState.length);
+ };
+
ManyRelationship.prototype.removeCompletelyFromOwn = function removeCompletelyFromOwn(internalModel) {
_Relationship.prototype.removeCompletelyFromOwn.call(this, internalModel);
var canonicalIndex = this.canonicalState.indexOf(internalModel);
@@ -8990,11 +9033,37 @@
ManyRelationship.prototype.removeInternalModelFromOwn = function removeInternalModelFromOwn(internalModel, idx) {
if (!this.members.has(internalModel)) {
return;
}
_Relationship.prototype.removeInternalModelFromOwn.call(this, internalModel, idx);
- var manyArray = this.manyArray;
+ // note that ensuring the many array is created, via `this.manyArray`
+ // (instead of `this._manyArray`) is intentional.
+ //
+ // Because we're removing from local, and not canonical, state, it is
+ // important that the many array is initialized now with those changes,
+ // otherwise it will be initialized with canonical state and we'll have
+ // lost the fact that this internalModel was removed.
+ this._removeInternalModelFromManyArray(this.manyArray, internalModel, idx);
+ this._removeInternalModelFromManyArray(this._retainedManyArray, internalModel, idx);
+ };
+
+ ManyRelationship.prototype.removeAllInternalModelsFromOwn = function removeAllInternalModelsFromOwn() {
+ _Relationship.prototype.removeAllInternalModelsFromOwn.call(this);
+ // as with removeInternalModelFromOwn, we make sure the many array is
+ // instantiated, or we'll lose local removals, as we're not updating
+ // canonical state here.
+ this.manyArray.clear();
+ if (this._retainedManyArray) {
+ this._retainedManyArray.clear();
+ }
+ };
+
+ ManyRelationship.prototype._removeInternalModelFromManyArray = function _removeInternalModelFromManyArray(manyArray, internalModel, idx) {
+ if (manyArray === null) {
+ return;
+ }
+
if (idx !== undefined) {
//TODO(Igor) not used currently, fix
manyArray.currentState.removeAt(idx);
} else {
manyArray._removeInternalModels([internalModel]);
@@ -9152,16 +9221,18 @@
ManyRelationship.prototype.destroy = function destroy() {
_Relationship.prototype.destroy.call(this);
var manyArray = this._manyArray;
if (manyArray) {
manyArray.destroy();
+ this._manyArray = null;
}
var proxy = this.__loadingPromise;
if (proxy) {
proxy.destroy();
+ this.__loadingPromise = null;
}
};
_createClass(ManyRelationship, [{
key: '_loadingPromise',
@@ -9169,21 +9240,30 @@
return this.__loadingPromise;
}
}, {
key: 'manyArray',
get: function () {
+ (false && Ember.assert('Error: relationship ' + this.parentType + ':' + this.key + ' has both many array and retained many array', this._manyArray === null || this._retainedManyArray === null));
+
+
if (!this._manyArray) {
this._manyArray = _manyArray.default.create({
canonicalState: this.canonicalState,
store: this.store,
relationship: this,
type: this.store.modelFor(this.belongsToType),
record: this.internalModel,
meta: this.meta,
isPolymorphic: this.isPolymorphic
});
+
+ if (this._retainedManyArray !== null) {
+ this._retainedManyArray.destroy();
+ this._retainedManyArray = null;
+ }
}
+
return this._manyArray;
}
}]);
return ManyRelationship;
@@ -9232,10 +9312,11 @@
return Constructor;
};
}();
var guidFor = Ember.guidFor;
+ var get = Ember.get;
var Relationship = function () {
function Relationship(store, internalModel, inverseKey, relationshipMeta) {
var async = relationshipMeta.options.async;
var polymorphic = relationshipMeta.options.polymorphic;
@@ -9253,38 +9334,56 @@
this.inverseKeyForImplicit = this.internalModel.modelName + this.key;
this.linkPromise = null;
this.meta = null;
this.hasData = false;
this.hasLoaded = false;
+ this.__inverseMeta = undefined;
}
Relationship.prototype._inverseIsAsync = function _inverseIsAsync() {
- if (!this.inverseKey || !this.inverseInternalModel) {
+ var inverseMeta = this._inverseMeta;
+ if (!inverseMeta) {
return false;
}
- return this.inverseInternalModel._relationships.get(this.inverseKey).isAsync;
+
+ var inverseAsync = inverseMeta.options.async;
+ return typeof inverseAsync === 'undefined' ? true : inverseAsync;
};
- Relationship.prototype.removeInverseRelationships = function removeInverseRelationships() {
+ Relationship.prototype._inverseIsSync = function _inverseIsSync() {
+ var inverseMeta = this._inverseMeta;
+ if (!inverseMeta) {
+ return false;
+ }
+
+ var inverseAsync = inverseMeta.options.async;
+ return typeof inverseAsync === 'undefined' ? false : !inverseAsync;
+ };
+
+ Relationship.prototype.internalModelDidDematerialize = function internalModelDidDematerialize() {
+ var _this = this;
+
if (!this.inverseKey) {
return;
}
- var allMembers =
- // we actually want a union of members and canonicalMembers
- // they should be disjoint but currently are not due to a bug
- this.members.list.concat(this.canonicalMembers.list);
+ this.forAllMembers(function (inverseInternalModel) {
+ var relationship = inverseInternalModel._relationships.get(_this.inverseKey);
+ relationship.inverseDidDematerialize(_this.internalModel);
+ });
+ };
- for (var i = 0; i < allMembers.length; i++) {
- var inverseInternalModel = allMembers[i];
- var relationship = inverseInternalModel._relationships.get(this.inverseKey);
- relationship.inverseDidDematerialize();
+ Relationship.prototype.inverseDidDematerialize = function inverseDidDematerialize(inverseInternalModel) {
+ if (!this.isAsync) {
+ // unloading inverse of a sync relationship is treated as a client-side
+ // delete, so actually remove the models don't merely invalidate the cp
+ // cache.
+ this.removeInternalModelFromOwn(inverseInternalModel);
+ this.removeCanonicalInternalModelFromOwn(inverseInternalModel);
}
};
- Relationship.prototype.inverseDidDematerialize = function inverseDidDematerialize() {};
-
Relationship.prototype.updateMeta = function updateMeta(meta) {
this.meta = meta;
};
Relationship.prototype.clear = function clear() {
@@ -9300,23 +9399,33 @@
var _member = canonicalMembers[0];
this.removeCanonicalInternalModel(_member);
}
};
+ Relationship.prototype.removeAllInternalModelsFromOwn = function removeAllInternalModelsFromOwn() {
+ this.members.clear();
+ this.internalModel.updateRecordArrays();
+ };
+
+ Relationship.prototype.removeAllCanonicalInternalModelsFromOwn = function removeAllCanonicalInternalModelsFromOwn() {
+ this.canonicalMembers.clear();
+ this.flushCanonicalLater();
+ };
+
Relationship.prototype.removeInternalModels = function removeInternalModels(internalModels) {
- var _this = this;
+ var _this2 = this;
internalModels.forEach(function (internalModel) {
- return _this.removeInternalModel(internalModel);
+ return _this2.removeInternalModel(internalModel);
});
};
Relationship.prototype.addInternalModels = function addInternalModels(internalModels, idx) {
- var _this2 = this;
+ var _this3 = this;
internalModels.forEach(function (internalModel) {
- _this2.addInternalModel(internalModel, idx);
+ _this3.addInternalModel(internalModel, idx);
if (idx !== undefined) {
idx++;
}
});
};
@@ -9355,11 +9464,11 @@
}
} else {
var _relationships = internalModel._implicitRelationships;
var _relationship = _relationships[this.inverseKeyForImplicit];
if (!_relationship) {
- _relationship = _relationships[this.inverseKeyForImplicit] = new Relationship(this.store, internalModel, this.key, { options: { async: this.isAsync } });
+ _relationship = _relationships[this.inverseKeyForImplicit] = new Relationship(this.store, internalModel, this.key, { options: { async: this.isAsync }, type: this.parentType });
}
_relationship.addCanonicalInternalModel(this.internalModel);
}
};
@@ -9393,11 +9502,11 @@
this.notifyRecordRelationshipAdded(internalModel, idx);
if (this.inverseKey) {
internalModel._relationships.get(this.inverseKey).addInternalModel(this.internalModel);
} else {
if (!internalModel._implicitRelationships[this.inverseKeyForImplicit]) {
- internalModel._implicitRelationships[this.inverseKeyForImplicit] = new Relationship(this.store, internalModel, this.key, { options: { async: this.isAsync } });
+ internalModel._implicitRelationships[this.inverseKeyForImplicit] = new Relationship(this.store, internalModel, this.key, { options: { async: this.isAsync }, type: this.parentType });
}
internalModel._implicitRelationships[this.inverseKeyForImplicit].addInternalModel(this.internalModel);
}
this.internalModel.updateRecordArrays();
}
@@ -9442,11 +9551,11 @@
this.canonicalMembers.delete(internalModel);
this.flushCanonicalLater();
};
Relationship.prototype.removeCompletelyFromInverse = function removeCompletelyFromInverse() {
- var _this3 = this;
+ var _this4 = this;
if (!this.inverseKey) {
return;
}
@@ -9457,20 +9566,46 @@
var unload = function (inverseInternalModel) {
var id = guidFor(inverseInternalModel);
if (seen[id] === undefined) {
- var relationship = inverseInternalModel._relationships.get(_this3.inverseKey);
+ var relationship = inverseInternalModel._relationships.get(_this4.inverseKey);
relationship.removeCompletelyFromOwn(internalModel);
seen[id] = true;
}
};
this.members.forEach(unload);
this.canonicalMembers.forEach(unload);
+
+ if (!this.isAsync) {
+ this.clear();
+ }
};
+ Relationship.prototype.forAllMembers = function forAllMembers(callback) {
+ var seen = Object.create(null);
+
+ for (var i = 0; i < this.members.list.length; i++) {
+ var inverseInternalModel = this.members.list[i];
+ var id = guidFor(inverseInternalModel);
+ if (!seen[id]) {
+ seen[id] = true;
+ callback(inverseInternalModel);
+ }
+ }
+
+ for (var _i = 0; _i < this.canonicalMembers.list.length; _i++) {
+ var _inverseInternalModel = this.canonicalMembers.list[_i];
+ var _id = guidFor(_inverseInternalModel);
+ if (!seen[_id]) {
+ seen[_id] = true;
+ callback(_inverseInternalModel);
+ }
+ }
+ };
+
Relationship.prototype.removeCompletelyFromOwn = function removeCompletelyFromOwn(internalModel) {
this.canonicalMembers.delete(internalModel);
this.members.delete(internalModel);
this.internalModel.updateRecordArrays();
};
@@ -9487,12 +9622,12 @@
}
}
//TODO(Igor) make this less abysmally slow
this.members = this.canonicalMembers.copy();
- for (var _i = 0; _i < newInternalModels.length; _i++) {
- this.members.add(newInternalModels[_i]);
+ for (var _i2 = 0; _i2 < newInternalModels.length; _i2++) {
+ this.members.add(newInternalModels[_i2]);
}
};
Relationship.prototype.flushCanonicalLater = function flushCanonicalLater() {
if (this.willSync) {
@@ -9589,10 +9724,27 @@
Relationship.prototype.updateData = function updateData() {};
Relationship.prototype.destroy = function destroy() {};
_createClass(Relationship, [{
+ key: '_inverseMeta',
+ get: function () {
+ if (this.__inverseMeta === undefined) {
+ var inverseMeta = null;
+
+ if (this.inverseKey) {
+ var inverseModelClass = this.store.modelFor(this.relationshipMeta.type);
+ var inverseRelationships = get(inverseModelClass, 'relationshipsByName');
+ inverseMeta = inverseRelationships.get(this.inverseKey);
+ }
+
+ this.__inverseMeta = inverseMeta;
+ }
+
+ return this.__inverseMeta;
+ }
+ }, {
key: 'parentType',
get: function () {
return this.internalModel.modelName;
}
}]);
@@ -18215,10 +18367,10 @@
});
define("ember-data/version", ["exports"], function (exports) {
"use strict";
exports.__esModule = true;
- exports.default = "2.18.0";
+ exports.default = "2.18.1";
});
define("ember-inflector", ["module", "exports", "ember-inflector/lib/system", "ember-inflector/lib/ext/string"], function (module, exports, _system) {
"use strict";
exports.__esModule = true;