dist/globals/ember-data.prod.js in ember-data-source-2.6.0.beta.1 vs dist/globals/ember-data.prod.js in ember-data-source-2.6.0.beta.2
- 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.6.0-beta.1
+ * @version 2.6.0-beta.2
*/
var loader, define, requireModule, require, requirejs;
(function(global) {
@@ -61,20 +61,21 @@
length + '` arguments to define`');
}
var defaultDeps = ['require', 'exports', 'module'];
- function Module(name, deps, callback) {
+ function Module(name, deps, callback, alias) {
this.id = uuid++;
this.name = name;
this.deps = !deps.length && callback.length ? defaultDeps : deps;
this.module = { exports: {} };
this.callback = callback;
this.state = undefined;
- this._require = undefined;
this.finalized = false;
this.hasExportsAsDep = false;
+ this.isAlias = alias;
+ this.reified = new Array(deps.length);
}
Module.prototype.makeDefaultExport = function() {
var exports = this.module.exports;
if (exports !== null &&
@@ -82,18 +83,18 @@
exports['default'] === undefined) {
exports['default'] = exports;
}
};
- Module.prototype.exports = function(reifiedDeps) {
+ Module.prototype.exports = function() {
if (this.finalized) {
return this.module.exports;
} else {
if (loader.wrapModules) {
this.callback = loader.wrapModules(this.name, this.callback);
}
- var result = this.callback.apply(this, reifiedDeps);
+ var result = this.callback.apply(this, this.reified);
if (!(this.hasExportsAsDep && result === undefined)) {
this.module.exports = result;
}
this.makeDefaultExport();
this.finalized = true;
@@ -107,15 +108,14 @@
this.module = { exports: {}};
};
Module.prototype.reify = function() {
var deps = this.deps;
- var length = deps.length;
- var reified = new Array(length);
var dep;
+ var reified = this.reified;
- for (var i = 0, l = length; i < l; i++) {
+ for (var i = 0; i < deps.length; i++) {
dep = deps[i];
if (dep === 'exports') {
this.hasExportsAsDep = true;
reified[i] = this.module.exports;
} else if (dep === 'require') {
@@ -124,26 +124,29 @@
reified[i] = this.module;
} else {
reified[i] = findModule(resolve(dep, this.name), this.name).module.exports;
}
}
-
- return reified;
};
Module.prototype.makeRequire = function() {
var name = this.name;
-
- return this._require || (this._require = function(dep) {
+ var r = function(dep) {
return require(resolve(dep, name));
- });
+ };
+ r['default'] = r;
+ r.has = function(dep) {
+ return has(resolve(dep, name));
+ }
+ return r;
};
Module.prototype.build = function() {
- if (this.state === FAILED) { return; }
+ if (this.state === FAILED || this.state === LOADED) { return; }
this.state = FAILED;
- this.exports(this.reify());
+ this.reify()
+ this.exports();
this.state = LOADED;
};
define = function(name, deps, callback) {
if (arguments.length < 2) {
@@ -153,11 +156,15 @@
if (!_isArray(deps)) {
callback = deps;
deps = [];
}
- registry[name] = new Module(name, deps, callback);
+ if (callback instanceof Alias) {
+ registry[name] = new Module(callback.name, deps, callback, true);
+ } else {
+ registry[name] = new Module(name, deps, callback, false);
+ }
};
// we don't support all of AMD
// define.amd = {};
// we will support petals...
@@ -180,13 +187,12 @@
};
function findModule(name, referrer) {
var mod = registry[name] || registry[name + '/index'];
- while (mod && mod.callback instanceof Alias) {
- name = mod.callback.name;
- mod = registry[name];
+ while (mod && mod.isAlias) {
+ mod = registry[mod.name];
}
if (!mod) { missingModule(name, referrer); }
mod.build();
@@ -214,19 +220,46 @@
}
return parentBase.join('/');
}
+ function has(name) {
+ return !!(registry[name] || registry[name + '/index']);
+ }
+
requirejs.entries = requirejs._eak_seen = registry;
+ requirejs.has = has;
requirejs.unsee = function(moduleName) {
findModule(moduleName, '(unsee)').unsee();
};
requirejs.clear = function() {
requirejs.entries = requirejs._eak_seen = registry = {};
seen = {};
};
+
+ // prime
+ define('foo', function() {});
+ define('foo/bar', [], function() {});
+ define('foo/asdf', ['module', 'exports', 'require'], function(module, exports, require) {
+ if (require.has('foo/bar')) {
+ require('foo/bar');
+ }
+ });
+ define('foo/baz', [], define.alias('foo'));
+ define('foo/quz', define.alias('foo'));
+ define('foo/bar', ['foo', './quz', './baz', './asdf', './bar', '../foo'], function() {});
+ define('foo/main', ['foo/bar'], function() {});
+
+ require('foo/main');
+ require.unsee('foo/bar');
+
+ requirejs.clear();
+
+ if (typeof module !== 'undefined') {
+ module.exports = { require: require, define: define };
+ }
})(this);
define("ember-data/-private/adapters", ["exports", "ember-data/adapters/json-api", "ember-data/adapters/rest"], function (exports, _emberDataAdaptersJsonApi, _emberDataAdaptersRest) {
exports.JSONAPIAdapter = _emberDataAdaptersJsonApi.default;
exports.RESTAdapter = _emberDataAdaptersRest.default;
@@ -3359,22 +3392,35 @@
},
/**
Returns an object, whose keys are changed properties, and value is
an [oldProp, newProp] array.
+ The array represents the diff of the canonical state with the local state
+ of the model. Note: if the model is created locally, the canonical state is
+ empty since the adapter hasn't acknowledged the attributes yet:
Example
```app/models/mascot.js
import DS from 'ember-data';
export default DS.Model.extend({
- name: attr('string')
+ name: attr('string'),
+ isAdmin: attr('boolean', {
+ defaultValue: false
+ })
});
```
```javascript
var mascot = store.createRecord('mascot');
- mascot.changedAttributes(); // {}
- mascot.set('name', 'Tomster');
- mascot.changedAttributes(); // {name: [undefined, 'Tomster']}
+ mascot.changedAttributes(); // {}
+ mascot.set('name', 'Tomster');
+ mascot.changedAttributes(); // { name: [undefined, 'Tomster'] }
+ mascot.set('isAdmin', true);
+ mascot.changedAttributes(); // { isAdmin: [undefined, true], name: [undefined, 'Tomster'] }
+ mascot.save().then(function() {
+ mascot.changedAttributes(); // {}
+ mascot.set('isAdmin', false);
+ mascot.changedAttributes(); // { isAdmin: [true, false] }
+ });
```
@method changedAttributes
@return {Object} an object, whose keys are changed properties,
and value is an [oldProp, newProp] array.
*/
@@ -3604,11 +3650,11 @@
```javascript
// models/blog.js
export default DS.Model.extend({
user: DS.belongsTo({ async: true })
});
- store.push({
+ var blog = store.push({
type: 'blog',
id: 1,
relationships: {
user: { type: 'user', id: 1 }
}
@@ -3653,11 +3699,11 @@
```javascript
// models/blog.js
export default DS.Model.extend({
comments: DS.hasMany({ async: true })
});
- store.push({
+ var blog = store.push({
type: 'blog',
id: 1,
relationships: {
comments: {
data: [
@@ -7942,36 +7988,90 @@
return this.findRecord(modelName, id);
},
/**
This method returns a record for a given type and id combination.
- The `findRecord` method will always return a **promise** that will be
- resolved with the record. If the record was already in the store,
- the promise will be resolved immediately. Otherwise, the store
- will ask the adapter's `find` method to find the necessary data.
The `findRecord` method will always resolve its promise with the same
object for a given type and `id`.
+ The `findRecord` method will always return a **promise** that will be
+ resolved with the record.
Example
```app/routes/post.js
import Ember from 'ember';
export default Ember.Route.extend({
model: function(params) {
return this.store.findRecord('post', params.post_id);
}
});
```
- If you would like to force the record to reload, instead of
- loading it from the cache when present you can set `reload: true`
- in the options object for `findRecord`.
- ```app/routes/post/edit.js
- import Ember from 'ember';
- export default Ember.Route.extend({
- model: function(params) {
- return this.store.findRecord('post', params.post_id, { reload: true });
+ If the record is not yet available, the store will ask the adapter's `find`
+ method to find the necessary data. If the record is already present in the
+ store, it depends on the reload behavior _when_ the returned promise
+ resolves.
+ The reload behavior is configured either via the passed `options` hash or
+ the result of the adapter's `shouldReloadRecord`.
+ If `{ reload: true }` is passed or `adapter.shouldReloadRecord` evaluates
+ to `true`, then the returned promise resolves once the adapter returns
+ data, regardless if the requested record is already in the store:
+ ```js
+ store.push({
+ data: {
+ id: 1,
+ type: 'post',
+ revision: 1
}
});
+ // adapter#findRecord resolves with
+ // [
+ // {
+ // id: 1,
+ // type: 'post',
+ // revision: 2
+ // }
+ // ]
+ store.findRecord('post', 1, { reload: true }).then(function(post) {
+ post.get("revision"); // 2
+ });
```
+ If no reload is indicated via the abovementioned ways, then the promise
+ immediately resolves with the cached version in the store.
+ Optionally, if `adapter.shouldBackgroundReloadRecord` evaluates to `true`,
+ then a background reload is started, which updates the records' data, once
+ it is available:
+ ```js
+ // app/adapters/post.js
+ import ApplicationAdapter from "./application";
+ export default ApplicationAdapter.extend({
+ shouldReloadRecord(store, snapshot) {
+ return false;
+ },
+ shouldBackgroundReloadRecord(store, snapshot) {
+ return true;
+ }
+ });
+ // ...
+ store.push({
+ data: {
+ id: 1,
+ type: 'post',
+ revision: 1
+ }
+ });
+ var blogPost = store.findRecord('post', 1).then(function(post) {
+ post.get('revision'); // 1
+ });
+ // later, once adapter#findRecord resolved with
+ // [
+ // {
+ // id: 1,
+ // type: 'post',
+ // revision: 2
+ // }
+ // ]
+ blogPost.get('revision'); // 2
+ ```
+ See [peekRecord](#method_peekRecord) to get the cached version of a record.
@method findRecord
@param {String} modelName
@param {(String|Integer)} id
@param {Object} options
@return {Promise} promise
@@ -8407,23 +8507,86 @@
return (0, _emberDataPrivateSystemPromiseProxies.promiseObject)((0, _emberDataPrivateSystemStoreFinders._queryRecord)(adapter, this, typeClass, query));
},
/**
- `findAll` ask the adapter's `findAll` method to find the records
- for the given type, and return a promise that will be resolved
- once the server returns the values. The promise will resolve into
- all records of this type present in the store, even if the server
- only returns a subset of them.
+ `findAll` ask the adapter's `findAll` method to find the records for the
+ given type, and returns a promise which will resolve with all records of
+ this type present in the store, even if the adapter only returns a subset
+ of them.
```app/routes/authors.js
import Ember from 'ember';
export default Ember.Route.extend({
model: function(params) {
return this.store.findAll('author');
}
});
```
+ _When_ the returned promise resolves depends on the reload behavior,
+ configured via the passed `options` hash and the result of the adapter's
+ `shouldReloadAll` method.
+ If `{ reload: true }` is passed or `adapter.shouldReloadAll` evaluates to
+ `true`, then the returned promise resolves once the adapter returns data,
+ regardless if there are already records in the store:
+ ```js
+ store.push({
+ data: {
+ id: 'first',
+ type: 'author'
+ }
+ });
+ // adapter#findAll resolves with
+ // [
+ // {
+ // id: 'second',
+ // type: 'author'
+ // }
+ // ]
+ store.findAll('author', { reload: true }).then(function(authors) {
+ authors.getEach("id"); // ['first', 'second']
+ });
+ ```
+ If no reload is indicated via the abovementioned ways, then the promise
+ immediately resolves with all the records currently loaded in the store.
+ Optionally, if `adapter.shouldBackgroundReloadAll` evaluates to `true`,
+ then a background reload is started. Once this resolves, the array with
+ which the promise resolves, is updated automatically so it contains all the
+ records in the store:
+ ```js
+ // app/adapters/application.js
+ export default DS.Adapter.extend({
+ shouldReloadAll(store, snapshotsArray) {
+ return false;
+ },
+ shouldBackgroundReloadAll(store, snapshotsArray) {
+ return true;
+ }
+ });
+ // ...
+ store.push({
+ data: {
+ id: 'first',
+ type: 'author'
+ }
+ });
+ var allAuthors;
+ store.findAll('author').then(function(authors) {
+ authors.getEach('id'); // ['first']
+ allAuthors = authors;
+ });
+ // later, once adapter#findAll resolved with
+ // [
+ // {
+ // id: 'second',
+ // type: 'author'
+ // }
+ // ]
+ allAuthors.getEach('id'); // ['first', 'second']
+ ```
+ See [peekAll](#method_peekAll) to get an array of current records in the
+ store, without waiting until a reload is finished.
+ See [query](#method_query) to only get a subset of records from the server.
@method findAll
@param {String} modelName
@param {Object} options
@return {Promise} promise
*/
@@ -10576,13 +10739,33 @@
/**
This method is used by the store to determine if the store should
reload a record from the adapter when a record is requested by
`store.findRecord`.
- If this method returns true, the store will re-fetch a record from
- the adapter. If this method returns false, the store will resolve
+ If this method returns `true`, the store will re-fetch a record from
+ the adapter. If this method returns `false`, the store will resolve
immediately using the cached record.
+ For example, if you are building an events ticketing system, in which users
+ can only reserve tickets for 20 minutes at a time, and want to ensure that
+ in each route you have data that is no more than 20 minutes old you could
+ write:
+ ```javascript
+ shouldReloadRecord: function(store, ticketSnapshot) {
+ var timeDiff = moment().diff(ticketSnapshot.attr('lastAccessedAt')).minutes();
+ if (timeDiff > 20) {
+ return true;
+ } else {
+ return false;
+ }
+ }
+ ```
+ This method would ensure that whenever you do `store.findRecord('ticket',
+ id)` you will always get a ticket that is no more than 20 minutes old. In
+ case the cached version is more than 20 minutes old, `findRecord` will not
+ resolve until you fetched the latest version.
+ By default this hook returns `false`, as most UIs should not block user
+ interactions while waiting on data update.
@method shouldReloadRecord
@param {DS.Store} store
@param {DS.Snapshot} snapshot
@return {Boolean}
*/
@@ -10592,13 +10775,37 @@
/**
This method is used by the store to determine if the store should
reload all records from the adapter when records are requested by
`store.findAll`.
- If this method returns true, the store will re-fetch all records from
- the adapter. If this method returns false, the store will resolve
- immediately using the cached record.
+ If this method returns `true`, the store will re-fetch all records from
+ the adapter. If this method returns `false`, the store will resolve
+ immediately using the cached records.
+ For example, if you are building an events ticketing system, in which users
+ can only reserve tickets for 20 minutes at a time, and want to ensure that
+ in each route you have data that is no more than 20 minutes old you could
+ write:
+ ```javascript
+ shouldReloadAll: function(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;
+ }
+ });
+ }
+ ```
+ This method would ensure that whenever you do `store.findAll('ticket')` you
+ will always get a list of tickets that are no more than 20 minutes old. In
+ case a cached version is more than 20 minutes old, `findAll` will not
+ resolve until you fetched the latest versions.
+ By default this methods returns `true` if the passed `snapshotRecordArray`
+ is empty (meaning that there are no records locally available yet),
+ otherwise it returns `false`.
@method shouldReloadAll
@param {DS.Store} store
@param {DS.SnapshotRecordArray} snapshotRecordArray
@return {Boolean}
*/
@@ -10610,12 +10817,27 @@
This method is used by the store to determine if the store should
reload a record after the `store.findRecord` method resolves a
cached record.
This method is *only* checked by the store when the store is
returning a cached record.
- If this method returns true the store will re-fetch a record from
+ If this method returns `true` the store will re-fetch a record from
the adapter.
+ For example, if you do not want to fetch complex data over a mobile
+ connection, or if the network is down, you can implement
+ `shouldBackgroundReloadRecord` as follows:
+ ```javascript
+ shouldBackgroundReloadRecord: function(store, snapshot) {
+ var connection = window.navigator.connection;
+ if (connection === 'cellular' || connection === 'none') {
+ return false;
+ } else {
+ return true;
+ }
+ }
+ ```
+ By default this hook returns `true` so the data for the record is updated
+ in the background.
@method shouldBackgroundReloadRecord
@param {DS.Store} store
@param {DS.Snapshot} snapshot
@return {Boolean}
*/
@@ -10627,12 +10849,27 @@
This method is used by the store to determine if the store should
reload a record array after the `store.findAll` method resolves
with a cached record array.
This method is *only* checked by the store when the store is
returning a cached record array.
- If this method returns true the store will re-fetch all records
+ If this method returns `true` the store will re-fetch all records
from the adapter.
+ For example, if you do not want to fetch complex data over a mobile
+ connection, or if the network is down, you can implement
+ `shouldBackgroundReloadAll` as follows:
+ ```javascript
+ shouldBackgroundReloadAll: function(store, snapshotArray) {
+ var connection = window.navigator.connection;
+ if (connection === 'cellular' || connection === 'none') {
+ return false;
+ } else {
+ return true;
+ }
+ }
+ ```
+ By default this method returns `true`, indicating that a background reload
+ should always be triggered.
@method shouldBackgroundReloadAll
@param {DS.Store} store
@param {DS.SnapshotRecordArray} snapshotRecordArray
@return {Boolean}
*/
@@ -12499,11 +12736,11 @@
post: DS.belongsTo('post')
});
```
Use a custom (type) serializer for the post model to configure embedded author
```app/serializers/post.js
- import DS from 'ember-data;
+ import DS from 'ember-data';
export default DS.RESTSerializer.extend(DS.EmbeddedRecordsMixin, {
attrs: {
author: { embedded: 'always' }
}
})
@@ -15554,10 +15791,10 @@
*/
deserialize: null
});
});
define("ember-data/version", ["exports"], function (exports) {
- exports.default = "2.6.0-beta.1";
+ exports.default = "2.6.0-beta.2";
});
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;