Skip to content
This repository was archived by the owner on Jan 26, 2021. It is now read-only.

Commit 5f291f5

Browse files
committed
Index nested objects that come from include queries
1 parent e76d574 commit 5f291f5

File tree

10 files changed

+371
-84
lines changed

10 files changed

+371
-84
lines changed

dist/parse-react.js

Lines changed: 65 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -436,7 +436,7 @@ var Mixin = {
436436
componentWillUpdate: function componentWillUpdate(nextProps, nextState) {
437437
// only subscribe if props or state changed
438438
if (nextProps !== this.props || nextState !== this.state) {
439-
this._subscribe();
439+
this._subscribe(nextProps, nextState);
440440
}
441441
},
442442

@@ -1131,7 +1131,11 @@ function storeObject(data) {
11311131
if (!(data.id instanceof Id)) {
11321132
throw new Error('Cannot store an object without an Id');
11331133
}
1134-
store[data.id] = { data: data, queries: {} };
1134+
var queries = {};
1135+
if (store[data.id]) {
1136+
queries = store[data.id].queries;
1137+
}
1138+
store[data.id] = { data: data, queries: queries };
11351139
return data.id;
11361140
}
11371141
/**
@@ -1346,10 +1350,26 @@ function storeQueryResults(results, query) {
13461350
orderColumns[column] = true;
13471351
}
13481352
}
1353+
var includes = [];
1354+
if (query._include.length) {
1355+
for (i = 0; i < query._include.length; i++) {
1356+
includes.push(query._include[i].split('.'));
1357+
}
1358+
}
13491359
var ids = [];
13501360
for (i = 0; i < results.length; i++) {
13511361
var flat = flatten(results[i]);
13521362
var id = storeObject(flat);
1363+
if (includes.length) {
1364+
for (var inclusion = 0; inclusion < includes.length; inclusion++) {
1365+
var inclusionChain = includes[inclusion];
1366+
var cur = results[i];
1367+
for (var col = 0; col < inclusionChain.length; col++) {
1368+
cur = cur.get(inclusionChain[col]);
1369+
storeObject(flatten(cur));
1370+
}
1371+
}
1372+
}
13531373
var resultItem = id;
13541374
if (orderColumns) {
13551375
// Fetch and store ordering info
@@ -1389,6 +1409,32 @@ function getDataForIds(ids) {
13891409
return data;
13901410
}
13911411

1412+
/**
1413+
* Fetch objects from the store, converting pointers to objects where possible
1414+
*/
1415+
function deepFetch(id, seen) {
1416+
if (!store[id]) {
1417+
return null;
1418+
}
1419+
if (typeof seen === 'undefined') {
1420+
seen = [id.toString()];
1421+
}
1422+
var source = store[id].data;
1423+
var obj = {};
1424+
for (var attr in source) {
1425+
var sourceVal = source[attr];
1426+
if (sourceVal.__type === 'Pointer') {
1427+
var childId = new Id(sourceVal.className, sourceVal.objectId);
1428+
if (seen.indexOf(childId.toString()) < 0 && store[childId]) {
1429+
seen = seen.concat([childId.toString()]);
1430+
sourceVal = deepFetch(childId, seen);
1431+
}
1432+
}
1433+
obj[attr] = sourceVal;
1434+
}
1435+
return obj;
1436+
}
1437+
13921438
/**
13931439
* Calculate the result of applying all Mutations to an object.
13941440
*/
@@ -1411,7 +1457,7 @@ function getLatest(id) {
14111457
return base;
14121458
}
14131459
if (store[id]) {
1414-
var source = store[id].data;
1460+
var source = deepFetch(id);
14151461
for (attr in source) {
14161462
base[attr] = source[attr];
14171463
}
@@ -1427,7 +1473,7 @@ function getLatest(id) {
14271473
return base;
14281474
}
14291475
// If there are no mutations, just return the stored object
1430-
return store[id] ? store[id].data : null;
1476+
return store[id] ? deepFetch(id) : null;
14311477
}
14321478

14331479
var ObjectStore = {
@@ -1442,6 +1488,7 @@ var ObjectStore = {
14421488
commitDelta: commitDelta,
14431489
storeQueryResults: storeQueryResults,
14441490
getDataForIds: getDataForIds,
1491+
deepFetch: deepFetch,
14451492
getLatest: getLatest
14461493
};
14471494

@@ -2621,26 +2668,30 @@ var Id = _dereq_('./Id');
26212668
var Parse = _dereq_('./StubParse');
26222669
var warning = _dereq_('./warning');
26232670

2671+
function mappedFlatten(el) {
2672+
if (el instanceof Parse.Object) {
2673+
return {
2674+
__type: 'Pointer',
2675+
className: el.className,
2676+
objectId: el.id
2677+
};
2678+
}
2679+
return flatten(el);
2680+
}
2681+
26242682
/**
26252683
* Convert a Parse Object or array of Parse Objects into a plain JS Object.
26262684
*/
26272685

2628-
function flatten(object, seen) {
2629-
var mappedFlatten = function mappedFlatten(el) {
2630-
return flatten(el, seen);
2631-
};
2686+
function flatten(object) {
26322687
if (Array.isArray(object)) {
26332688
return object.map(mappedFlatten);
26342689
}
26352690
if (!(object instanceof Parse.Object)) {
26362691
warning('Attempted to flatten something that is not a Parse Object');
26372692
return object;
26382693
}
2639-
if (!Array.isArray(seen)) {
2640-
seen = [];
2641-
}
26422694

2643-
seen.push(object);
26442695
var flat = {
26452696
id: new Id(object.className, object.id),
26462697
className: object.className,
@@ -2655,10 +2706,8 @@ function flatten(object, seen) {
26552706
for (var attr in object.attributes) {
26562707
var val = object.attributes[attr];
26572708
if (val instanceof Parse.Object) {
2658-
if (seen.indexOf(val) > -1) {
2659-
throw new Error('Cannot flatten circular reference');
2660-
}
2661-
flat[attr] = flatten(val, seen);
2709+
// We replace it with a pointer
2710+
flat[attr] = mappedFlatten(val);
26622711
} else if (Array.isArray(val)) {
26632712
flat[attr] = val.map(mappedFlatten);
26642713
} else {

dist/parse-react.min.js

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

lib/Mixin.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@ var Mixin = {
5252
componentWillUpdate: function componentWillUpdate(nextProps, nextState) {
5353
// only subscribe if props or state changed
5454
if (nextProps !== this.props || nextState !== this.state) {
55-
this._subscribe();
55+
this._subscribe(nextProps, nextState);
5656
}
5757
},
5858

lib/ObjectStore.js

Lines changed: 50 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,11 @@ function storeObject(data) {
5757
if (!(data.id instanceof Id)) {
5858
throw new Error('Cannot store an object without an Id');
5959
}
60-
store[data.id] = { data: data, queries: {} };
60+
var queries = {};
61+
if (store[data.id]) {
62+
queries = store[data.id].queries;
63+
}
64+
store[data.id] = { data: data, queries: queries };
6165
return data.id;
6266
}
6367
/**
@@ -272,10 +276,26 @@ function storeQueryResults(results, query) {
272276
orderColumns[column] = true;
273277
}
274278
}
279+
var includes = [];
280+
if (query._include.length) {
281+
for (i = 0; i < query._include.length; i++) {
282+
includes.push(query._include[i].split('.'));
283+
}
284+
}
275285
var ids = [];
276286
for (i = 0; i < results.length; i++) {
277287
var flat = flatten(results[i]);
278288
var id = storeObject(flat);
289+
if (includes.length) {
290+
for (var inclusion = 0; inclusion < includes.length; inclusion++) {
291+
var inclusionChain = includes[inclusion];
292+
var cur = results[i];
293+
for (var col = 0; col < inclusionChain.length; col++) {
294+
cur = cur.get(inclusionChain[col]);
295+
storeObject(flatten(cur));
296+
}
297+
}
298+
}
279299
var resultItem = id;
280300
if (orderColumns) {
281301
// Fetch and store ordering info
@@ -315,6 +335,32 @@ function getDataForIds(ids) {
315335
return data;
316336
}
317337

338+
/**
339+
* Fetch objects from the store, converting pointers to objects where possible
340+
*/
341+
function deepFetch(id, seen) {
342+
if (!store[id]) {
343+
return null;
344+
}
345+
if (typeof seen === 'undefined') {
346+
seen = [id.toString()];
347+
}
348+
var source = store[id].data;
349+
var obj = {};
350+
for (var attr in source) {
351+
var sourceVal = source[attr];
352+
if (sourceVal.__type === 'Pointer') {
353+
var childId = new Id(sourceVal.className, sourceVal.objectId);
354+
if (seen.indexOf(childId.toString()) < 0 && store[childId]) {
355+
seen = seen.concat([childId.toString()]);
356+
sourceVal = deepFetch(childId, seen);
357+
}
358+
}
359+
obj[attr] = sourceVal;
360+
}
361+
return obj;
362+
}
363+
318364
/**
319365
* Calculate the result of applying all Mutations to an object.
320366
*/
@@ -337,7 +383,7 @@ function getLatest(id) {
337383
return base;
338384
}
339385
if (store[id]) {
340-
var source = store[id].data;
386+
var source = deepFetch(id);
341387
for (attr in source) {
342388
base[attr] = source[attr];
343389
}
@@ -353,7 +399,7 @@ function getLatest(id) {
353399
return base;
354400
}
355401
// If there are no mutations, just return the stored object
356-
return store[id] ? store[id].data : null;
402+
return store[id] ? deepFetch(id) : null;
357403
}
358404

359405
var ObjectStore = {
@@ -368,6 +414,7 @@ var ObjectStore = {
368414
commitDelta: commitDelta,
369415
storeQueryResults: storeQueryResults,
370416
getDataForIds: getDataForIds,
417+
deepFetch: deepFetch,
371418
getLatest: getLatest
372419
};
373420

lib/flatten.js

Lines changed: 14 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -26,26 +26,30 @@ var Id = require('./Id');
2626
var Parse = require('./StubParse');
2727
var warning = require('./warning');
2828

29+
function mappedFlatten(el) {
30+
if (el instanceof Parse.Object) {
31+
return {
32+
__type: 'Pointer',
33+
className: el.className,
34+
objectId: el.id
35+
};
36+
}
37+
return flatten(el);
38+
}
39+
2940
/**
3041
* Convert a Parse Object or array of Parse Objects into a plain JS Object.
3142
*/
3243

33-
function flatten(object, seen) {
34-
var mappedFlatten = function mappedFlatten(el) {
35-
return flatten(el, seen);
36-
};
44+
function flatten(object) {
3745
if (Array.isArray(object)) {
3846
return object.map(mappedFlatten);
3947
}
4048
if (!(object instanceof Parse.Object)) {
4149
warning('Attempted to flatten something that is not a Parse Object');
4250
return object;
4351
}
44-
if (!Array.isArray(seen)) {
45-
seen = [];
46-
}
4752

48-
seen.push(object);
4953
var flat = {
5054
id: new Id(object.className, object.id),
5155
className: object.className,
@@ -60,10 +64,8 @@ function flatten(object, seen) {
6064
for (var attr in object.attributes) {
6165
var val = object.attributes[attr];
6266
if (val instanceof Parse.Object) {
63-
if (seen.indexOf(val) > -1) {
64-
throw new Error('Cannot flatten circular reference');
65-
}
66-
flat[attr] = flatten(val, seen);
67+
// We replace it with a pointer
68+
flat[attr] = mappedFlatten(val);
6769
} else if (Array.isArray(val)) {
6870
flat[attr] = val.map(mappedFlatten);
6971
} else {

0 commit comments

Comments
 (0)