Skip to content

Commit 6e89fd1

Browse files
committed
feat: parallel include
1 parent 5811465 commit 6e89fd1

File tree

1 file changed

+41
-20
lines changed

1 file changed

+41
-20
lines changed

src/RestQuery.js

Lines changed: 41 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -852,31 +852,54 @@ _UnsafeRestQuery.prototype.handleExcludeKeys = function () {
852852
};
853853

854854
// Augments this.response with data at the paths provided in this.include.
855-
_UnsafeRestQuery.prototype.handleInclude = function () {
855+
_UnsafeRestQuery.prototype.handleInclude = async function () {
856856
if (this.include.length == 0) {
857857
return;
858858
}
859859

860-
var pathResponse = includePath(
861-
this.config,
862-
this.auth,
863-
this.response,
864-
this.include[0],
865-
this.context,
866-
this.restOptions
867-
);
868-
if (pathResponse.then) {
869-
return pathResponse.then(newResponse => {
870-
this.response = newResponse;
871-
this.include = this.include.slice(1);
872-
return this.handleInclude();
860+
const indexedResults = this.response.results.reduce((indexed, result, i) => {
861+
indexed[result.objectId] = i;
862+
return indexed;
863+
}, {});
864+
865+
// Build the execution tree
866+
const executionTree = {}
867+
this.include.forEach(path => {
868+
let current = executionTree;
869+
path.forEach((node) => {
870+
if (!current[node]) {
871+
current[node] = {
872+
path,
873+
children: {}
874+
};
875+
}
876+
current = current[node].children
873877
});
874-
} else if (this.include.length > 0) {
875-
this.include = this.include.slice(1);
876-
return this.handleInclude();
878+
});
879+
880+
const recursiveExecutionTree = async (treeNode) => {
881+
const { path, children } = treeNode;
882+
const pathResponse = includePath(
883+
this.config,
884+
this.auth,
885+
this.response,
886+
path,
887+
this.context,
888+
this.restOptions,
889+
this,
890+
);
891+
if (pathResponse.then) {
892+
const newResponse = await pathResponse
893+
newResponse.results.forEach(newObject => {
894+
// We hydrate the root of each result with sub results
895+
this.response.results[indexedResults[newObject.objectId]][path[0]] = newObject[path[0]];
896+
})
897+
}
898+
return Promise.all(Object.values(children).map(recursiveExecutionTree));
877899
}
878900

879-
return pathResponse;
901+
await Promise.all(Object.values(executionTree).map(recursiveExecutionTree));
902+
this.include = []
880903
};
881904

882905
//Returns a promise of a processed set of results
@@ -1013,7 +1036,6 @@ function includePath(config, auth, response, path, context, restOptions = {}) {
10131036
} else if (restOptions.readPreference) {
10141037
includeRestOptions.readPreference = restOptions.readPreference;
10151038
}
1016-
10171039
const queryPromises = Object.keys(pointersHash).map(async className => {
10181040
const objectIds = Array.from(pointersHash[className]);
10191041
let where;
@@ -1052,7 +1074,6 @@ function includePath(config, auth, response, path, context, restOptions = {}) {
10521074
}
10531075
return replace;
10541076
}, {});
1055-
10561077
var resp = {
10571078
results: replacePointers(response.results, path, replace),
10581079
};

0 commit comments

Comments
 (0)