Skip to content

Instantly share code, notes, and snippets.

@Globegitter
Last active July 28, 2016 09:28
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save Globegitter/553f7dffd1f7ceaead1aba0dd56c5554 to your computer and use it in GitHub Desktop.
Save Globegitter/553f7dffd1f7ceaead1aba0dd56c5554 to your computer and use it in GitHub Desktop.
Hacked defer support
const defaultNetworkLayer = new Relay.DefaultNetworkLayer(endpoint, {
fetchTimeout,
retryDelays,
headers: {...authHeaders, ...customHeaders}
});
defaultNetworkLayer.supports = (...options) => {
return options.every(option => {
if (option === 'defer') {
return true;
}
return false;
});
};
// I am splitting the the requests into ones I found I could execute in parallel and the ones that need to wait on
// results. So that would be the ref-queries I suppose. Not sure if checking for it being deferred and it having'request._query.getBatchCall()'
// is the best way of doing it, but that seemed to be consistent a consistent way for me.
// This code is merely a proof of concept and also wouldn't work for nested ref-queries
// Also I noticed that I still got the 'Deferred queries are not supported' invariant, but everything in my test-case got loaded nevertheless.
defaultNetworkLayer.sendQueries = (requests) => {
var deferredFragmentRequests = [];
var nonDeferredRequests = [];
requests.forEach(function (request) {
if (request._query.isDeferred() && request._query.getBatchCall()) {
deferredFragmentRequests.push(request);
} else {
nonDeferredRequests.push(request)
}
});
return Promise.all(nonDeferredRequests.map(request => (
defaultNetworkLayer._sendQuery(request).then(
result => result.json()
).then(payload => {
if (payload.hasOwnProperty('errors')) {
var error = new Error('Server request for query `' + request.getDebugName() + '` ' + 'failed for the following reasons:\n\n' + formatRequestErrors(request, payload.errors));
error.source = payload;
request.reject(error);
} else if (!payload.hasOwnProperty('data')) {
request.reject(new Error(
'Server response was missing for query ' +
`\`${request.getDebugName()}\`.`
));
} else {
deferredFragmentRequests.forEach((deferredFragmentRequest) => {
// Match the expected id from the ref query agains the returned request id
if (deferredFragmentRequest._query.getBatchCall() && deferredFragmentRequest._query.getBatchCall().sourceQueryID == request.getID()) {
const fullPath = deferredFragmentRequest._query.getBatchCall().sourceQueryPath.slice(4).split('.');
let deferredFragmentVariable = payload.data[request._query.getFieldName()];
fullPath.forEach((pathPart) => {
deferredFragmentVariable = deferredFragmentVariable[pathPart];
});
// override things in such a way that it this request can be succesfull
deferredFragmentRequest._query.__batchCall__ = null;
deferredFragmentRequest._query.__identifyingArg__ = {
name: "id",
value: deferredFragmentVariable,
type: "ID!"
};
deferredFragmentRequest._query.__calls__ = [{
"name": "id",
"value": deferredFragmentVariable,
"type": "ID!"
}];
deferredFragmentRequest._query.__concreteNode__.fieldName = 'node';
defaultNetworkLayer._sendQuery(deferredFragmentRequest).then(function (result) {
return result.json();
}).then(function (payload) {
if (payload.hasOwnProperty('errors')) {
var error = new Error('Server request for query `' + request.getDebugName() + '` ' + 'failed for the following reasons:\n\n' + formatRequestErrors(request, payload.errors));
error.source = payload;
request.reject(error);
} else if (!payload.hasOwnProperty('data')) {
request.reject(new Error('Server response was missing for query `' + request.getDebugName() + '`.'));
} else {
request.resolve({response: payload.data});
}
})['catch'](function (error) {
return request.reject(error);
});
}
});
request.resolve({response: payload.data});
}
}).catch(
error => request.reject(error)
)
)));
};
Relay.injectNetworkLayer(defaultNetworkLayer);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment