8000 Annotated everything but the asynchronous methods. · StudyForFun/js-data@dd6e23f · GitHub
[go: up one dir, main page]

Skip to content

Commit dd6e23f

Browse files
committed
Annotated everything but the asynchronous methods.
Closes js-data#157 Addresses js-data#156
1 parent 1ba581f commit dd6e23f

28 files changed

+489
-137
lines changed

CHANGELOG.md

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,11 @@
1+
##### 2.0.0-beta.7 - xx June 2015
2+
3+
###### Backwards compatible API changes
4+
- #157 - DSEject not available on instances
5+
6+
###### Other
7+
- #156 - Thoroughly annotate all source code to encourage contribution
8+
19
##### 2.0.0-beta.6 - 04 June 2015
210

311
###### Breaking API changes

src/datastore/async_methods/create.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ export default function create(resourceName, attrs, options) {
4141
definition.emit('DS.afterCreate', definition, attrs);
4242
}
4343
if (options.cacheResponse) {
44-
let created = _this.inject(definition.n, attrs, options.orig());
44+
let created = _this.inject(definition.name, attrs, options.orig());
4545
let id = created[definition.idAttribute];
4646
let resource = _this.s[resourceName];
4747
resource.completedQueries[id] = new Date().getTime();

src/datastore/async_methods/save.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,7 @@ export default function save(resourceName, id, options) {
6161
if (noChanges) {
6262
return attrs;
6363
} else if (options.cacheResponse) {
64-
let injected = _this.inject(definition.n, attrs, options.orig());
64+
let injected = _this.inject(definition.name, attrs, options.orig());
6565
let resource = _this.s[resourceName];
6666
let id = injected[definition.idAttribute];
6767
resource.saved[id] = DSUtils.updateTimestamp(resource.saved[id]);

src/datastore/async_methods/update.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ export default function update(resourceName, id, attrs, options) {
3030
definition.emit('DS.afterUpdate', definition, attrs);
3131
}
3232
if (options.cacheResponse) {
33-
let injected = _this.inject(definition.n, attrs, options.orig());
33+
let injected = _this.inject(definition.name, attrs, options.orig());
3434
let resource = _this.s[resourceName];
3535
let id = injected[definition.idAttribute];
3636
resource.saved[id] = DSUtils.updateTimestamp(resource.saved[id]);

src/datastore/async_methods/updateAll.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ export default function updateAll(resourceName, attrs, params, options) {
2828
}
2929
let origOptions = options.orig();
3030
if (options.cacheResponse) {
31-
let injected = _this.inject(definition.n, data, origOptions);
31+
let injected = _this.inject(definition.name, data, origOptions);
3232
let resource = _this.s[resourceName];
3333
DSUtils.forEach(injected, i => {
3434
let id = i[definition.idAttribute];

src/datastore/sync_methods/defineResource.js

Lines changed: 55 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,20 @@
22
import DSUtils from '../../utils';
33
import DSErrors from '../../errors';
44

5+
/**
6+
* These are DS methods that will be proxied by instances. e.g.
7+
*
8+
* var store = new JSData.DS();
9+
* var User = store.defineResource('user');
10+
* var user = User.createInstance({ id: 1 });
11+
*
12+
* store.update(resourceName, id, attrs[, options]) // DS method
13+
* User.update(id, attrs[, options]) // DS method proxied on a Resource
14+
* user.DSUpdate(attrs[, options]) // DS method proxied on an Instance
15+
*/
516
let instanceMethods = [
617
'compute',
18+
'eject',
719
'refresh',
820
'save',
921
'update',
@@ -21,6 +33,10 @@ export default function defineResource(definition) {
2133
let _this = this;
2234
let definitions = _this.defs;
2335

36+
/**
37+
* This allows the name-only definition shorthand.
38+
* store.defineResource('user') is the same as store.defineResource({ name: 'user'})
39+
*/
2440
if (DSUtils._s(definition)) {
2541
definition = {
2642
name: definition.replace(/\s/gi, '')
@@ -34,6 +50,11 @@ export default function defineResource(definition) {
3450
throw new DSErrors.R(`${definition.name} is already registered!`);
3551
}
3652

53+
/**
54+
* Dynamic Resource constructor function.
55+
*
56+
* A Resource inherits from the defaults of the data store that created it.
57+
*/
3758
function Resource(options) {
3859
this.defaultValues = {};
3960
this.methods = {};
@@ -50,6 +71,7 @@ export default function defineResource(definition) {
5071
}
5172

5273
try {
74+
// Resources can inherit from another resource instead of inheriting directly from the data store defaults.
5375
if (definition.extends && definitions[definition.extends]) {
5476
// Inherit from another resource
5577
Resource.prototype = definitions[definition.extends];
@@ -61,9 +83,6 @@ export default function defineResource(definition) {
6183

6284
var def = definitions[definition.name];
6385

64-
// alias name, shaves 0.08 kb off the minified build
65-
def.n = def.name;
66-
6786
def.logFn('Preparing resource.');
6887

6988
if (!DSUtils._s(def.idAttribute)) {
@@ -82,7 +101,7 @@ export default function defineResource(definition) {
82101
DSUtils.forEach(relatedModels[relationName], d => {
83102
d.type = type;
84103
d.relation = relationName;
85-
d.name = def.n;
104+
d.name = def.name;
86105
def.relationList.push(d);
87106
if (d.localField) {
88107
def.relationFields.push(d.localField);
@@ -153,13 +172,6 @@ export default function defineResource(definition) {
153172
}
154173
};
155174

156-
// Remove this in v0.11.0 and make a breaking change notice
157-
// the the `filter` option has been renamed to `defaultFilter`
158-
if (def.filter) {
159-
def.defaultFilter = def.filter;
160-
delete def.filter;
161-
}
162-
163175
// Create the wrapper class for the new resource
164176
var _class = def['class'] = DSUtils.pascalCase(def.name);
165177
try {
@@ -182,21 +194,30 @@ export default function defineResource(definition) {
182194
};
183195
}
184196

185-
// Apply developer-defined methods
197+
// Apply developer-defined instance methods
186198
DSUtils.forOwn(def.methods, (fn, m) => {
187199
def[_class].prototype[m] = fn;
188200
});
189201

202+
/**
203+
* var user = User.createInstance({ id: 1 });
204+
* user.set('foo', 'bar');
205+
*/
190206
def[_class].prototype.set = function (key, value) {
191207
DSUtils.set(this, key, value);
192-
_this.compute(def.n, this);
208+
_this.compute(def.name, this);
193209
return this;
194210
};
195211

212+
/**
213+
* var user = User.createInstance({ id: 1 });
214+
* user.get('id'); // 1
215+
*/
196216
def[_class].prototype.get = function (key) {
197217
return DSUtils.get(this, key);
198218
};
199219

220+
// Setup the relation links
200221
DSUtils.applyRelationGettersToTarget(_this, def, def[_class].prototype);
201222

202223
// Prepare for computed properties
@@ -227,22 +248,24 @@ export default function defineResource(definition) {
227248
});
228249
});
229250

251+
// add instance proxies of DS methods
230252
DSUtils.forEach(instanceMethods, name => {
231253
def[_class].prototype[`DS${DSUtils.pascalCase(name)}`] = function (...args) {
232254
args.unshift(this[def.idAttribute] || this);
233-
args.unshift(def.n);
255+
args.unshift(def.name);
234256
return _this[name].apply(_this, args);
235257
};
236258
});
237259

260+
// manually add instance proxy for DS#create
238261
def[_class].prototype.DSCreate = function (...args) {
239262
args.unshift(this);
240-
args.unshift(def.n);
263+
args.unshift(def.name);
241264
return _this.create.apply(_this, args);
242265
};
243266

244267
// Initialize store data for the new resource
245-
_this.s[def.n] = {
268+
_this.s[def.name] = {
246269
collection: [],
247270
expiresHeap: new DSUtils.BinaryHeap(x => x.expires, (x, y) => x.item === y),
248271
completedQueries: {},
@@ -258,23 +281,33 @@ export default function defineResource(definition) {
258281
collectionModified: 0
259282
};
260283

284+
// start the reaping
261285
if (def.reapInterval) {
262-
setInterval(() => _this.reap(def.n, {isInterval: true}), def.reapInterval);
286+
setInterval(() => _this.reap(def.name, {isInterval: true}), def.reapInterval);
263287
}
264288

265-
// Proxy DS methods with shorthand ones
289+
// proxy DS methods with shorthand ones
10000
266290
let fns = ['registerAdapter', 'getAdapter', 'is'];
267291
for (var key in _this) {
268292
if (typeof _this[key] === 'function') {
269293
fns.push(key);
270294
}
271295
}
272296

297+
/**
298+
* Create the Resource shorthands that proxy DS methods. e.g.
299+
*
300+
* var store = new JSData.DS();
301+
* var User = store.defineResource('user');
302+
*
303+
* store.update(resourceName, id, attrs[, options]) // DS method
304+
* User.update(id, attrs[, options]) // DS method proxied on a Resource
305+
*/
273306
DSUtils.forEach(fns, key => {
274307
let k = key;
275308
if (_this[k].shorthand !== false) {
276309
def[k] = (...args) => {
277-
args.unshift(def.n);
310+
args.unshift(def.name);
278311
return _this[k].apply(_this, args);
279312
};
280313
def[k].before = fn => {
@@ -302,6 +335,8 @@ export default function defineResource(definition) {
302335
if (def.hasOwnProperty('defaultAdapter')) {
303336
defaultAdapter = def.defaultAdapter;
304337
}
338+
339+
// setup "actions"
305340
DSUtils.forOwn(def.actions, (action, name) => {
306341
if (def[name] && !def.actions[name]) {
307342
throw new Error(`Cannot override existing method "${name}"!`);
@@ -338,7 +373,7 @@ export default function defineResource(definition) {
338373
};
339374
});
340375

341-
// Mix-in events
376+
// mix in events
342377
DSUtils.Events(def);
343378

344379
def.logFn('Done preparing resource.');

src/datastore/sync_methods/eject.js

Lines changed: 34 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,13 @@
1+
/**
2+
* Eject an item from the store, if it is currently in the store.
3+
*
4+
* @param resourceName The name of the resource type of the item eject.
5+
* @param id The primary key of the item to eject.
6+
* @param options Optional configuration.
7+
* @param options.notify Whether to emit the "DS.beforeEject" and "DS.afterEject" events
8+
* @param options.clearEmptyQueries Whether to remove cached findAll queries that become empty as a result of this method call.
9+
* @returns The ejected item if one was ejected.
10+
*/
111
export default function eject(resourceName, id, options) {
212
let _this = this;
313
let DSUtils = _this.utils;
@@ -18,50 +28,62 @@ export default function eject(resourceName, id, options) {
1828

1929
options.logFn('eject', id, options);
2030

31+
// find the item to eject
2132
for (var i = 0; i < resource.collection.length; i++) {
2233
if (resource.collection[i][definition.idAttribute] == id) { // jshint ignore:line
2334
item = resource.collection[i];
35+
// remove its expiration timestamp
2436
resource.expiresHeap.remove(item);
2537
found = true;
2638
break;
2739
}
2840
}
2941
if (found) {
42+
// lifecycle
3043
definition.beforeEject(options, item);
3144
if (options.notify) {
3245
definition.emit('DS.beforeEject', definition, item);
3346
}
34-
resource.collection.splice(i, 1);
35-
if (DSUtils.w) {
36-
resource.observers[id].close();
37-
}
38-
delete resource.observers[id];
3947

40-
delete resource.index[id];
41-
delete resource.previousAttributes[id];
42-
delete resource.completedQueries[id];
43-
delete resource.pendingQueries[id];
44-
DSUtils.forEach(resource.changeHistories[id], changeRecord => {
45-
DSUtils.remove(resource.changeHistory, changeRecord);
46-
});
48+
// find the item in any ($$injected) cached queries
4749
let toRemove = [];
4850
DSUtils.forOwn(resource.queryData, (items, queryHash) => {
4951
if (items.$$injected) {
5052
DSUtils.remove(items, item);
5153
}
54+
// optionally remove any empty queries
5255
if (!items.length && options.clearEmptyQueries) {
5356
toRemove.push(queryHash);
5457
}
5558
});
59+
60+
// clean up
61+
DSUtils.forEach(resource.changeHistories[id], changeRecord => {
62+
DSUtils.remove(resource.changeHistory, changeRecord);
63+
});
5664
DSUtils.forEach(toRemove, queryHash => {
5765
delete resource.completedQueries[queryHash];
5866
delete resource.queryData[queryHash];
5967
});
68+
if (DSUtils.w) {
69+
// stop observation
70+
resource.observers[id].close();
71+
}
72+
delete resource.observers[id];
73+
delete resource.index[id];
74+
delete resource.previousAttributes[id];
75+
delete resource.completedQueries[id];
76+
delete resource.pendingQueries[id];
6077
delete resource.changeHistories[id];
6178
delete resource.modified[id];
6279
delete resource.saved[id];
80+
81+
// remove it from the store
82+
resource.collection.splice(i, 1);
83+
// collection has been modified
6384
resource.collectionModified = DSUtils.updateTimestamp(resource.collectionModified);
6485

86+
// lifecycle
6587
definition.afterEject(options, item);
6688
if (options.notify) {
6789
definition.emit('DS.afterEject', definition, item);

src/datastore/sync_methods/ejectAll.js

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,11 @@
1+
/**
2+
* Eject a collection of items from the store, if any items currently in the store match the given criteria.
3+
*
4+
* @param resourceName The name of the resource type of the items eject.
5+
* @param params The criteria by which to match items to eject. See http://www.js-data.io/docs/query-syntax
6+
* @param options Optional configuration.
7+
* @returns The collection of items that were ejected, if any.
8+
*/
19
export default function ejectAll(resourceName, params, options) {
210
let _this = this;
311
let DSUtils = _this.utils;
@@ -14,21 +22,29 @@ export default function ejectAll(resourceName, params, options) {
1422

1523
let resource = _this.s[resourceName];
1624
let queryHash = DSUtils.toJson(params);
17-
let items = _this.filter(definition.n, params);
25+
26+
// get items that match the criteria
27+
let items = _this.filter(definition.name, params);
1828
let ids = [];
29+
1930
if (DSUtils.isEmpty(params)) {
31+
// remove all completed queries if ejecting all items
2032
resource.completedQueries = {};
2133
} else {
34+
// remove matching completed query, if any
2235
delete resource.completedQueries[queryHash];
2336
}
37+
// prepare to remove matching items
2438
DSUtils.forEach(items, item => {
2539
if (item && item[definition.idAttribute]) {
2640
ids.push(item[definition.idAttribute]);
2741
}
2842
});
43+
// eject each matching item
2944
DSUtils.forEach(ids, id => {
30-
_this.eject(definition.n, id, options);
45+
_this.eject(definition.name, id, options);
3146
});
47+
// collection has been modified
3248
resource.collectionModified = DSUtils.updateTimestamp(resource.collectionModified);
3349
return items;
3450
}

0 commit comments

Comments
 (0)
0